From 371acab83d5a53c352018350904a127e9d44a363 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Fri, 20 Jul 2012 16:13:59 +0300 Subject: [PATCH 01/75] Fixed issue : Clean up remotecontrol of dublicate functions Dev : Deleted functions will be reinserted after merged with NOCs functions --- .../controllers/admin/remotecontrol.php | 176 +----------------- 1 file changed, 8 insertions(+), 168 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 6b60217c67b..6e4ccba15e1 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -192,69 +192,23 @@ public function release_session_key($sSessionKey) } - /** - * RPC routine to import a survey - imports lss,csv,xls or survey zip archive - * - * @access public - * @param string $sSessionKey - * @param string $sImportData String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive - * @param string $sImportDataType lss,csv,xls or zip - * @param integer $DestSurveyID This is the new ID of the survey - if already used a random one will be taken instead - * @return integer iSurveyID - ID of the new survey - */ - public function import_survey($sSessionKey, $sImportData, $sImportDataType, $sNewSurveyName=NULL, $DestSurveyID=NULL) - { - if ($this->_checkSessionKey($sSessionKey)) - { - if (hasGlobalPermission('USER_RIGHT_CREATE_SURVEY')) - { - if (!in_array($sImportDataType,array('zip','csv','xls','lss'))) return array('status' => 'Invalid extension'); - Yii::app()->loadHelper('admin/import'); - // First save the data to a temporary file - $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; - file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); - $aImportResults = importSurveyFile($sFullFilePath, true, $sNewSurveyName, $DestSurveyID); - unlink($sFullFilePath); - if (isset($aImportResults['error'])) return array('status' => 'Error: '.$aImportResults['error']); - else - { - return $aImportResults['newsid']; - } - } - else - return array('status' => 'No permission'); - } - } /** - * RPC routine to activate a survey + * RPC routine to delete a survey * * @access public * @param string $sSessionKey - * @param string $sLSSData String containing the data of an LSS file - * @param integer $DestSurveyID This is the new ID of the survey - if already used a random one will be taken instead - * @return integer iSurveyID - ID of the new survey + * @param int $iSurveyID + * @return array */ - public function activate_survey($sSessionKey, $iSurveyID) + public function delete_survey($sSessionKey, $iSurveyID) { if ($this->_checkSessionKey($sSessionKey)) { - $oSurvey=Survey::model()->findByPk($iSurveyID); - if (is_null($oSurvey)) - { - return array('status' => 'Error: Invalid survey ID'); - } - - if (hasSurveyPermission($iSurveyID, 'surveyactivation', 'update')) + if (hasSurveyPermission($iSurveyID, 'survey', 'delete')) { - Yii::app()->loadHelper('admin/activate'); - $aImportResults = activateSurvey($iSurveyID); - - if (isset($aImportResults['error'])) return array('status' => 'Error: '.$aImportResults['error']); - else - { - return $aImportResults; - } + Survey::model()->deleteSurvey($iSurveyID,true); + return array('status' => 'OK'); } else return array('status' => 'No permission'); @@ -315,62 +269,6 @@ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurvey } } - /** - * RPC routine to modify survey settings - * - * @access public - * @param string $sSessionKey - * @param integer $iSurveyID - ID of the survey - * @param array $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey - * @return array OK, when save successful otherwise error text. - */ - public function modify_survey_settings($sSessionKey, $iSurveyID, $aSurveyData) - { - if ($this->_checkSessionKey($sSessionKey)) - { - $oSurvey=Survey::model()->findByPk($iSurveyID); - if (is_null($oSurvey)) - { - return array('status' => 'Error: Invalid survey ID'); - } - if (hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) - { - // Remove fields that may not be modified - unset($aSurveyData['active']); - unset($aSurveyData['language']); - unset($aSurveyData['additional_languages']); - // Remove invalid fields - $aDestinationFields=array_flip(Survey::model()->tableSchema->columnNames); - $aSurveyData=array_intersect_key($aSurveyData,$aDestinationFields); - $oSurvey=Survey::model()->findByPk($iSurveyID); - if ($oSurvey->active=='Y') - { - // remove all fields that may not be changed when a survey is active - unset($aSurveyData['anonymized']); - unset($aSurveyData['datestamp']); - unset($aSurveyData['savetimings']); - unset($aSurveyData['ipaddr']); - unset($aSurveyData['refurl']); - } - foreach($aSurveyData as $sFieldName=>$sValue) - { - $oSurvey->$sFieldName=$sValue; - } - try - { - $oSurvey->save(); // save the change to database - return array('status' => 'OK'); - } - catch(Exception $e) - { - return array('status' => 'Error'); - } - } - else - return array('status' => 'No permission'); - } - } - /** @@ -535,27 +433,7 @@ public function activate_tokens($sSessionKey, $iSurveyID, $aAttributeFields=arra return array('status' => 'No permission'); } - /** - * RPC routine to delete a survey - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @return array - */ - public function delete_survey($sSessionKey, $iSurveyID) - { - if ($this->_checkSessionKey($sSessionKey)) - { - if (hasSurveyPermission($iSurveyID, 'survey', 'delete')) - { - Survey::model()->deleteSurvey($iSurveyID,true); - return array('status' => 'OK'); - } - else - return array('status' => 'No permission'); - } - } + /** * RPC routine to add a response to the survey response table @@ -670,44 +548,6 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b return array('status' => 'No permission'); } - /** - * RPC routine to export responses - * Returns the requested file as base64 encoded string - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param string $sDocumentType pdf,csv,xls,doc - * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to complete - * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' - * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' - * @param integer $iFromResponseID Optional - * @param integer $iToResponseID Optional - * @return On success: Requested file as base 64-encoded string. On failure array with error information - **/ - function export_reponses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode=null, $sCompletionStatus='all', $sHeadingType='code', $sResponseType='short', $iFromResponseID=null, $iToResponseID=null, $aFields=null) - { - if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); - Yii::app()->loadHelper('admin/exportresults'); - if (!hasSurveyPermission($iSurveyID, 'responses', 'export')) return array('status' => 'No permission'); - if (is_null($sLanguageCode)) $sLanguageCode=getBaseLanguageFromSurveyID($iSurveyID); - if (is_null($aFields)) $aFields=array_keys(createFieldMap($iSurveyID,'full',true,false,$sLanguageCode)); - if($sDocumentType=='xls'){ - // Cut down to the first 255 fields - $aFields=array_slice($aFields,0,255); - } - $oFomattingOptions=new FormattingOptions(); - $oFomattingOptions->format=$sDocumentType; - $oFomattingOptions->responseMinRecord=$iFromResponseID; - $oFomattingOptions->responseMaxRecord=$iToResponseID; - $oFomattingOptions->selectedColumns=$aFields; - $oFomattingOptions->responseCompletionState=$sCompletionStatus; - $oFomattingOptions->headingFormat=$sHeadingType; - $oFomattingOptions->answerFormat=$sResponseType; - $oExport=new ExportSurveyResultsService(); - $sFileData=$oExport->exportSurvey($iSurveyID,$sLanguageCode,$oFomattingOptions,'return'); - return base64_encode($sFileData); - } /** From fd94fef1c3d1df9e528824c11fa918095ff2b53f Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Fri, 20 Jul 2012 16:20:20 +0300 Subject: [PATCH 02/75] New Feature : Added remotecontrol function get_site_settings --- .../controllers/admin/remotecontrol.php | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 6e4ccba15e1..3c39102b38e 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -191,7 +191,33 @@ public function release_session_key($sSessionKey) return 'OK'; } - + /** + * RPC routine to get settings + * + * @access public + * @param string $sSessionKey + * @param string $sSetttingName + * @return string + */ + public function get_site_settings($sSessionKey,$sSetttingName) + { + if ($this->_checkSessionKey($sSessionKey)) + { + if( Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1) + { + if (Yii::app()->getRegistry($sSetttingName) !== false) + return Yii::app()->getRegistry($sSetttingName); + elseif (Yii::app()->getConfig($sSetttingName) !== false) + return Yii::app()->getConfig($sSetttingName); + else + return array('status' => 'Invalid setting'); + } + else + return array('status' => 'Invalid setting'); + } + else + return array('status' => 'Invalid session key'); + } /** * RPC routine to delete a survey From 248ac9f080df2bc6fb0a276c95fc2f3402d56655 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Mon, 23 Jul 2012 16:14:20 +0300 Subject: [PATCH 03/75] New feature : Remotecontrol functions for manipulation of surveys Dev: merged functions : export responses, import_survey, activate_survey,modify_survey_properties, modify_survey_locale_properties Dev: Added functions : create_survey, get_survey_list, get_survey_summary, get_survey_settings, send_statistics Dev: Send statistics requires generate statistic to produce proper result (pending) --- .../controllers/admin/remotecontrol.php | 714 +++++++++++++++++- 1 file changed, 711 insertions(+), 3 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 3c39102b38e..08b41626266 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -219,6 +219,95 @@ public function get_site_settings($sSessionKey,$sSetttingName) return array('status' => 'Invalid session key'); } + /** + * RPC routine to create an empty survey with minimum details + * Used as a placeholder for importing groups and/or questions + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param string $sSurveyTitle + * @param string $sSurveyLanguage + * @param string $sformat + * @return string + * @throws Zend_XmlRpc_Server_Exception + */ + public function create_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLanguage, $sformat = 'G') + { + Yii::app()->loadHelper("surveytranslator"); + if ($this->_checkSessionKey($sSessionKey)) + { + if (Yii::app()->session['USER_RIGHT_CREATE_SURVEY']) + { + if( $sSurveyTitle=='' || $sSurveyLanguage=='' || !array_key_exists($sSurveyLanguage,getLanguageDataRestricted()) || !in_array($sformat, array('A','G','S'))) + return array('status' => 'Faulty parameters'); + + $aInsertData = array('template' => 'default', + 'owner_id' => Yii::app()->session['loginID'], + 'active' => 'N', + 'language'=>$sSurveyLanguage, + 'format' => $sformat + ); + + if(Yii::app()->getConfig('filterxsshtml') && Yii::app()->session['USER_RIGHT_SUPERADMIN'] != 1) + $xssfilter = true; + else + $xssfilter = false; + + if (!is_null($iSurveyID)) + $aInsertData['wishSID'] = $iSurveyID; + + try + { + $iNewSurveyid = Survey::model()->insertNewSurvey($aInsertData, $xssfilter); + if (!$iNewSurveyid) + return array('status' => 'Creation Failed'); + + $sTitle = html_entity_decode($sSurveyTitle, ENT_QUOTES, "UTF-8"); + + // Load default email templates for the chosen language + $oLanguage = new Limesurvey_lang($sSurveyLanguage); + $aDefaultTexts = templateDefaultTexts($oLanguage, 'unescaped'); + unset($oLanguage); + + $bIsHTMLEmail = false; + + $aInsertData = array( + 'surveyls_survey_id' => $iNewSurveyid, + 'surveyls_title' => $sTitle, + 'surveyls_language' => $sSurveyLanguage, + 'surveyls_email_invite_subj' => $aDefaultTexts['invitation_subject'], + 'surveyls_email_invite' => conditionalNewlineToBreak($aDefaultTexts['invitation'], $bIsHTMLEmail, 'unescaped'), + 'surveyls_email_remind_subj' => $aDefaultTexts['reminder_subject'], + 'surveyls_email_remind' => conditionalNewlineToBreak($aDefaultTexts['reminder'], $bIsHTMLEmail, 'unescaped'), + 'surveyls_email_confirm_subj' => $aDefaultTexts['confirmation_subject'], + 'surveyls_email_confirm' => conditionalNewlineToBreak($aDefaultTexts['confirmation'], $bIsHTMLEmail, 'unescaped'), + 'surveyls_email_register_subj' => $aDefaultTexts['registration_subject'], + 'surveyls_email_register' => conditionalNewlineToBreak($aDefaultTexts['registration'], $bIsHTMLEmail, 'unescaped'), + 'email_admin_notification_subj' => $aDefaultTexts['admin_notification_subject'], + 'email_admin_notification' => conditionalNewlineToBreak($aDefaultTexts['admin_notification'], $bIsHTMLEmail, 'unescaped'), + 'email_admin_responses_subj' => $aDefaultTexts['admin_detailed_notification_subject'], + 'email_admin_responses' => $aDefaultTexts['admin_detailed_notification'] + ); + + $langsettings = new Surveys_languagesettings; + $langsettings->insertNewSurvey($aInsertData, $xssfilter); + Survey_permissions::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'], $iNewSurveyid); + + return $iNewSurveyid; + } + catch(Exception $e) + { + return array('status' => $e->getmessage()); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + /** * RPC routine to delete a survey * @@ -239,20 +328,308 @@ public function delete_survey($sSessionKey, $iSurveyID) else return array('status' => 'No permission'); } + else + return array('status' => 'Invalid session key'); } + /** + * RPC routine to activate a survey + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID The id of the survey to be activated + * @param string dStart - Optional parameter Startdate + * @param string dEnd - Optional parameter Expires + * @return array the result of the activation + */ + public function activate_survey($sSessionKey, $iSurveyID, $dStart='', $dEnd='') + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oSurvey=Survey::model()->findByPk($iSurveyID); + if (is_null($oSurvey)) + return array('status' => 'Error: Invalid survey ID'); + + $date_pattern = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/'; + try + { + if($dStart!='' && filter_var($dStart, FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>$date_pattern)))) + Survey::model()->updateByPk($iSurveyID, array('startdate'=> $dStart)); + + if($dEnd!='' && filter_var($dEnd, FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>$date_pattern)))) + Survey::model()->updateByPk($iSurveyID, array('expires'=> $dEnd)); + } + catch(Exception $e) + { + //return array('status' => $e->getmessage()); + } + + if (hasSurveyPermission($iSurveyID, 'surveyactivation', 'update')) + { + Yii::app()->loadHelper('admin/activate'); + $aActivateResults = activateSurvey($iSurveyID); + + if (isset($aActivateResults['error'])) return array('status' => 'Error: '.$aActivateResults['error']); + else + { + return $aActivateResults; + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + /** + * RPC routine to import a survey - imports lss,csv,xls or survey zip archive + * + * @access public + * @param string $sSessionKey + * @param string $sImportData String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive + * @param string $sImportDataType lss,csv,xls or zip + * @param integer $DestSurveyID This is the new ID of the survey - if already used a random one will be taken instead + * @return integer iSurveyID - ID of the new survey + */ + public function import_survey($sSessionKey, $sImportData, $sImportDataType, $sNewSurveyName=NULL, $DestSurveyID=NULL) + { + if ($this->_checkSessionKey($sSessionKey)) + { + if (hasGlobalPermission('USER_RIGHT_CREATE_SURVEY')) + { + if (!in_array($sImportDataType,array('zip','csv','xls','lss'))) return array('status' => 'Invalid extension'); + Yii::app()->loadHelper('admin/import'); + // First save the data to a temporary file + $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; + file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); + $aImportResults = importSurveyFile($sFullFilePath, true, $sNewSurveyName, $DestSurveyID); + unlink($sFullFilePath); + if (isset($aImportResults['error'])) return array('status' => 'Error: '.$aImportResults['error']); + else + { + return $aImportResults['newsid']; + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + /** + * RPC routine to return the ids and info of surveys belonging to a user + * Returns array of ids and info + * If user is admin he can get surveys of every user + * else only the syrveys belonging to the user requesting will be shown + * + * @access public + * @param string $sSessionKey + * @param string $suser + * @return array + * @throws Zend_XmlRpc_Server_Exception + */ + public function get_survey_list($sSessionKey, $suser='') + { + if ($this->_checkSessionKey($sSessionKey)) + { + $current_user = Yii::app()->session['user']; + if( Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1 and $suser !='') + $current_user = $suser; + + $aUserData = User::model()->findByAttributes(array('users_name' => $current_user)); + if (!isset($aUserData)) + return array('status' => 'Invalid user'); + + $user_surveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); + if(count($user_surveys)==0) + return array('status' => 'No surveys found'); + + foreach ($user_surveys as $asurvey) + { + $asurvey_ls = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $asurvey->primaryKey, 'surveyls_language' => $asurvey->language)); + if (!isset($asurvey_ls)) + $asurvey_title = ''; + else + $asurvey_title = $asurvey_ls->attributes['surveyls_title']; + $aData[]= array('sid'=>$asurvey->primaryKey,'surveyls_title'=>$asurvey_title,'startdate'=>$asurvey->attributes['startdate'],'expires'=>$asurvey->attributes['expires'],'active'=>$asurvey->attributes['active']); + } + return $aData; + } + else + return array('status' => 'Invalid session key'); + } + + /** + * RPC routine to get survey summary, regarding token usage and survey participation + * Return integer with the requested value + * @access public + * @param string $sSessionKey + * @param int $sid + * @param string $stats_name + * @return string + */ + public function get_survey_summary($sSessionKey,$iSurveyID, $stat_name) + { + $permitted_stats = array(); + if ($this->_checkSessionKey($sSessionKey)) + { + $permitted_token_stats = array('token_count', + 'token_invalid', + 'token_sent', + 'token_opted_out', + 'token_completed' + ); + $permitted_survey_stats = array('completed_responses', + 'incomplete_responses', + 'full_responses' + ); + $permitted_stats = array_merge($permitted_survey_stats, $permitted_token_stats); + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Invalid surveyid'); + + if(in_array($stat_name, $permitted_token_stats)) + { + if (tableExists('{{tokens_' . $iSurveyID . '}}')) + $summary = Tokens_dynamic::model($iSurveyID)->summary(); + else + return array('status' => 'No available data'); + } + + if(in_array($stat_name, $permitted_survey_stats) && !tableExists('{{survey_' . $iSurveyID . '}}')) + return array('status' => 'No available data'); + + if (!in_array($stat_name, $permitted_stats)) + return array('status' => 'No such property'); + + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) + { + switch($stat_name) + { + case 'token_count': + if (isset($summary)) + return $summary['tkcount']; + break; + case 'token_invalid': + if (isset($summary)) + return $summary['tkinvalid']; + break; + case 'token_sent': + if (isset($summary)) + return $summary['tksent']; + break; + case 'token_opted_out': + if (isset($summary)) + return $summary['tkoptout']; + break; + case 'token_completed'; + if (isset($summary)) + return $summary['tkcompleted']; + break; + case 'completed_responses': + return Survey_dynamic::model($iSurveyID)->count('submitdate IS NOT NULL'); + break; + case 'incomplete_responses': + return Survey_dynamic::model($iSurveyID)->countByAttributes(array('submitdate' => null)); + break; + case 'full_responses'; + return Survey_dynamic::model($iSurveyID)->count(); + break; + default: + return array('status' => 'Data is not available'); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + /** + * RPC routine to modify survey settings + * + * @access public + * @param string $sSessionKey + * @param integer $iSurveyID - ID of the survey + * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey + * @return array of succeeded and failed nodifications according to internal validation. + */ + public function modify_survey_settings($sSessionKey, $iSurveyID, $aSurveyData) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oSurvey=Survey::model()->findByPk($iSurveyID); + if (is_null($oSurvey)) + { + return array('status' => 'Error: Invalid survey ID'); + } + if (hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) + { + // Remove fields that may not be modified + unset($aSurveyData['active']); + unset($aSurveyData['language']); + unset($aSurveyData['additional_languages']); + // Remove invalid fields + $aDestinationFields=array_flip(Survey::model()->tableSchema->columnNames); + $aSurveyData=array_intersect_key($aSurveyData,$aDestinationFields); + $oSurvey=Survey::model()->findByPk($iSurveyID); + $succeded = array(); + $failed = array(); + if ($oSurvey->active=='Y') + { + // remove all fields that may not be changed when a survey is active + unset($aSurveyData['anonymized']); + unset($aSurveyData['datestamp']); + unset($aSurveyData['savetimings']); + unset($aSurveyData['ipaddr']); + unset($aSurveyData['refurl']); + + } + foreach($aSurveyData as $sFieldName=>$sValue) + { + if($this->_internal_validate($sFieldName,$sValue)) + { + $oSurvey->$sFieldName=$sValue; + $succeded[$sFieldName]=$sValue; + } + else + $failed[$sFieldName]=$sValue; + } + try + { + $oSurvey->save(); // save the change to database + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session key'); + } + + /** * RPC routine to modify survey locale settings * * @access public * @param string $sSessionKey * @param integer $iSurveyID - ID of the survey - * @param array $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey + * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey * @param string $aLanguage - Optional - Language to update - if not give the base language of the particular survey is used * @return array status=>OK, when save successful otherwise error text. */ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurveyLocaleData, $sLanguage=NULL) { + Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) { $oSurvey=Survey::model()->findByPk($iSurveyID); @@ -260,11 +637,15 @@ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurvey { return array('status' => 'Error: Invalid survey ID'); } + if (is_null($sLanguage)) { $sLanguage=$oSurvey->language; } + if (!array_key_exists($sLanguage,getLanguageDataRestricted())) + return array('status' => 'Error: Invalid language'); + if (hasSurveyPermission($iSurveyID, 'surveylocale', 'update')) { // Remove fields that may not be modified @@ -276,14 +657,23 @@ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurvey $aSurveyLocaleData=array_intersect_key($aSurveyLocaleData,$aDestinationFields); $oSurveyLocale = Surveys_languagesettings::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLanguage)); + $succeded = array(); + $failed = array(); foreach($aSurveyLocaleData as $sFieldName=>$sValue) { - $oSurveyLocale->$sFieldName=$sValue; + if($this->_internal_validate($sFieldName,$sValue)) + { + $oSurveyLocale->$sFieldName=$sValue; + $succeded[$sFieldName]=$sValue; + } + else + $failed[$sFieldName]=$sValue; } try { $oSurveyLocale->save(); // save the change to database - return array('status' => 'OK'); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; } catch(Exception $e) { @@ -293,9 +683,175 @@ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurvey else return array('status' => 'No permission'); } + else + return array('status' => 'Invalid Session key'); } + /** + * RPC routine to get survey settings + * Properties are those defined in tables surveys and surveys_language_settings + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param array $aSurveySettings + * @param string $slang + * @return array + */ + public function get_survey_settings($sSessionKey,$iSurveyID, $aSurveySettings, $slang=NULL) + { + Yii::app()->loadHelper("surveytranslator"); + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + { + return array('status' => 'Error: Invalid survey ID'); + } + if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) + { + $aBasicDestinationFields=Surveys_languagesettings::model()->tableSchema->columnNames; + $aLanguageDestinationFields=Survey::model()->tableSchema->columnNames; + $aSurveyFields = array_merge($aBasicDestinationFields,$aLanguageDestinationFields); + + $aSurveySettings=array_intersect($aSurveySettings,$aSurveyFields); + + $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); + + if ($slang == NULL || !array_key_exists($slang,getLanguageDataRestricted())) + $slang = $abasic_attrs['language']; + + $alang_attrs = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $slang))->getAttributes(); + + $result = array(); + foreach($aSurveySettings as $sproperty_name) + { + if (isset($abasic_attrs[$sproperty_name])) + $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + elseif (isset($alang_attrs[$sproperty_name])) + $result[$sproperty_name]=$alang_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Not available'; + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session key'); + } + + /** + * RPC routine to export responses + * Returns the requested file as base64 encoded string + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param string $sDocumentType pdf,csv,xls,doc + * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to complete + * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' + * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' + * @param integer $iFromResponseID Optional + * @param integer $iToResponseID Optional + * @return On success: Requested file as base 64-encoded string. On failure array with error information + **/ + function export_reponses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode=null, $sCompletionStatus='all', $sHeadingType='code', $sResponseType='short', $iFromResponseID=null, $iToResponseID=null, $aFields=null) + { + if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); + Yii::app()->loadHelper('admin/exportresults'); + if (!hasSurveyPermission($iSurveyID, 'responses', 'export')) return array('status' => 'No permission'); + if (is_null($sLanguageCode)) $sLanguageCode=getBaseLanguageFromSurveyID($iSurveyID); + if (is_null($aFields)) $aFields=array_keys(createFieldMap($iSurveyID,'full',true,false,$sLanguageCode)); + if($sDocumentType=='xls'){ + // Cut down to the first 255 fields + $aFields=array_slice($aFields,0,255); + } + $oFomattingOptions=new FormattingOptions(); + $oFomattingOptions->format=$sDocumentType; + $oFomattingOptions->responseMinRecord=$iFromResponseID; + $oFomattingOptions->responseMaxRecord=$iToResponseID; + $oFomattingOptions->selectedColumns=$aFields; + $oFomattingOptions->responseCompletionState=$sCompletionStatus; + $oFomattingOptions->headingFormat=$sHeadingType; + $oFomattingOptions->answerFormat=$sResponseType; + $oExport=new ExportSurveyResultsService(); + $sFileData=$oExport->exportSurvey($iSurveyID,$sLanguageCode,$oFomattingOptions,'return'); + return base64_encode($sFileData); + } + /** + * RPC routine to export statistics of a survey to a user + * Returns string - base64 encoding of the statistics + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param string $docType + * @param string $graph + * @return string + * @throws Zend_XmlRpc_Server_Exception + */ + public function send_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') + { + Yii::app()->loadHelper('admin/statistics'); + + if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); + + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID');; + + if(Survey::model()->findByPk($iSurveyID)->owner_id != $_SESSION['loginID']) + return array('status' => 'Error: No Permission'); + + $allqs = Questions::model()->findAll("sid = '".$iSurveyID."'"); + foreach($allqs as $field) + { + $myField = $iSurveyID."X".$field['gid']."X".$field['qid']; + // Multiple choice get special treatment + if ($field['type'] == "M" || $field['type'] == "P") {$myField = "M$myField";} + //numerical input will get special treatment (arihtmetic mean, standard derivation, ...) + if ($field['type'] == "N") {$myField = "N$myField";} + if ($field['type'] == "Q") {$myField = "Q$myField";} + // textfields get special treatment + if ($field['type'] == "S" || $field['type'] == "T" || $field['type'] == "U"){$myField = "T$myField";} + //statistics for Date questions are not implemented yet. + if ($field['type'] == "D") {$myField = "D$myField";} + if ($field['type'] == "F" || $field['type'] == "H") + { + $result3 = Answers::model()->findAllByAttributes(array('qid' => $field['qid'],'language' => getBaseLanguageFromSurveyID($sid)), array('order' => 'sortorder, answer')); + foreach ($result3 as $row) + { + $myField = "$myField{$row['code']}"; + } + } + $summary[]=$myField; + } + + switch ($docType) + { + case 'pdf': + $tempFile = generate_statistics($iSurveyID,$summary,'all',$graph,$docType,'F'); + break; + case 'xls': + $tempFile = generate_statistics($iSurveyID,$summary,'all',0,$docType, 'F'); + break; + case 'html': + $html = generate_statistics($iSurveyID,$summary,'all',0,$docType, 'F'); + break; + } + + if(isset($html)) + return base64_encode($html); + else + { + $result = file_get_contents($tempfile); + unlink($tempfile); + return base64_encode($result); + } + } /** * RPC routine to add a survey language @@ -652,4 +1208,156 @@ protected function _checkSessionKey($sSessionKey) return true; } } + + /** + * This function validates parameters to be inserted in survey model + * + * @access protected + * @param string $sparam_name + * @param string $sparam_value + * @return bool|string + * @throws Zend_XmlRpc_Server_Exception + */ + protected function _internal_validate($sparam_name, $sparam_value) + { + $date_pattern = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/'; + $validation_categories = array( + 'active'=>'char', + 'anonymized'=>'char', + 'savetimings'=>'char', + 'datestamp'=>'char', + 'ipaddr'=>'char', + 'refurl'=>'char', + 'usecookie'=>'char', + 'allowregister'=>'char', + 'allowsave'=>'char', + 'autoredirect'=>'char', + 'allowprev'=>'char', + 'printanswers'=>'char', + 'publicstatistics'=>'char', + 'publicgraphs'=>'char', + 'listpublic'=>'char', + 'htmlemail'=>'char', + 'sendconfirmation'=>'char', + 'tokenanswerspersistence'=>'char', + 'assessments'=>'char', + 'usecaptcha'=>'captcha_format', + 'usetokens'=>'char', + 'showxquestions'=>'char', + 'showgroupinfo'=>'group_format', + 'shownoanswer'=>'char', + 'showqnumcode'=>'gnum_format', + 'showwelcome'=>'char', + 'showprogress'=>'char', + 'allowjumps'=>'char', + 'nokeyboard'=>'char', + 'alloweditaftercompletion'=>'char', + 'googleanalyticsstyle'=>'ga_format', + 'bounceprocessing'=>'char', + 'autonumber_start'=>'int', + 'tokenlength'=>'int', + 'bouncetime'=>'int', + 'navigationdelay'=>'int', + 'expires'=>'date', + 'startdate'=>'date', + 'datecreated'=>'date', + 'adminemail'=>'email', + 'bounce_email'=>'email', + 'surveyls_dateformat'=>'dateformat', + 'surveyls_numberformat'=>'numberformat', + 'template'=>'tmpl', + 'format'=>'gsa_format', + //group parameters + 'group_order'=>'int', + //question_parameters + 'other'=>'char', + 'mandatory'=>'char', + 'question_order'=>'int', + 'scale_id'=>'int', + 'same_default'=>'int', + //token parameters + 'email'=>'email', + 'remindercount'=>'int', + 'remindersent'=>'int', + 'usesleft'=>'int', + 'validfrom'=>'date', + 'validuntil'=>'date', + 'mpid'=>'int', + 'blacklisted'=>'char', + 'sent'=>'char', + 'completed'=>'char' + ); + + if (array_key_exists($sparam_name, $validation_categories)) + { + switch($validation_categories[$sparam_name]) + { + case 'char': + if(in_array($sparam_value, array('Y','N'))) + return $sparam_value; + else + return false; + break; + + case 'int': + return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>999999999))); + break; + + case 'date': + return filter_var($sparam_value, FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>$date_pattern))); + break; + + case 'email': + return filter_var($sparam_value, FILTER_VALIDATE_EMAIL); + break; + + case 'dateformat': + return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>12))); + break; + + case 'numberformat': + return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>0, "max_range"=>1))); + break; + case 'tmpl': + if(array_key_exists($sparam_value,getTemplateList())) + return $sparam_value; + else + return false; + break; + case 'gsa_format': + if(in_array($sparam_value, array('G','S','A'))) + return $sparam_value; + else + return false; + break; + case 'captcha_format': + if(in_array($sparam_value, array('A','B','C','D','X','R','S','N'))) + return $sparam_value; + else + return false; + break; + case 'group_format': + if(in_array($sparam_value, array('B','N','D','X'))) + return $sparam_value; + else + return false; + break; + case 'gnum_format': + if(in_array($sparam_value, array('B','N','C','X'))) + return $sparam_value; + else + return false; + break; + case 'ga_format': + return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>0, "max_range"=>2))); + break; + default: + return $sparam_value; + + } + } + else + return $sparam_value; + } + } From 43780b0d5373db18781f833bfc4bc20d3c68e408 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 24 Jul 2012 13:28:03 +0300 Subject: [PATCH 04/75] New feature : Remotecontrol functions for manipulation of groups Dev: Created new functions: Create group, import_group, delete_group, modify_group_settings, get_group_settings, get_group_list Dev: Import_group is done only through stream of data, according to import_survey logic --- .../controllers/admin/remotecontrol.php | 329 ++++++++++++++++++ application/models/Groups.php | 2 +- 2 files changed, 330 insertions(+), 1 deletion(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 08b41626266..bb6e6347630 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1130,6 +1130,335 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b return array('status' => 'No permission'); } + /** + * RPC routine to create an empty group with minimum details + * Used as a placeholder for importing questions + * Returns the groupid of the created group + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param string $sGroupTitle + * @param string $sGroupDescription + * @return string + * @throws Zend_XmlRpc_Server_Exception + */ + public function create_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescription='') + { + if ($this->_checkSessionKey($sSessionKey)) + { + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if($surveyidExists['active']=='Y') + return array('status' => 'Error:Survey is active and not editable'); + + $group = new Groups; + $group->sid = $iSurveyID; + $group->group_name = $sGroupTitle; + $group->description = $sGroupDescription; + $group->group_order = getMaxGroupOrder($iSurveyID); + $group->language = Survey::model()->findByPk($iSurveyID)->language; + if($group->save()) + return $group->gid; + else + return array('status' => 'Creation Failed'); + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + + /** + * RPC routine to import a group - imports lsg,csv + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID the id of the survey that the group will belong + * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv + * @param string $sImportDataType lsg,csv + * @param string $sNewGroupName Optional new name for the group + * @param string $sNewGroupDescription Optional new description for the group + * @return integer iGroupID - ID of the new group + */ + public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDataType, $sNewGroupName=NULL, $sNewGroupDescription=NULL) + { + + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if($surveyidExists->getAttribute('active') =='Y') + return array('status' => 'Error:Survey is aCctive and not editable'); + + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + { + if (!in_array($sImportDataType,array('csv','lsg'))) return array('status' => 'Invalid extension'); + libxml_use_internal_errors(true); + Yii::app()->loadHelper('admin/import'); + // First save the data to a temporary file + $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; + file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); + + if (strtolower($sImportDataType)=='csv') + { + $aImportResults = CSVImportGroup($sFullFilePath, $iSurveyID); + } + elseif ( strtolower($sImportDataType)=='lsg') + { + + $xml = simplexml_load_file($sFullFilePath); + if(!$xml) + { + unlink($sFullFilePath); + return array('status' => 'Error: Invalid LimeSurvey group structure XML '); + } + $aImportResults = XMLImportGroup($sFullFilePath, $iSurveyID); + } + else + return array('status' => 'Invalid extension'); //just for symmetry! + + unlink($sFullFilePath); + + if (isset($aImportResults['fatalerror'])) return array('status' => 'Error: '.$aImportResults['fatalerror']); + else + { + $iNewgid = $aImportResults['newgid']; + + $group = Groups::model()->findByAttributes(array('gid' => $iNewgid)); + $slang=$group['language']; + if($sNewGroupName!='') + $group->setAttribute('group_name',$sNewGroupName); + if($sNewGroupDescription!='') + $group->setAttribute('description',$sNewGroupDescription); + try + { + $group->save(); + } + catch(Exception $e) + { + // no need to throw exception + } + return $aImportResults['newgid']; + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + + /** + * RPC routine to delete a group of a survey + * Returns the id of the deleted group + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param int $iGroupID + * @return int + * @throws Zend_XmlRpc_Server_Exception + */ + public function delete_group($sSessionKey, $iSurveyID, $iGroupID) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $iSurveyID = sanitize_int($iSurveyID); + $iGroupID = sanitize_int($iGroupID); + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + $groupidExists = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($groupidExists)) + return array('status' => 'Error: Invalid group ID'); + + if($surveyidExists['active']=='Y') + return array('status' => 'Error:Survey is active and not editable'); + + if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) + { + LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); + $iGroupsDeleted = Groups::deleteWithDependency($iGroupID, $iSurveyID); + + if ($iGroupsDeleted === 1) + fixSortOrderGroups($iSurveyID); + + LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); + + if ($iGroupsDeleted === 1) + return $iGroupID; + else + return array('status' => 'Group deletion failed'); + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + /** + * RPC routine to return the ids and info of groups belonging to survey + * Returns array of ids and info + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @return array + * @throws Zend_XmlRpc_Server_Exception + */ + public function get_group_list($sSessionKey, $iSurveyID) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) + { + $group_list = Groups::model()->findAllByAttributes(array("sid"=>$iSurveyID)); + if(count($group_list)==0) + return array('status' => 'No groups found'); + + foreach ($group_list as $group) + { + $aData[]= array('id'=>$group->primaryKey,'group_name'=>$group->attributes['group_name']); + } + return $aData; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + + /** + * RPC routine to return settings of a group of a survey + * Returns array of properties + * + * @access public + * @param string $sSessionKey + * @param int $iGroupID + * @param array $aGroupSettings + * @return array + * @throws Zend_XmlRpc_Server_Exception + */ + public function get_group_settings($sSessionKey, $iGroupID, $aGroupSettings) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $current_group = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($current_group)) + return array('status' => 'Error: Invalid group ID'); + + $aBasicDestinationFields=Groups::model()->tableSchema->columnNames; + $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); + + if (hasSurveyPermission($current_group->sid, 'survey', 'read')) + { + $abasic_attrs = $current_group ->getAttributes(); + foreach($aGroupSettings as $sGroupSetting) + { + if (isset($abasic_attrs[$sGroupSetting])) + $result[$sGroupSetting]=$abasic_attrs[$sGroupSetting]; + else + $result[$sGroupSetting]='Data not available'; + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + + /** + * RPC routine to modify group settings + * + * @access public + * @param string $sSessionKey + * @param integer $iGroupID - ID of the survey + * @param array|struct $aGroupData - An array with the particular fieldnames as keys and their values to set on that particular survey + * @return array of succeeded and failed modifications according to internal validation. + */ + public function modify_group_settings($sSessionKey, $iGroupID, $aGroupData) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oGroup=Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (is_null($oGroup)) + { + return array('status' => 'Error: Invalid group ID'); + } + if (hasSurveyPermission($oGroup->sid, 'survey', 'update')) + { + $succeded = array(); + $failed = array(); + // Remove fields that may not be modified + unset($aGroupData['sid']); + unset($aGroupData['gid']); + // Remove invalid fields + $aDestinationFields=array_flip(Groups::model()->tableSchema->columnNames); + $aGroupData=array_intersect_key($aGroupData,$aDestinationFields); + + foreach($aGroupData as $sFieldName=>$sValue) + { + $valid_value = $this->_internal_validate($sFieldName,$sValue); + + if ($valid_value === false) + $failed[$sFieldName]=$sValue; + else + { + //all dependencies this group has + $has_dependencies=getGroupDepsForConditions($oGroup->sid,$iGroupID); + //all dependencies on this group + $depented_on = getGroupDepsForConditions($oGroup->sid,"all",$iGroupID,"by-targgid"); + //We do not allow groups with dependencies to change order - that would lead to broken dependencies + + if((isset($has_dependencies) || isset($depented_on)) && $sFieldName == 'group_order') + $failed[$sFieldName]='Group with dependencies - Order cannot be changed'; + else + { + $oGroup->setAttribute($sFieldName,$valid_value); + $succeded[$sFieldName]=$sValue; + } + } + } + try + { + $oGroup->save(); // save the change to database + fixSortOrderGroups($oGroup->sid); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session key'); + } + /** diff --git a/application/models/Groups.php b/application/models/Groups.php index a9027c82601..08e5ecc97e4 100644 --- a/application/models/Groups.php +++ b/application/models/Groups.php @@ -86,7 +86,7 @@ function updateGroupOrder($sid,$lang,$position=0) ->order('group_order, group_name ASC') ->from('{{groups}}') ->bindParam(':sid', $sid, PDO::PARAM_INT) - ->bindParam(':language', $language, PDO::PARAM_STR) + ->bindParam(':language', $lang, PDO::PARAM_STR) ->query(); $position = intval($position); From ec61d9e0973d180cad15c9a23808904c1d8df58c Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 24 Jul 2012 16:04:43 +0300 Subject: [PATCH 05/75] New feature : Remotecontrol functions for manipulation of tokens Dev: Created new functions: Delete tokens, get_token_list, get_token_settings, modify_token_settings Dev: Implemented token_return function --- .../controllers/admin/remotecontrol.php | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index bb6e6347630..4e384c08e69 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1130,6 +1130,259 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b return array('status' => 'No permission'); } + + /** + * RPC routing to to return unused Tokens. + * Returns the unused tokens in an Array. + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @return array + */ + public function token_return($sSessionKey, $iSurveyID) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + { + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); + if(count($oTokens)==0) + return array('status' => 'No unused Tokens found'); + + foreach ($oTokens as $token) + { + $aData[] = $token->attributes['token']; + } + return $aData; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + /** + * RPC routine to return the ids and info of tokens of a survey + * Returns array of ids and info + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @return array + */ + public function get_token_list($sSessionKey, $iSurveyID) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + { + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(); + if(count($oTokens)==0) + return array('status' => 'No Tokens found'); + + foreach ($oTokens as $token) + { + $aData[] = array( + 'tid'=>$token->primarykey, + 'token'=>$token->attributes['token'], + 'participant_info'=>array( + 'firstname'=>$token->attributes['firstname'], + 'lastname'=>$token->attributes['lastname'], + 'email'=>$token->attributes['email'], + )); + } + return $aData; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + /** + * RPC routine to delete multiple token records + * Returns the id of the deleted token + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param array $aTokenIDs + * @return array + */ + public function delete_tokens($sSessionKey, $iSurveyID, $aTokenIDs) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $iSurveyID = sanitize_int($iSurveyID); + + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'delete')) + { + $result=array(); + foreach($aTokenIDs as $iTokenID) + { + $tokenidExists = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($tokenidExists)) + $result[$iTokenID]='Invalid token ID'; + else + { + Survey_links::deleteTokenLink(array($iTokenID), $iSurveyID); + if(Tokens_dynamic::model($iSurveyID)->deleteRecords(array($iTokenID))) + $result[$iTokenID]='Deleted'; + else + $result[$iTokenID]='Deletion went wrong'; + } + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + + /** + * RPC routine to return settings of a token of a survey + * Returns string + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param int $iTokenID + * @param array $aTokenProperties + * @return array + */ + public function get_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTokenProperties) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($oToken)) + return array('status' => 'Error: Invalid tokenid'); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + { + $result=array(); + $aBasicDestinationFields=Tokens_dynamic::model()->tableSchema->columnNames; + $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); + $abasic_attrs = $oToken->getAttributes(); + + foreach($aTokenProperties as $sproperty_name ) + { + if (isset($abasic_attrs[$sproperty_name])) + $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Data not available'; + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + /** + * RPC routine to modify settings of a token of a survey + * Returns array + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param int $iTokenID + * @param array|struct $aTokenData + * @return array + */ + public function modify_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTokenData) + { + if ($this->_checkSessionKey($sSessionKey)) + { + + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($oToken)) + return array('status' => 'Error: Invalid tokenid'); + + $succeded = array(); + $failed = array(); + // Remove fields that may not be modified + unset($aTokenData['tid']); + + $aBasicDestinationFields=array_flip(Tokens_dynamic::model()->tableSchema->columnNames); + $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) + { + foreach($aTokenData as $sFieldName=>$sValue) + { + if($this->_internal_validate($sFieldName,$sValue)) + { + $oToken->$sFieldName=$sValue; + $succeded[$sFieldName]=$sValue; + } + else + $failed[$sFieldName]=$sValue; + } + try + { + $oToken->save(); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + /** * RPC routine to create an empty group with minimum details * Used as a placeholder for importing questions From a0dcbad8f7a9eb3e9f1c58cc3d27f036374364db Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 25 Jul 2012 15:18:41 +0300 Subject: [PATCH 06/75] New feature : Remotecontrol functions for manipulation of questions Dev: Created new functions: Import_question, delete_question, get_question_list, get_question_settings, modify_question_settings --- .../controllers/admin/remotecontrol.php | 356 ++++++++++++++++++ 1 file changed, 356 insertions(+) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 4e384c08e69..7372a512c91 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1713,6 +1713,362 @@ public function modify_group_settings($sSessionKey, $iGroupID, $aGroupData) } + /** + * RPC routine to import a question - imports lsq,csv + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID the id of the survey that the question will belong + * @param int $iGroupID the id of the group that the question will belong + * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv + * @param string $sImportDataType lsq,csv + * @param string $sMandatory + * @param string $sNewQuestionTitle Optional new title for the question + * @param string $sNewqQuestion An optional new question + * @param string $sNewQuestionHelp An optional new question help text + * @return integer iQuestionID - ID of the new question + */ + public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData, $sImportDataType, $sMandatory='N', $sNewQuestionTitle=NULL, $sNewqQuestion=NULL, $sNewQuestionHelp=NULL) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) + return array('status' => 'Error: Invalid survey ID'); + + if($oSurvey->getAttribute('active') =='Y') + return array('status' => 'Error:Survey is Active and not editable'); + + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($oGroup)) + return array('status' => 'Error: Invalid group ID'); + + $gsid = $oGroup['sid']; + if($gsid != $iSurveyID) + return array('status' => 'Error: IMissmatch in surveyid and groupid'); + + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + { + if (!in_array($sImportDataType,array('csv','lsq'))) return array('status' => 'Invalid extension'); + libxml_use_internal_errors(true); + Yii::app()->loadHelper('admin/import'); + // First save the data to a temporary file + $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; + file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); + + if (strtolower($sImportDataType)=='csv') + { + $aImportResults = CSVImportQuestion($sFullFilePath, $iSurveyID, $iGroupID); + } + elseif ( strtolower($sImportDataType)=='lsq') + { + + $xml = simplexml_load_file($sFullFilePath); + if(!$xml) + { + unlink($sFullFilePath); + return array('status' => 'Error: Invalid LimeSurvey question structure XML '); + } + $aImportResults = XMLImportQuestion($sFullFilePath, $iSurveyID, $iGroupID); + } + else + return array('status' => 'Really Invalid extension'); //just for symmetry! + + unlink($sFullFilePath); + + if (isset($aImportResults['fatalerror'])) return array('status' => 'Error: '.$aImportResults['fatalerror']); + else + { + fixLanguageConsistency($iSurveyID); + $iNewqid = $aImportResults['newqid']; + + $oQuestion = Questions::model()->findByAttributes(array('sid' => $iSurveyID, 'gid' => $iGroupID, 'qid' => $iNewqid)); + if($sNewQuestionTitle!=NULL) + $oQuestion->setAttribute('title',$sNewQuestionTitle); + if($sNewqQuestion!='') + $oQuestion->setAttribute('question',$sNewqQuestion); + if($sNewQuestionHelp!='') + $oQuestion->setAttribute('help',$sNewQuestionHelp); + if(in_array($sMandatory, array('Y','N'))) + $oQuestion->setAttribute('mandatory',$sMandatory); + else + $oQuestion->setAttribute('mandatory','N'); + + try + { + $oQuestion->save(); + } + catch(Exception $e) + { + // no need to throw exception + } + return $aImportResults['newqid']; + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + + /** + * RPC routine to delete a question of a survey + * Returns the id of the deleted question + * + * @access public + * @param string $sSessionKey + * @param int iQuestionID + * @return string + */ + public function delete_question($sSessionKey, $iQuestionID) + { + if ($this->_checkSessionKey($sSessionKey)) + { + + $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); + if (!isset($oQuestion)) + return array('status' => 'Error: Invalid question ID'); + + $iSurveyID = $oQuestion['sid']; + $oSurvey = Survey::model()->findByPk($iSurveyID); + + if($oSurvey['active']=='Y') + return array('status' => 'Survey is active and not editable'); + $iGroupID=$oQuestion['gid']; + + if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) + { + $oCondition = Conditions::model()->findAllByAttributes(array('cqid' => $iQuestionID)); + if(count($oCondition)>0) + return array('status' => 'Cannot delete Question. Others rely on this question'); + + LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL,$iQuestionID); + + try + { + Conditions::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Question_attributes::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Answers::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + + $criteria = new CDbCriteria; + $criteria->addCondition('qid = :qid or parent_qid = :qid'); + $criteria->params[':qid'] = $iQuestionID; + Questions::model()->deleteAll($criteria); + + Defaultvalues::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Quota_members::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Questions::updateSortOrder($iGroupID, $iSurveyID); + + return $iQuestionID; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } + + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + + + /** + * RPC routine to return the ids and info of questions of a survey/group + * Returns array of ids and info + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param int $iGroupID + * @return array + */ + public function get_question_list($sSessionKey, $iSurveyID, $iGroupID=NULL) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) + { + if($iGroupID!=NULL) + { + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + $gsid = $oGroup['sid']; + + if($gsid != $iSurveyID) + return array('status' => 'Error: IMissmatch in surveyid and groupid'); + else + $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID, "gid"=>$iGroupID,"parent_qid"=>"0")); + } + else + $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID,"parent_qid"=>"0")); + + if(count($aQuestionList)==0) + return array('status' => 'No questions found'); + + foreach ($aQuestionList as $question) + { + $aData[]= array('id'=>$question->primaryKey,'type'=>$question->attributes['type'], 'question'=>$question->attributes['question']); + } + return $aData; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + + /** + * RPC routine to return properties of a question of a survey + * Returns string + * + * @access public + * @param string $sSessionKey + * @param int $iQuestionID + * @param array $aQuestionSettings + * @return array + */ + public function get_question_settings($sSessionKey, $iQuestionID, $aQuestionSettings) + { + + if ($this->_checkSessionKey($sSessionKey)) + { + $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); + if (!isset($oQuestion)) + return array('status' => 'Error: Invalid questionid', 22); + + $aBasicDestinationFields=Questions::model()->tableSchema->columnNames; + array_push($aBasicDestinationFields,'available_answers') ; + $aQuestionSettings=array_intersect($aQuestionSettings,$aBasicDestinationFields); + + if (empty($aQuestionSettings)) + return array('status' => 'No valid Data'); + + if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) + { + $abasic_attrs = $oQuestion->getAttributes(); + $result=array(); + foreach ($aQuestionSettings as $sproperty_name ) + { + if ($sproperty_name == 'available_answers') + { + $subgroups = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID),array('order'=>'title') ); + if (count($subgroups)>0) + { + foreach($subgroups as $subgroup) + $aData[$subgroup['title']]= $subgroup['question']; + + $result['available_answers']=$aData; + } + else + $result['available_answers']='No available answers'; + } + else + { + if (isset($abasic_attrs[$sproperty_name])) + $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Data not available'; + + } + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + /** + * RPC routine to modify group settings + * + * @access public + * @param string $sSessionKey + * @param integer $iQuestionID - ID of the question + * @param array|struct $aQuestionData - An array with the particular fieldnames as keys and their values to set on that particular question + * @return array of succeeded and failed modifications according to internal validation. + */ + public function modify_question_settings($sSessionKey, $iQuestionID, $aQuestionData) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oQuestion=Questions::model()->findByAttributes(array('qid' => $iQuestionID)); + if (is_null($oQuestion)) + return array('status' => 'Error: Invalid group ID'); + + if (hasSurveyPermission($oQuestion->sid, 'survey', 'update')) + { + $succeded = array(); + $failed = array(); + // Remove fields that may not be modified + unset($aQuestionData['qid']); + unset($aQuestionData['gid']); + unset($aQuestionData['sid']); + unset($aQuestionData['parent_qid']); + unset($aQuestionData['language']); + unset($aQuestionData['type']); + // Remove invalid fields + $aDestinationFields=array_flip(Questions::model()->tableSchema->columnNames); + $aQuestionData=array_intersect_key($aQuestionData,$aDestinationFields); + + if (empty($aQuestionData)) + return array('status' => 'No valid Data'); + + foreach($aQuestionData as $sFieldName=>$sValue) + { + $valid_value = $this->_internal_validate($sFieldName,$sValue); + + if ($valid_value === false) + $failed[$sFieldName]=$sValue; + else + { + //all the dependencies that this question has to other questions + $dependencies=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,$iQuestionID); + //all dependencies by other questions to this question + $is_criteria_question=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,"all",$iQuestionID,"by-targqid"); + //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies + + if((isset($dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') + $failed[$sFieldName]='Questions with dependencies - Order cannot be changed'; + else + { + $oQuestion->setAttribute($sFieldName,$valid_value); + $succeded[$sFieldName]=$sValue; + } + } + } + try + { + $oQuestion->save(); // save the change to database + fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session key'); + } + + /** * Tries to login with username and password From 40c2cd72b0c351c85f9828a4bfdb3e45a23617a2 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 25 Jul 2012 15:47:32 +0300 Subject: [PATCH 07/75] Fixed issue: Empty settings array returns status message in get-modify survey,group,token --- .../controllers/admin/remotecontrol.php | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 7372a512c91..9d973d85d5c 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -230,7 +230,6 @@ public function get_site_settings($sSessionKey,$sSetttingName) * @param string $sSurveyLanguage * @param string $sformat * @return string - * @throws Zend_XmlRpc_Server_Exception */ public function create_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLanguage, $sformat = 'G') { @@ -428,7 +427,6 @@ public function import_survey($sSessionKey, $sImportData, $sImportDataType, $sNe * @param string $sSessionKey * @param string $suser * @return array - * @throws Zend_XmlRpc_Server_Exception */ public function get_survey_list($sSessionKey, $suser='') { @@ -588,6 +586,10 @@ public function modify_survey_settings($sSessionKey, $iSurveyID, $aSurveyData) unset($aSurveyData['refurl']); } + + if (empty($aSurveyData)) + return array('status' => 'No valid Data'); + foreach($aSurveyData as $sFieldName=>$sValue) { if($this->_internal_validate($sFieldName,$sValue)) @@ -659,6 +661,10 @@ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurvey $oSurveyLocale = Surveys_languagesettings::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLanguage)); $succeded = array(); $failed = array(); + + if (empty($aSurveyLocaleData)) + return array('status' => 'No valid Data'); + foreach($aSurveyLocaleData as $sFieldName=>$sValue) { if($this->_internal_validate($sFieldName,$sValue)) @@ -791,7 +797,6 @@ function export_reponses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCod * @param string $docType * @param string $graph * @return string - * @throws Zend_XmlRpc_Server_Exception */ public function send_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') { @@ -1081,7 +1086,6 @@ public function add_response($sSessionKey, $iSurveyID, $aResponseData) * @param struct $aParticipantData * @param bool Optional - Defaults to true and determins if the access token automatically created * @return array - * @throws Zend_XmlRpc_Server_Exception */ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $bCreateToken=true) { @@ -1301,6 +1305,9 @@ public function get_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTokenP $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); $abasic_attrs = $oToken->getAttributes(); + if (empty($aTokenProperties)) + return array('status' => 'No valid Data'); + foreach($aTokenProperties as $sproperty_name ) { if (isset($abasic_attrs[$sproperty_name])) @@ -1353,7 +1360,10 @@ public function modify_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTok $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) - { + { + if (empty($aTokenData)) + return array('status' => 'No valid Data'); + foreach($aTokenData as $sFieldName=>$sValue) { if($this->_internal_validate($sFieldName,$sValue)) @@ -1394,7 +1404,6 @@ public function modify_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTok * @param string $sGroupTitle * @param string $sGroupDescription * @return string - * @throws Zend_XmlRpc_Server_Exception */ public function create_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescription='') { @@ -1520,7 +1529,6 @@ public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDat * @param int $iSurveyID * @param int $iGroupID * @return int - * @throws Zend_XmlRpc_Server_Exception */ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) { @@ -1569,7 +1577,6 @@ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) * @param string $sSessionKey * @param int $iSurveyID * @return array - * @throws Zend_XmlRpc_Server_Exception */ public function get_group_list($sSessionKey, $iSurveyID) { @@ -1608,7 +1615,6 @@ public function get_group_list($sSessionKey, $iSurveyID) * @param int $iGroupID * @param array $aGroupSettings * @return array - * @throws Zend_XmlRpc_Server_Exception */ public function get_group_settings($sSessionKey, $iGroupID, $aGroupSettings) { @@ -1624,6 +1630,10 @@ public function get_group_settings($sSessionKey, $iGroupID, $aGroupSettings) if (hasSurveyPermission($current_group->sid, 'survey', 'read')) { $abasic_attrs = $current_group ->getAttributes(); + + if (empty($aGroupSettings)) + return array('status' => 'No valid Data'); + foreach($aGroupSettings as $sGroupSetting) { if (isset($abasic_attrs[$sGroupSetting])) @@ -1669,7 +1679,10 @@ public function modify_group_settings($sSessionKey, $iGroupID, $aGroupData) // Remove invalid fields $aDestinationFields=array_flip(Groups::model()->tableSchema->columnNames); $aGroupData=array_intersect_key($aGroupData,$aDestinationFields); - + + if (empty($aGroupData)) + return array('status' => 'No valid Data'); + foreach($aGroupData as $sFieldName=>$sValue) { $valid_value = $this->_internal_validate($sFieldName,$sValue); From 87429e0802d081ebfa046aad3d556a220cdd61c6 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 25 Jul 2012 16:00:08 +0300 Subject: [PATCH 08/75] Fixed issue : Discriminate get_survey_locale_settings from get_survey_settings function --- .../controllers/admin/remotecontrol.php | 64 ++++++++++++++++--- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 9d973d85d5c..941c1b22322 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -701,10 +701,58 @@ public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurvey * @param string $sSessionKey * @param int $iSurveyID * @param array $aSurveySettings + * @return array + */ + public function get_survey_settings($sSessionKey,$iSurveyID, $aSurveySettings) + { + Yii::app()->loadHelper("surveytranslator"); + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + { + return array('status' => 'Error: Invalid survey ID'); + } + if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) + { + $aBasicDestinationFields=Survey::model()->tableSchema->columnNames; + $aSurveySettings=array_intersect($aSurveySettings,$aBasicDestinationFields); + + $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); + + $result = array(); + + if (empty($aSurveySettings)) + return array('status' => 'No valid Data'); + + foreach($aSurveySettings as $sproperty_name) + { + if (isset($abasic_attrs[$sproperty_name])) + $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Not available'; + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session key'); + } + + /** + * RPC routine to get survey settings + * Properties are those defined in tables surveys and surveys_language_settings + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param array $aSurveyLocaleSettings * @param string $slang * @return array */ - public function get_survey_settings($sSessionKey,$iSurveyID, $aSurveySettings, $slang=NULL) + public function get_survey_locale_settings($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $slang=NULL) { Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) @@ -717,10 +765,8 @@ public function get_survey_settings($sSessionKey,$iSurveyID, $aSurveySettings, $ if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) { $aBasicDestinationFields=Surveys_languagesettings::model()->tableSchema->columnNames; - $aLanguageDestinationFields=Survey::model()->tableSchema->columnNames; - $aSurveyFields = array_merge($aBasicDestinationFields,$aLanguageDestinationFields); - $aSurveySettings=array_intersect($aSurveySettings,$aSurveyFields); + $aSurveyLocaleSettings=array_intersect($aSurveyLocaleSettings,$aBasicDestinationFields); $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); @@ -730,11 +776,13 @@ public function get_survey_settings($sSessionKey,$iSurveyID, $aSurveySettings, $ $alang_attrs = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $slang))->getAttributes(); $result = array(); - foreach($aSurveySettings as $sproperty_name) + + if (empty($aSurveyLocaleSettings)) + return array('status' => 'No valid Data'); + + foreach($aSurveyLocaleSettings as $sproperty_name) { - if (isset($abasic_attrs[$sproperty_name])) - $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; - elseif (isset($alang_attrs[$sproperty_name])) + if (isset($alang_attrs[$sproperty_name])) $result[$sproperty_name]=$alang_attrs[$sproperty_name]; else $result[$sproperty_name]='Not available'; From f2a0bb2e01a51a57885f78acd34f0f6484e029bf Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Thu, 26 Jul 2012 10:28:56 +0300 Subject: [PATCH 09/75] Fixed issue: Incorporated token_return functionality into get_token_list --- .../controllers/admin/remotecontrol.php | 54 ++++--------------- 1 file changed, 9 insertions(+), 45 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 941c1b22322..1649860105a 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1182,71 +1182,35 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b return array('status' => 'No permission'); } - - /** - * RPC routing to to return unused Tokens. - * Returns the unused tokens in an Array. - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @return array - */ - public function token_return($sSessionKey, $iSurveyID) - { - if ($this->_checkSessionKey($sSessionKey)) - { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - - if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) - { - $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); - if(count($oTokens)==0) - return array('status' => 'No unused Tokens found'); - - foreach ($oTokens as $token) - { - $aData[] = $token->attributes['token']; - } - return $aData; - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session Key'); - } - /** * RPC routine to return the ids and info of tokens of a survey * Returns array of ids and info + * if $bUnused is true, user will get the list of not completed tokens (old token_return functionality) * * @access public * @param string $sSessionKey * @param int $iSurveyID + * @param bool $bUnused * @return array */ - public function get_token_list($sSessionKey, $iSurveyID) + public function get_token_list($sSessionKey, $iSurveyID, $bUnused=false) { if ($this->_checkSessionKey($sSessionKey)) { $surveyidExists = Survey::model()->findByPk($iSurveyID); if (!isset($surveyidExists)) return array('status' => 'Error: Invalid survey ID'); - if(!tableExists("{{tokens_$iSurveyID}}")) return array('status' => 'Error: No token table'); - - + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) { - $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(); + if($bUnused) + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); + else + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(); + if(count($oTokens)==0) return array('status' => 'No Tokens found'); From 7b61ae6cac14030bb325481cb486b3d01637c560 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Thu, 26 Jul 2012 10:43:52 +0300 Subject: [PATCH 10/75] Fixed Issue: Remotecontrol function add_participants Dev: Created Tokens_dynamic model function createToken Dev: Fixed inserting of values in token table --- .../controllers/admin/remotecontrol.php | 9 ++--- application/models/Tokens_dynamic.php | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 1649860105a..c0aeb712d05 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1150,18 +1150,19 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b return array('status' => 'No token table'); $aDestinationFields = Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}')->getColumnNames(); - $aDestinationFields = array_flip($field_names); + $aDestinationFields = array_flip($aDestinationFields); foreach ($aParticipantData as &$aParticipant) { $aParticipant=array_intersect_key($aParticipant,$aDestinationFields); - Tokens_dynamic::sid($iSurveyID); - $token = new Tokens_dynamic; - if ($token->insert($aParticipant)) + if ($token->insert()) { + foreach ($aParticipant as $k => $v) + $token->$k = $v; + $inresult = $token->save(); $new_token_id = $token->primaryKey; if ($bCreateToken) diff --git a/application/models/Tokens_dynamic.php b/application/models/Tokens_dynamic.php index e8757a1c2a7..2f9853479a2 100644 --- a/application/models/Tokens_dynamic.php +++ b/application/models/Tokens_dynamic.php @@ -163,6 +163,42 @@ function selectEmptyTokens($iSurveyID) { return Yii::app()->db->createCommand("SELECT tid FROM {{tokens_{$iSurveyID}}} WHERE token IS NULL OR token=''")->queryAll(); } + + /** + * Creates and inserts token for a specific token record and returns the token string created + * + * @param int $iTokenID + * @return string token string + */ + function createToken($iTokenID) + { + //get token length from survey settings + $tlrow = Survey::model()->findByAttributes(array("sid"=>self::$sid)); + $iTokenLength = $tlrow->tokenlength; + + //get all existing tokens + $criteria = $this->getDbCriteria(); + $criteria->select = 'token'; + $ntresult = $this->findAllAsArray($criteria); + foreach ($ntresult as $tkrow) + { + $existingtokens[] = $tkrow['token']; + } + //create new_token + $bIsValidToken = false; + while ($bIsValidToken == false) + { + $newtoken = randomChars($iTokenLength); + if (!in_array($newtoken, $existingtokens)) { + $existingtokens[] = $newtoken; + $bIsValidToken = true; + } + } + //update specific token row + $itresult = $this->updateToken($iTokenID, $newtoken); + return $newtoken; + } + /** * Creates tokens for all token records that have empty token fields and returns the number * of tokens created From 023d929472ce11cba8ded7665dccd84eb8c191ce Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Thu, 26 Jul 2012 12:57:57 +0300 Subject: [PATCH 11/75] Updated feature : Remote control functions new naming schema Dev: Adapt all functions to the naming schema - add,delete,import,export,get,set,list,activate Dev: Reorder functions to creeate logical blocks --- .../controllers/admin/remotecontrol.php | 2360 ++++++++--------- 1 file changed, 1180 insertions(+), 1180 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index c0aeb712d05..bf3087ee7ed 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -87,12 +87,12 @@ public function test() { echo 'Survey '.$iSurveyID.' successfully activated.
'; } - $aResult=$myJSONRPCClient->activate_tokens($sSessionKey, $iSurveyID,array(1,2)); + $aResult=$myJSONRPCClient->activate_participant_tokens($sSessionKey, $iSurveyID,array(1,2)); if ($aResult['status']=='OK') { echo 'Tokens for Survey ID '.$iSurveyID.' successfully activated.
'; } - $aResult=$myJSONRPCClient->modify_survey_settings($sSessionKey, $iSurveyID,array('faxto'=>'0800-LIMESURVEY')); + $aResult=$myJSONRPCClient->set_survey_properties($sSessionKey, $iSurveyID,array('faxto'=>'0800-LIMESURVEY')); if ($aResult['status']=='OK') { echo 'Modified survey settings for survey '.$iSurveyID.'
'; @@ -102,7 +102,7 @@ public function test() { echo 'Added Arabian as additional language'.'
'; } - $aResult=$myJSONRPCClient->modify_survey_locale_settings($sSessionKey, $iSurveyID,array('surveyls_welcometext'=>'An Arabian welcome text!'),'ar'); + $aResult=$myJSONRPCClient->set_survey_language_properties($sSessionKey, $iSurveyID,array('surveyls_welcometext'=>'An Arabian welcome text!'),'ar'); if ($aResult['status']=='OK') { echo 'Modified survey locale setting welcometext for Arabian in survey ID '.$iSurveyID.'
'; @@ -219,8 +219,11 @@ public function get_site_settings($sSessionKey,$sSetttingName) return array('status' => 'Invalid session key'); } + + /* Survey specific functions */ + /** - * RPC routine to create an empty survey with minimum details + * RPC routine to add an empty survey with minimum details * Used as a placeholder for importing groups and/or questions * * @access public @@ -231,7 +234,7 @@ public function get_site_settings($sSessionKey,$sSetttingName) * @param string $sformat * @return string */ - public function create_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLanguage, $sformat = 'G') + public function add_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLanguage, $sformat = 'G') { Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) @@ -331,56 +334,6 @@ public function delete_survey($sSessionKey, $iSurveyID) return array('status' => 'Invalid session key'); } - /** - * RPC routine to activate a survey - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID The id of the survey to be activated - * @param string dStart - Optional parameter Startdate - * @param string dEnd - Optional parameter Expires - * @return array the result of the activation - */ - public function activate_survey($sSessionKey, $iSurveyID, $dStart='', $dEnd='') - { - if ($this->_checkSessionKey($sSessionKey)) - { - $oSurvey=Survey::model()->findByPk($iSurveyID); - if (is_null($oSurvey)) - return array('status' => 'Error: Invalid survey ID'); - - $date_pattern = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/'; - try - { - if($dStart!='' && filter_var($dStart, FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>$date_pattern)))) - Survey::model()->updateByPk($iSurveyID, array('startdate'=> $dStart)); - - if($dEnd!='' && filter_var($dEnd, FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>$date_pattern)))) - Survey::model()->updateByPk($iSurveyID, array('expires'=> $dEnd)); - } - catch(Exception $e) - { - //return array('status' => $e->getmessage()); - } - - if (hasSurveyPermission($iSurveyID, 'surveyactivation', 'update')) - { - Yii::app()->loadHelper('admin/activate'); - $aActivateResults = activateSurvey($iSurveyID); - - if (isset($aActivateResults['error'])) return array('status' => 'Error: '.$aActivateResults['error']); - else - { - return $aActivateResults; - } - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid session key'); - } - /** * RPC routine to import a survey - imports lss,csv,xls or survey zip archive * @@ -417,137 +370,57 @@ public function import_survey($sSessionKey, $sImportData, $sImportDataType, $sNe return array('status' => 'Invalid session key'); } - /** - * RPC routine to return the ids and info of surveys belonging to a user - * Returns array of ids and info - * If user is admin he can get surveys of every user - * else only the syrveys belonging to the user requesting will be shown + /** + * RPC routine to get survey properties + * Properties are those defined in table surveys * * @access public * @param string $sSessionKey - * @param string $suser + * @param int $iSurveyID + * @param array $aSurveySettings * @return array */ - public function get_survey_list($sSessionKey, $suser='') - { - if ($this->_checkSessionKey($sSessionKey)) - { - $current_user = Yii::app()->session['user']; - if( Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1 and $suser !='') - $current_user = $suser; - - $aUserData = User::model()->findByAttributes(array('users_name' => $current_user)); - if (!isset($aUserData)) - return array('status' => 'Invalid user'); - - $user_surveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); - if(count($user_surveys)==0) - return array('status' => 'No surveys found'); - - foreach ($user_surveys as $asurvey) - { - $asurvey_ls = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $asurvey->primaryKey, 'surveyls_language' => $asurvey->language)); - if (!isset($asurvey_ls)) - $asurvey_title = ''; - else - $asurvey_title = $asurvey_ls->attributes['surveyls_title']; - $aData[]= array('sid'=>$asurvey->primaryKey,'surveyls_title'=>$asurvey_title,'startdate'=>$asurvey->attributes['startdate'],'expires'=>$asurvey->attributes['expires'],'active'=>$asurvey->attributes['active']); - } - return $aData; - } - else - return array('status' => 'Invalid session key'); - } - - /** - * RPC routine to get survey summary, regarding token usage and survey participation - * Return integer with the requested value - * @access public - * @param string $sSessionKey - * @param int $sid - * @param string $stats_name - * @return string - */ - public function get_survey_summary($sSessionKey,$iSurveyID, $stat_name) + public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) { - $permitted_stats = array(); + Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) - { - $permitted_token_stats = array('token_count', - 'token_invalid', - 'token_sent', - 'token_opted_out', - 'token_completed' - ); - $permitted_survey_stats = array('completed_responses', - 'incomplete_responses', - 'full_responses' - ); - $permitted_stats = array_merge($permitted_survey_stats, $permitted_token_stats); + { $surveyidExists = Survey::model()->findByPk($iSurveyID); if (!isset($surveyidExists)) - return array('status' => 'Invalid surveyid'); - - if(in_array($stat_name, $permitted_token_stats)) { - if (tableExists('{{tokens_' . $iSurveyID . '}}')) - $summary = Tokens_dynamic::model($iSurveyID)->summary(); - else - return array('status' => 'No available data'); - } - - if(in_array($stat_name, $permitted_survey_stats) && !tableExists('{{survey_' . $iSurveyID . '}}')) - return array('status' => 'No available data'); - - if (!in_array($stat_name, $permitted_stats)) - return array('status' => 'No such property'); - - if (hasSurveyPermission($iSurveyID, 'survey', 'read')) - { - switch($stat_name) + return array('status' => 'Error: Invalid survey ID'); + } + if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) { - case 'token_count': - if (isset($summary)) - return $summary['tkcount']; - break; - case 'token_invalid': - if (isset($summary)) - return $summary['tkinvalid']; - break; - case 'token_sent': - if (isset($summary)) - return $summary['tksent']; - break; - case 'token_opted_out': - if (isset($summary)) - return $summary['tkoptout']; - break; - case 'token_completed'; - if (isset($summary)) - return $summary['tkcompleted']; - break; - case 'completed_responses': - return Survey_dynamic::model($iSurveyID)->count('submitdate IS NOT NULL'); - break; - case 'incomplete_responses': - return Survey_dynamic::model($iSurveyID)->countByAttributes(array('submitdate' => null)); - break; - case 'full_responses'; - return Survey_dynamic::model($iSurveyID)->count(); - break; - default: - return array('status' => 'Data is not available'); + $aBasicDestinationFields=Survey::model()->tableSchema->columnNames; + $aSurveySettings=array_intersect($aSurveySettings,$aBasicDestinationFields); + + $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); + + $result = array(); + + if (empty($aSurveySettings)) + return array('status' => 'No valid Data'); + + foreach($aSurveySettings as $sproperty_name) + { + if (isset($abasic_attrs[$sproperty_name])) + $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Not available'; + } + return $result; } - } else - return array('status' => 'No permission'); + return array('status' => 'No permission'); } else - return array('status' => 'Invalid session key'); - } - + return array('status' => 'Invalid Session key'); + } + /** - * RPC routine to modify survey settings + * RPC routine to set survey properties + * Properties are those defined in table surveys * * @access public * @param string $sSessionKey @@ -555,7 +428,7 @@ public function get_survey_summary($sSessionKey,$iSurveyID, $stat_name) * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey * @return array of succeeded and failed nodifications according to internal validation. */ - public function modify_survey_settings($sSessionKey, $iSurveyID, $aSurveyData) + public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) { if ($this->_checkSessionKey($sSessionKey)) { @@ -618,221 +491,82 @@ public function modify_survey_settings($sSessionKey, $iSurveyID, $aSurveyData) return array('status' => 'Invalid Session key'); } - + /** + * RPC routine to list the ids and info of surveys belonging to a user + * Returns array of ids and info + * If user is admin he can get surveys of every user + * else only the syrveys belonging to the user requesting will be shown + * + * @access public + * @param string $sSessionKey + * @param string $suser + * @return array + */ + public function list_surveys($sSessionKey, $suser='') + { + if ($this->_checkSessionKey($sSessionKey)) + { + $current_user = Yii::app()->session['user']; + if( Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1 and $suser !='') + $current_user = $suser; + + $aUserData = User::model()->findByAttributes(array('users_name' => $current_user)); + if (!isset($aUserData)) + return array('status' => 'Invalid user'); + + $user_surveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); + if(count($user_surveys)==0) + return array('status' => 'No surveys found'); + + foreach ($user_surveys as $asurvey) + { + $asurvey_ls = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $asurvey->primaryKey, 'surveyls_language' => $asurvey->language)); + if (!isset($asurvey_ls)) + $asurvey_title = ''; + else + $asurvey_title = $asurvey_ls->attributes['surveyls_title']; + $aData[]= array('sid'=>$asurvey->primaryKey,'surveyls_title'=>$asurvey_title,'startdate'=>$asurvey->attributes['startdate'],'expires'=>$asurvey->attributes['expires'],'active'=>$asurvey->attributes['active']); + } + return $aData; + } + else + return array('status' => 'Invalid session key'); + } + + /** - * RPC routine to modify survey locale settings + * RPC routine to activate a survey * * @access public * @param string $sSessionKey - * @param integer $iSurveyID - ID of the survey - * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey - * @param string $aLanguage - Optional - Language to update - if not give the base language of the particular survey is used - * @return array status=>OK, when save successful otherwise error text. + * @param int $iSurveyID The id of the survey to be activated + + * @return array the result of the activation */ - public function modify_survey_locale_settings($sSessionKey, $iSurveyID, $aSurveyLocaleData, $sLanguage=NULL) + public function activate_survey($sSessionKey, $iSurveyID) { - Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) { $oSurvey=Survey::model()->findByPk($iSurveyID); if (is_null($oSurvey)) - { return array('status' => 'Error: Invalid survey ID'); - } - - if (is_null($sLanguage)) - { - $sLanguage=$oSurvey->language; - } - - if (!array_key_exists($sLanguage,getLanguageDataRestricted())) - return array('status' => 'Error: Invalid language'); - if (hasSurveyPermission($iSurveyID, 'surveylocale', 'update')) + if (hasSurveyPermission($iSurveyID, 'surveyactivation', 'update')) { - // Remove fields that may not be modified - unset($aSurveyLocaleData['surveyls_language']); - unset($aSurveyLocaleData['surveyls_survey_id']); - - // Remove invalid fields - $aDestinationFields=array_flip(Surveys_languagesettings::model()->tableSchema->columnNames); + Yii::app()->loadHelper('admin/activate'); + $aActivateResults = activateSurvey($iSurveyID); - $aSurveyLocaleData=array_intersect_key($aSurveyLocaleData,$aDestinationFields); - $oSurveyLocale = Surveys_languagesettings::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLanguage)); - $succeded = array(); - $failed = array(); - - if (empty($aSurveyLocaleData)) - return array('status' => 'No valid Data'); - - foreach($aSurveyLocaleData as $sFieldName=>$sValue) - { - if($this->_internal_validate($sFieldName,$sValue)) - { - $oSurveyLocale->$sFieldName=$sValue; - $succeded[$sFieldName]=$sValue; - } - else - $failed[$sFieldName]=$sValue; - } - try - { - $oSurveyLocale->save(); // save the change to database - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; - } - catch(Exception $e) + if (isset($aActivateResults['error'])) return array('status' => 'Error: '.$aActivateResults['error']); + else { - return array('status' => 'Error'); + return $aActivateResults; } } else return array('status' => 'No permission'); } - else - return array('status' => 'Invalid Session key'); - } - - /** - * RPC routine to get survey settings - * Properties are those defined in tables surveys and surveys_language_settings - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param array $aSurveySettings - * @return array - */ - public function get_survey_settings($sSessionKey,$iSurveyID, $aSurveySettings) - { - Yii::app()->loadHelper("surveytranslator"); - if ($this->_checkSessionKey($sSessionKey)) - { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - { - return array('status' => 'Error: Invalid survey ID'); - } - if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) - { - $aBasicDestinationFields=Survey::model()->tableSchema->columnNames; - $aSurveySettings=array_intersect($aSurveySettings,$aBasicDestinationFields); - - $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); - - $result = array(); - - if (empty($aSurveySettings)) - return array('status' => 'No valid Data'); - - foreach($aSurveySettings as $sproperty_name) - { - if (isset($abasic_attrs[$sproperty_name])) - $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; - else - $result[$sproperty_name]='Not available'; - } - return $result; - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session key'); - } - - /** - * RPC routine to get survey settings - * Properties are those defined in tables surveys and surveys_language_settings - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param array $aSurveyLocaleSettings - * @param string $slang - * @return array - */ - public function get_survey_locale_settings($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $slang=NULL) - { - Yii::app()->loadHelper("surveytranslator"); - if ($this->_checkSessionKey($sSessionKey)) - { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - { - return array('status' => 'Error: Invalid survey ID'); - } - if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) - { - $aBasicDestinationFields=Surveys_languagesettings::model()->tableSchema->columnNames; - - $aSurveyLocaleSettings=array_intersect($aSurveyLocaleSettings,$aBasicDestinationFields); - - $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); - - if ($slang == NULL || !array_key_exists($slang,getLanguageDataRestricted())) - $slang = $abasic_attrs['language']; - - $alang_attrs = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $slang))->getAttributes(); - - $result = array(); - - if (empty($aSurveyLocaleSettings)) - return array('status' => 'No valid Data'); - - foreach($aSurveyLocaleSettings as $sproperty_name) - { - if (isset($alang_attrs[$sproperty_name])) - $result[$sproperty_name]=$alang_attrs[$sproperty_name]; - else - $result[$sproperty_name]='Not available'; - } - return $result; - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session key'); - } - - /** - * RPC routine to export responses - * Returns the requested file as base64 encoded string - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param string $sDocumentType pdf,csv,xls,doc - * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to complete - * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' - * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' - * @param integer $iFromResponseID Optional - * @param integer $iToResponseID Optional - * @return On success: Requested file as base 64-encoded string. On failure array with error information - **/ - function export_reponses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode=null, $sCompletionStatus='all', $sHeadingType='code', $sResponseType='short', $iFromResponseID=null, $iToResponseID=null, $aFields=null) - { - if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); - Yii::app()->loadHelper('admin/exportresults'); - if (!hasSurveyPermission($iSurveyID, 'responses', 'export')) return array('status' => 'No permission'); - if (is_null($sLanguageCode)) $sLanguageCode=getBaseLanguageFromSurveyID($iSurveyID); - if (is_null($aFields)) $aFields=array_keys(createFieldMap($iSurveyID,'full',true,false,$sLanguageCode)); - if($sDocumentType=='xls'){ - // Cut down to the first 255 fields - $aFields=array_slice($aFields,0,255); - } - $oFomattingOptions=new FormattingOptions(); - $oFomattingOptions->format=$sDocumentType; - $oFomattingOptions->responseMinRecord=$iFromResponseID; - $oFomattingOptions->responseMaxRecord=$iToResponseID; - $oFomattingOptions->selectedColumns=$aFields; - $oFomattingOptions->responseCompletionState=$sCompletionStatus; - $oFomattingOptions->headingFormat=$sHeadingType; - $oFomattingOptions->answerFormat=$sResponseType; - $oExport=new ExportSurveyResultsService(); - $sFileData=$oExport->exportSurvey($iSurveyID,$sLanguageCode,$oFomattingOptions,'return'); - return base64_encode($sFileData); + else + return array('status' => 'Invalid session key'); } /** @@ -846,7 +580,7 @@ function export_reponses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCod * @param string $graph * @return string */ - public function send_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') + public function export_survey_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') { Yii::app()->loadHelper('admin/statistics'); @@ -906,6 +640,95 @@ public function send_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph } } + /** + * RPC routine to get survey summary, regarding token usage and survey participation + * Return integer with the requested value + * @access public + * @param string $sSessionKey + * @param int $sid + * @param string $stats_name + * @return string + */ + public function get_survey_summary($sSessionKey,$iSurveyID, $stat_name) + { + $permitted_stats = array(); + if ($this->_checkSessionKey($sSessionKey)) + { + $permitted_token_stats = array('token_count', + 'token_invalid', + 'token_sent', + 'token_opted_out', + 'token_completed' + ); + $permitted_survey_stats = array('completed_responses', + 'incomplete_responses', + 'full_responses' + ); + $permitted_stats = array_merge($permitted_survey_stats, $permitted_token_stats); + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Invalid surveyid'); + + if(in_array($stat_name, $permitted_token_stats)) + { + if (tableExists('{{tokens_' . $iSurveyID . '}}')) + $summary = Tokens_dynamic::model($iSurveyID)->summary(); + else + return array('status' => 'No available data'); + } + + if(in_array($stat_name, $permitted_survey_stats) && !tableExists('{{survey_' . $iSurveyID . '}}')) + return array('status' => 'No available data'); + + if (!in_array($stat_name, $permitted_stats)) + return array('status' => 'No such property'); + + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) + { + switch($stat_name) + { + case 'token_count': + if (isset($summary)) + return $summary['tkcount']; + break; + case 'token_invalid': + if (isset($summary)) + return $summary['tkinvalid']; + break; + case 'token_sent': + if (isset($summary)) + return $summary['tksent']; + break; + case 'token_opted_out': + if (isset($summary)) + return $summary['tkoptout']; + break; + case 'token_completed'; + if (isset($summary)) + return $summary['tkcompleted']; + break; + case 'completed_responses': + return Survey_dynamic::model($iSurveyID)->count('submitdate IS NOT NULL'); + break; + case 'incomplete_responses': + return Survey_dynamic::model($iSurveyID)->countByAttributes(array('submitdate' => null)); + break; + case 'full_responses'; + return Survey_dynamic::model($iSurveyID)->count(); + break; + default: + return array('status' => 'Data is not available'); + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + /*Survey language specific functions */ + /** * RPC routine to add a survey language * @@ -1026,1075 +849,1252 @@ public function delete_survey_language($sSessionKey, $iSurveyID, $sLanguage) } } + /** - * RPC routine to activate tokens + * RPC routine to get survey language properties + * Properties are those defined in table surveys_language_settings + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param array $aSurveyLocaleSettings + * @param string $slang + * @return array + */ + public function get_survey_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $slang=NULL) + { + Yii::app()->loadHelper("surveytranslator"); + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + { + return array('status' => 'Error: Invalid survey ID'); + } + if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) + { + $aBasicDestinationFields=Surveys_languagesettings::model()->tableSchema->columnNames; + + $aSurveyLocaleSettings=array_intersect($aSurveyLocaleSettings,$aBasicDestinationFields); + + $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); + + if ($slang == NULL || !array_key_exists($slang,getLanguageDataRestricted())) + $slang = $abasic_attrs['language']; + + $alang_attrs = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $slang))->getAttributes(); + + $result = array(); + + if (empty($aSurveyLocaleSettings)) + return array('status' => 'No valid Data'); + + foreach($aSurveyLocaleSettings as $sproperty_name) + { + if (isset($alang_attrs[$sproperty_name])) + $result[$sproperty_name]=$alang_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Not available'; + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session key'); + } + + /** + * RPC routine to set survey language properties + * Properties are those defined in table surveys_languagesettings * * @access public * @param string $sSessionKey - * @param integer $iSurveyID ID of the survey where a token table will be created for - * @param array $aAttributeFields An array of integer describing any additional attribute fields - * @return array Status=>OK when successfull, otherwise the error description + * @param integer $iSurveyID - ID of the survey + * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey + * @param string $aLanguage - Optional - Language to update - if not give the base language of the particular survey is used + * @return array status=>OK, when save successful otherwise error text. */ - public function activate_tokens($sSessionKey, $iSurveyID, $aAttributeFields=array()) + public function set_survey_language_properties($sSessionKey, $iSurveyID, $aSurveyLocaleData, $sLanguage=NULL) { - if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); - if (hasGlobalPermission('USER_RIGHT_CREATE_SURVEY')) + Yii::app()->loadHelper("surveytranslator"); + if ($this->_checkSessionKey($sSessionKey)) { $oSurvey=Survey::model()->findByPk($iSurveyID); if (is_null($oSurvey)) { return array('status' => 'Error: Invalid survey ID'); } - if (is_array($aAttributeFields) && count($aAttributeFields)>0) + + if (is_null($sLanguage)) { - foreach ($aAttributeFields as &$sField) - { - $sField= intval($sField); - $sField='attribute_'.$sField; - } - $aAttributeFields=array_unique($aAttributeFields); + $sLanguage=$oSurvey->language; } - Yii::app()->loadHelper('admin/token'); - if (createTokenTable($iSurveyID, $aAttributeFields)) + + if (!array_key_exists($sLanguage,getLanguageDataRestricted())) + return array('status' => 'Error: Invalid language'); + + if (hasSurveyPermission($iSurveyID, 'surveylocale', 'update')) { - return array('status' => 'OK'); + // Remove fields that may not be modified + unset($aSurveyLocaleData['surveyls_language']); + unset($aSurveyLocaleData['surveyls_survey_id']); + + // Remove invalid fields + $aDestinationFields=array_flip(Surveys_languagesettings::model()->tableSchema->columnNames); + + $aSurveyLocaleData=array_intersect_key($aSurveyLocaleData,$aDestinationFields); + $oSurveyLocale = Surveys_languagesettings::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLanguage)); + $succeded = array(); + $failed = array(); + + if (empty($aSurveyLocaleData)) + return array('status' => 'No valid Data'); + + foreach($aSurveyLocaleData as $sFieldName=>$sValue) + { + if($this->_internal_validate($sFieldName,$sValue)) + { + $oSurveyLocale->$sFieldName=$sValue; + $succeded[$sFieldName]=$sValue; + } + else + $failed[$sFieldName]=$sValue; + } + try + { + $oSurveyLocale->save(); // save the change to database + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } } else - { - return array('status' => 'Token table could not be created'); - } + return array('status' => 'No permission'); } else - return array('status' => 'No permission'); + return array('status' => 'Invalid Session key'); } - + /* Group specific functions */ /** - * RPC routine to add a response to the survey response table - * Returns the id of the inserted survey response - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param struct $aResponseData - * @return int The response ID - */ - public function add_response($sSessionKey, $iSurveyID, $aResponseData) - { - if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); - $oSurvey=Survey::model()->findByPk($iSurveyID); - if (is_null($oSurvey)) + * RPC routine to add an empty group with minimum details + * Used as a placeholder for importing questions + * Returns the groupid of the created group + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param string $sGroupTitle + * @param string $sGroupDescription + * @return string + */ + public function add_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescription='') + { + if ($this->_checkSessionKey($sSessionKey)) { - return array('status' => 'Error: Invalid survey ID'); - } + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if($surveyidExists['active']=='Y') + return array('status' => 'Error:Survey is active and not editable'); + + $group = new Groups; + $group->sid = $iSurveyID; + $group->group_name = $sGroupTitle; + $group->description = $sGroupDescription; + $group->group_order = getMaxGroupOrder($iSurveyID); + $group->language = Survey::model()->findByPk($iSurveyID)->language; + if($group->save()) + return $group->gid; + else + return array('status' => 'Creation Failed'); + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } - if (hasSurveyPermission($iSurveyID, 'responses', 'create')) + /** + * RPC routine to delete a group of a survey + * Returns the id of the deleted group + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param int $iGroupID + * @return int + */ + public function delete_group($sSessionKey, $iSurveyID, $iGroupID) + { + if ($this->_checkSessionKey($sSessionKey)) { - if (!Yii::app()->db->schema->getTable('{{survey_' . $iSurveyID . '}}')) - return array('status' => 'No survey response table'); - - //set required values if not set - - // @todo: Some of this is part of the validation and should be done in the model instead - if (!isset($aResponseData['submitdate'])) - $aResponseData['submitdate'] = date("Y-m-d H:i:s"); - if (!isset($aResponseData['startlanguage'])) - $aResponseData['startlanguage'] = getBaseLanguageFromSurveyID($iSurveyID); + $iSurveyID = sanitize_int($iSurveyID); + $iGroupID = sanitize_int($iGroupID); + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + $groupidExists = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($groupidExists)) + return array('status' => 'Error: Invalid group ID'); + + if($surveyidExists['active']=='Y') + return array('status' => 'Error:Survey is active and not editable'); - if ($oSurvey->datestamp=='Y') + if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) { - if (!isset($aResponseData['datestamp'])) - $aResponseData['datestamp'] = date("Y-m-d H:i:s"); - if (!isset($aResponseData['startdate'])) - $aResponseData['startdate'] = date("Y-m-d H:i:s"); - } - - Survey_dynamic::sid($iSurveyID); - $survey_dynamic = new Survey_dynamic; - $result = $survey_dynamic->insert($aResponseData); + LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); + $iGroupsDeleted = Groups::deleteWithDependency($iGroupID, $iSurveyID); + + if ($iGroupsDeleted === 1) + fixSortOrderGroups($iSurveyID); + + LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); - if ($result) - return $survey_dynamic->primaryKey; + if ($iGroupsDeleted === 1) + return $iGroupID; + else + return array('status' => 'Group deletion failed'); + } else - return array('status' => 'Unable to add response'); + return array('status' => 'No permission'); } else - return array('status' => 'No permission'); - - } + return array('status' => 'Invalid Session Key'); + } - /** - * RPC routine to add a participant to a token table - * Returns the inserted data including additional new information like the Token entry ID and the token + /** + * RPC routine to import a group - imports lsg,csv * * @access public * @param string $sSessionKey - * @param int $iSurveyID - * @param struct $aParticipantData - * @param bool Optional - Defaults to true and determins if the access token automatically created - * @return array - */ - public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $bCreateToken=true) + * @param int $iSurveyID the id of the survey that the group will belong + * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv + * @param string $sImportDataType lsg,csv + * @param string $sNewGroupName Optional new name for the group + * @param string $sNewGroupDescription Optional new description for the group + * @return integer iGroupID - ID of the new group + */ + public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDataType, $sNewGroupName=NULL, $sNewGroupDescription=NULL) { - if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); - $oSurvey=Survey::model()->findByPk($iSurveyID); - if (is_null($oSurvey)) - { - return array('status' => 'Error: Invalid survey ID'); - } + + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if($surveyidExists->getAttribute('active') =='Y') + return array('status' => 'Error:Survey is aCctive and not editable'); - if (hasSurveyPermission($iSurveyID, 'tokens', 'create')) - { - if (!Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}')) - return array('status' => 'No token table'); + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + { + if (!in_array($sImportDataType,array('csv','lsg'))) return array('status' => 'Invalid extension'); + libxml_use_internal_errors(true); + Yii::app()->loadHelper('admin/import'); + // First save the data to a temporary file + $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; + file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); - $aDestinationFields = Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}')->getColumnNames(); - $aDestinationFields = array_flip($aDestinationFields); + if (strtolower($sImportDataType)=='csv') + { + $aImportResults = CSVImportGroup($sFullFilePath, $iSurveyID); + } + elseif ( strtolower($sImportDataType)=='lsg') + { + $xml = simplexml_load_file($sFullFilePath); + if(!$xml) + { + unlink($sFullFilePath); + return array('status' => 'Error: Invalid LimeSurvey group structure XML '); + } + $aImportResults = XMLImportGroup($sFullFilePath, $iSurveyID); + } + else + return array('status' => 'Invalid extension'); //just for symmetry! - foreach ($aParticipantData as &$aParticipant) - { - $aParticipant=array_intersect_key($aParticipant,$aDestinationFields); - Tokens_dynamic::sid($iSurveyID); - $token = new Tokens_dynamic; + unlink($sFullFilePath); - if ($token->insert()) + if (isset($aImportResults['fatalerror'])) return array('status' => 'Error: '.$aImportResults['fatalerror']); + else { - foreach ($aParticipant as $k => $v) - $token->$k = $v; - $inresult = $token->save(); - $new_token_id = $token->primaryKey; + $iNewgid = $aImportResults['newgid']; + + $group = Groups::model()->findByAttributes(array('gid' => $iNewgid)); + $slang=$group['language']; + if($sNewGroupName!='') + $group->setAttribute('group_name',$sNewGroupName); + if($sNewGroupDescription!='') + $group->setAttribute('description',$sNewGroupDescription); + try + { + $group->save(); + } + catch(Exception $e) + { + // no need to throw exception + } + return $aImportResults['newgid']; + } + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } - if ($bCreateToken) - $token_string = Tokens_dynamic::model()->createToken($new_token_id); - else - $token_string = ''; - $aParticipant = array_merge($aParticipant, array( - 'tid' => $new_token_id, - 'token' => $token_string, - )); + /** + * RPC routine to return properties of a group of a survey + * Returns array of properties + * + * @access public + * @param string $sSessionKey + * @param int $iGroupID + * @param array $aGroupSettings + * @return array + */ + public function get_group_properties($sSessionKey, $iGroupID, $aGroupSettings) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $current_group = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($current_group)) + return array('status' => 'Error: Invalid group ID'); + + $aBasicDestinationFields=Groups::model()->tableSchema->columnNames; + $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); + + if (hasSurveyPermission($current_group->sid, 'survey', 'read')) + { + $abasic_attrs = $current_group ->getAttributes(); + + if (empty($aGroupSettings)) + return array('status' => 'No valid Data'); + + foreach($aGroupSettings as $sGroupSetting) + { + if (isset($abasic_attrs[$sGroupSetting])) + $result[$sGroupSetting]=$abasic_attrs[$sGroupSetting]; + else + $result[$sGroupSetting]='Data not available'; + } + return $result; + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid Session Key'); + } + + + /** + * RPC routine to set group properties + * + * @access public + * @param string $sSessionKey + * @param integer $iGroupID - ID of the survey + * @param array|struct $aGroupData - An array with the particular fieldnames as keys and their values to set on that particular survey + * @return array of succeeded and failed modifications according to internal validation. + */ + public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oGroup=Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (is_null($oGroup)) + { + return array('status' => 'Error: Invalid group ID'); + } + if (hasSurveyPermission($oGroup->sid, 'survey', 'update')) + { + $succeded = array(); + $failed = array(); + // Remove fields that may not be modified + unset($aGroupData['sid']); + unset($aGroupData['gid']); + // Remove invalid fields + $aDestinationFields=array_flip(Groups::model()->tableSchema->columnNames); + $aGroupData=array_intersect_key($aGroupData,$aDestinationFields); + + if (empty($aGroupData)) + return array('status' => 'No valid Data'); + + foreach($aGroupData as $sFieldName=>$sValue) + { + $valid_value = $this->_internal_validate($sFieldName,$sValue); + + if ($valid_value === false) + $failed[$sFieldName]=$sValue; + else + { + //all dependencies this group has + $has_dependencies=getGroupDepsForConditions($oGroup->sid,$iGroupID); + //all dependencies on this group + $depented_on = getGroupDepsForConditions($oGroup->sid,"all",$iGroupID,"by-targgid"); + //We do not allow groups with dependencies to change order - that would lead to broken dependencies + + if((isset($has_dependencies) || isset($depented_on)) && $sFieldName == 'group_order') + $failed[$sFieldName]='Group with dependencies - Order cannot be changed'; + else + { + $oGroup->setAttribute($sFieldName,$valid_value); + $succeded[$sFieldName]=$sValue; + } + } + } + try + { + $oGroup->save(); // save the change to database + fixSortOrderGroups($oGroup->sid); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); } } - - return $aParticipantData; + else + return array('status' => 'No permission'); } else - return array('status' => 'No permission'); + return array('status' => 'Invalid Session key'); } /** - * RPC routine to return the ids and info of tokens of a survey + * RPC routine to return the ids and info of groups belonging to survey * Returns array of ids and info - * if $bUnused is true, user will get the list of not completed tokens (old token_return functionality) * * @access public * @param string $sSessionKey * @param int $iSurveyID - * @param bool $bUnused * @return array */ - public function get_token_list($sSessionKey, $iSurveyID, $bUnused=false) + public function list_groups($sSessionKey, $iSurveyID) { if ($this->_checkSessionKey($sSessionKey)) { $surveyidExists = Survey::model()->findByPk($iSurveyID); if (!isset($surveyidExists)) return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - - if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { - if($bUnused) - $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); - else - $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(); - - if(count($oTokens)==0) - return array('status' => 'No Tokens found'); + $group_list = Groups::model()->findAllByAttributes(array("sid"=>$iSurveyID)); + if(count($group_list)==0) + return array('status' => 'No groups found'); - foreach ($oTokens as $token) - { - $aData[] = array( - 'tid'=>$token->primarykey, - 'token'=>$token->attributes['token'], - 'participant_info'=>array( - 'firstname'=>$token->attributes['firstname'], - 'lastname'=>$token->attributes['lastname'], - 'email'=>$token->attributes['email'], - )); - } + foreach ($group_list as $group) + { + $aData[]= array('id'=>$group->primaryKey,'group_name'=>$group->attributes['group_name']); + } return $aData; } else - return array('status' => 'No permission'); + return array('status' => 'No permission'); } else - return array('status' => 'Invalid Session Key'); + return array('status' => 'Invalid Session Key'); } + + /* Question specific functions */ + + /** - * RPC routine to delete multiple token records - * Returns the id of the deleted token + * RPC routine to delete a question of a survey + * Returns the id of the deleted question * * @access public * @param string $sSessionKey - * @param int $iSurveyID - * @param array $aTokenIDs - * @return array + * @param int iQuestionID + * @return string */ - public function delete_tokens($sSessionKey, $iSurveyID, $aTokenIDs) + public function delete_question($sSessionKey, $iQuestionID) { if ($this->_checkSessionKey($sSessionKey)) { - $iSurveyID = sanitize_int($iSurveyID); - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); + if (!isset($oQuestion)) + return array('status' => 'Error: Invalid question ID'); + + $iSurveyID = $oQuestion['sid']; + $oSurvey = Survey::model()->findByPk($iSurveyID); + + if($oSurvey['active']=='Y') + return array('status' => 'Survey is active and not editable'); + $iGroupID=$oQuestion['gid']; + + if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) + { + $oCondition = Conditions::model()->findAllByAttributes(array('cqid' => $iQuestionID)); + if(count($oCondition)>0) + return array('status' => 'Cannot delete Question. Others rely on this question'); + + LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL,$iQuestionID); + + try + { + Conditions::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Question_attributes::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Answers::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + + $criteria = new CDbCriteria; + $criteria->addCondition('qid = :qid or parent_qid = :qid'); + $criteria->params[':qid'] = $iQuestionID; + Questions::model()->deleteAll($criteria); + + Defaultvalues::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Quota_members::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); + Questions::updateSortOrder($iGroupID, $iSurveyID); + + return $iQuestionID; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } + + } + else + return array('status' => 'No permission'); + } + else + return array('status' => 'Invalid session key'); + } + + + /** + * RPC routine to import a question - imports lsq,csv + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID the id of the survey that the question will belong + * @param int $iGroupID the id of the group that the question will belong + * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv + * @param string $sImportDataType lsq,csv + * @param string $sMandatory + * @param string $sNewQuestionTitle Optional new title for the question + * @param string $sNewqQuestion An optional new question + * @param string $sNewQuestionHelp An optional new question help text + * @return integer iQuestionID - ID of the new question + */ + public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData, $sImportDataType, $sMandatory='N', $sNewQuestionTitle=NULL, $sNewqQuestion=NULL, $sNewQuestionHelp=NULL) + { + if ($this->_checkSessionKey($sSessionKey)) + { + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); + + if($oSurvey->getAttribute('active') =='Y') + return array('status' => 'Error:Survey is Active and not editable'); + + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($oGroup)) + return array('status' => 'Error: Invalid group ID'); - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); + $gsid = $oGroup['sid']; + if($gsid != $iSurveyID) + return array('status' => 'Error: IMissmatch in surveyid and groupid'); - if (hasSurveyPermission($iSurveyID, 'tokens', 'delete')) - { - $result=array(); - foreach($aTokenIDs as $iTokenID) + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + { + if (!in_array($sImportDataType,array('csv','lsq'))) return array('status' => 'Invalid extension'); + libxml_use_internal_errors(true); + Yii::app()->loadHelper('admin/import'); + // First save the data to a temporary file + $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; + file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); + + if (strtolower($sImportDataType)=='csv') { - $tokenidExists = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); - if (!isset($tokenidExists)) - $result[$iTokenID]='Invalid token ID'; - else + $aImportResults = CSVImportQuestion($sFullFilePath, $iSurveyID, $iGroupID); + } + elseif ( strtolower($sImportDataType)=='lsq') + { + + $xml = simplexml_load_file($sFullFilePath); + if(!$xml) { - Survey_links::deleteTokenLink(array($iTokenID), $iSurveyID); - if(Tokens_dynamic::model($iSurveyID)->deleteRecords(array($iTokenID))) - $result[$iTokenID]='Deleted'; - else - $result[$iTokenID]='Deletion went wrong'; + unlink($sFullFilePath); + return array('status' => 'Error: Invalid LimeSurvey question structure XML '); } + $aImportResults = XMLImportQuestion($sFullFilePath, $iSurveyID, $iGroupID); } - return $result; + else + return array('status' => 'Really Invalid extension'); //just for symmetry! + + unlink($sFullFilePath); + + if (isset($aImportResults['fatalerror'])) return array('status' => 'Error: '.$aImportResults['fatalerror']); + else + { + fixLanguageConsistency($iSurveyID); + $iNewqid = $aImportResults['newqid']; + + $oQuestion = Questions::model()->findByAttributes(array('sid' => $iSurveyID, 'gid' => $iGroupID, 'qid' => $iNewqid)); + if($sNewQuestionTitle!=NULL) + $oQuestion->setAttribute('title',$sNewQuestionTitle); + if($sNewqQuestion!='') + $oQuestion->setAttribute('question',$sNewqQuestion); + if($sNewQuestionHelp!='') + $oQuestion->setAttribute('help',$sNewQuestionHelp); + if(in_array($sMandatory, array('Y','N'))) + $oQuestion->setAttribute('mandatory',$sMandatory); + else + $oQuestion->setAttribute('mandatory','N'); + + try + { + $oQuestion->save(); + } + catch(Exception $e) + { + // no need to throw exception + } + return $aImportResults['newqid']; + } } else return array('status' => 'No permission'); } else - return array('status' => 'Invalid Session Key'); - } + return array('status' => 'Invalid session key'); + } /** - * RPC routine to return settings of a token of a survey + * RPC routine to return properties of a question of a survey * Returns string * * @access public * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iTokenID - * @param array $aTokenProperties + * @param int $iQuestionID + * @param array $aQuestionSettings * @return array */ - public function get_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTokenProperties) + public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSettings) { + if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - - $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); - if (!isset($oToken)) - return array('status' => 'Error: Invalid tokenid'); - - if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); + if (!isset($oQuestion)) + return array('status' => 'Error: Invalid questionid', 22); + + $aBasicDestinationFields=Questions::model()->tableSchema->columnNames; + array_push($aBasicDestinationFields,'available_answers') ; + $aQuestionSettings=array_intersect($aQuestionSettings,$aBasicDestinationFields); + + if (empty($aQuestionSettings)) + return array('status' => 'No valid Data'); + + if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) { + $abasic_attrs = $oQuestion->getAttributes(); $result=array(); - $aBasicDestinationFields=Tokens_dynamic::model()->tableSchema->columnNames; - $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); - $abasic_attrs = $oToken->getAttributes(); - - if (empty($aTokenProperties)) - return array('status' => 'No valid Data'); - - foreach($aTokenProperties as $sproperty_name ) - { + foreach ($aQuestionSettings as $sproperty_name ) + { + if ($sproperty_name == 'available_answers') + { + $subgroups = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID),array('order'=>'title') ); + if (count($subgroups)>0) + { + foreach($subgroups as $subgroup) + $aData[$subgroup['title']]= $subgroup['question']; + + $result['available_answers']=$aData; + } + else + $result['available_answers']='No available answers'; + } + else + { if (isset($abasic_attrs[$sproperty_name])) $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; else $result[$sproperty_name]='Data not available'; + + } } - return $result; + return $result; } else - return array('status' => 'No permission'); - } + return array('status' => 'No permission'); + } else - return array('status' => 'Invalid Session Key'); + return array('status' => 'Invalid session key'); } - /** - * RPC routine to modify settings of a token of a survey - * Returns array - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iTokenID - * @param array|struct $aTokenData - * @return array - */ - public function modify_token_settings($sSessionKey, $iSurveyID, $iTokenID, $aTokenData) - { - if ($this->_checkSessionKey($sSessionKey)) - { - - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - - $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); - if (!isset($oToken)) - return array('status' => 'Error: Invalid tokenid'); - - $succeded = array(); - $failed = array(); - // Remove fields that may not be modified - unset($aTokenData['tid']); - - $aBasicDestinationFields=array_flip(Tokens_dynamic::model()->tableSchema->columnNames); - $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); - - if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) - { - if (empty($aTokenData)) - return array('status' => 'No valid Data'); - - foreach($aTokenData as $sFieldName=>$sValue) - { - if($this->_internal_validate($sFieldName,$sValue)) - { - $oToken->$sFieldName=$sValue; - $succeded[$sFieldName]=$sValue; - } - else - $failed[$sFieldName]=$sValue; - } - try - { - $oToken->save(); - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; - } - catch(Exception $e) - { - return array('status' => 'Error'); - } - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session Key'); - } - - - /** - * RPC routine to create an empty group with minimum details - * Used as a placeholder for importing questions - * Returns the groupid of the created group - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param string $sGroupTitle - * @param string $sGroupDescription - * @return string - */ - public function create_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescription='') - { - if ($this->_checkSessionKey($sSessionKey)) - { - if (hasSurveyPermission($iSurveyID, 'survey', 'update')) - { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - if($surveyidExists['active']=='Y') - return array('status' => 'Error:Survey is active and not editable'); - - $group = new Groups; - $group->sid = $iSurveyID; - $group->group_name = $sGroupTitle; - $group->description = $sGroupDescription; - $group->group_order = getMaxGroupOrder($iSurveyID); - $group->language = Survey::model()->findByPk($iSurveyID)->language; - if($group->save()) - return $group->gid; - else - return array('status' => 'Creation Failed'); - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session Key'); - } - - /** - * RPC routine to import a group - imports lsg,csv + * RPC routine to set question properties * * @access public * @param string $sSessionKey - * @param int $iSurveyID the id of the survey that the group will belong - * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv - * @param string $sImportDataType lsg,csv - * @param string $sNewGroupName Optional new name for the group - * @param string $sNewGroupDescription Optional new description for the group - * @return integer iGroupID - ID of the new group + * @param integer $iQuestionID - ID of the question + * @param array|struct $aQuestionData - An array with the particular fieldnames as keys and their values to set on that particular question + * @return array of succeeded and failed modifications according to internal validation. */ - public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDataType, $sNewGroupName=NULL, $sNewGroupDescription=NULL) - { - + public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionData) + { if ($this->_checkSessionKey($sSessionKey)) - { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - if($surveyidExists->getAttribute('active') =='Y') - return array('status' => 'Error:Survey is aCctive and not editable'); + { + $oQuestion=Questions::model()->findByAttributes(array('qid' => $iQuestionID)); + if (is_null($oQuestion)) + return array('status' => 'Error: Invalid group ID'); - if (hasSurveyPermission($iSurveyID, 'survey', 'update')) + if (hasSurveyPermission($oQuestion->sid, 'survey', 'update')) { - if (!in_array($sImportDataType,array('csv','lsg'))) return array('status' => 'Invalid extension'); - libxml_use_internal_errors(true); - Yii::app()->loadHelper('admin/import'); - // First save the data to a temporary file - $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; - file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); + $succeded = array(); + $failed = array(); + // Remove fields that may not be modified + unset($aQuestionData['qid']); + unset($aQuestionData['gid']); + unset($aQuestionData['sid']); + unset($aQuestionData['parent_qid']); + unset($aQuestionData['language']); + unset($aQuestionData['type']); + // Remove invalid fields + $aDestinationFields=array_flip(Questions::model()->tableSchema->columnNames); + $aQuestionData=array_intersect_key($aQuestionData,$aDestinationFields); + + if (empty($aQuestionData)) + return array('status' => 'No valid Data'); - if (strtolower($sImportDataType)=='csv') - { - $aImportResults = CSVImportGroup($sFullFilePath, $iSurveyID); - } - elseif ( strtolower($sImportDataType)=='lsg') - { + foreach($aQuestionData as $sFieldName=>$sValue) + { + $valid_value = $this->_internal_validate($sFieldName,$sValue); - $xml = simplexml_load_file($sFullFilePath); - if(!$xml) + if ($valid_value === false) + $failed[$sFieldName]=$sValue; + else { - unlink($sFullFilePath); - return array('status' => 'Error: Invalid LimeSurvey group structure XML '); + //all the dependencies that this question has to other questions + $dependencies=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,$iQuestionID); + //all dependencies by other questions to this question + $is_criteria_question=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,"all",$iQuestionID,"by-targqid"); + //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies + + if((isset($dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') + $failed[$sFieldName]='Questions with dependencies - Order cannot be changed'; + else + { + $oQuestion->setAttribute($sFieldName,$valid_value); + $succeded[$sFieldName]=$sValue; + } } - $aImportResults = XMLImportGroup($sFullFilePath, $iSurveyID); - } - else - return array('status' => 'Invalid extension'); //just for symmetry! - - unlink($sFullFilePath); - - if (isset($aImportResults['fatalerror'])) return array('status' => 'Error: '.$aImportResults['fatalerror']); - else + } + try { - $iNewgid = $aImportResults['newgid']; - - $group = Groups::model()->findByAttributes(array('gid' => $iNewgid)); - $slang=$group['language']; - if($sNewGroupName!='') - $group->setAttribute('group_name',$sNewGroupName); - if($sNewGroupDescription!='') - $group->setAttribute('description',$sNewGroupDescription); - try - { - $group->save(); - } - catch(Exception $e) - { - // no need to throw exception - } - return $aImportResults['newgid']; - } + $oQuestion->save(); // save the change to database + fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } } else return array('status' => 'No permission'); } else - return array('status' => 'Invalid session key'); + return array('status' => 'Invalid Session key'); } - /** - * RPC routine to delete a group of a survey - * Returns the id of the deleted group - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iGroupID - * @return int - */ - public function delete_group($sSessionKey, $iSurveyID, $iGroupID) - { - if ($this->_checkSessionKey($sSessionKey)) - { - $iSurveyID = sanitize_int($iSurveyID); - $iGroupID = sanitize_int($iGroupID); - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - $groupidExists = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($groupidExists)) - return array('status' => 'Error: Invalid group ID'); - - if($surveyidExists['active']=='Y') - return array('status' => 'Error:Survey is active and not editable'); - - if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) - { - LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); - $iGroupsDeleted = Groups::deleteWithDependency($iGroupID, $iSurveyID); - - if ($iGroupsDeleted === 1) - fixSortOrderGroups($iSurveyID); - - LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); - - if ($iGroupsDeleted === 1) - return $iGroupID; - else - return array('status' => 'Group deletion failed'); - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session Key'); - } - /** - * RPC routine to return the ids and info of groups belonging to survey + * RPC routine to return the ids and info of questions of a survey/group * Returns array of ids and info * * @access public * @param string $sSessionKey * @param int $iSurveyID + * @param int $iGroupID * @return array */ - public function get_group_list($sSessionKey, $iSurveyID) + public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) { if ($this->_checkSessionKey($sSessionKey)) { $surveyidExists = Survey::model()->findByPk($iSurveyID); if (!isset($surveyidExists)) return array('status' => 'Error: Invalid survey ID'); - + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { - $group_list = Groups::model()->findAllByAttributes(array("sid"=>$iSurveyID)); - if(count($group_list)==0) - return array('status' => 'No groups found'); + if($iGroupID!=NULL) + { + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + $gsid = $oGroup['sid']; + + if($gsid != $iSurveyID) + return array('status' => 'Error: IMissmatch in surveyid and groupid'); + else + $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID, "gid"=>$iGroupID,"parent_qid"=>"0")); + } + else + $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID,"parent_qid"=>"0")); + + if(count($aQuestionList)==0) + return array('status' => 'No questions found'); - foreach ($group_list as $group) + foreach ($aQuestionList as $question) { - $aData[]= array('id'=>$group->primaryKey,'group_name'=>$group->attributes['group_name']); + $aData[]= array('id'=>$question->primaryKey,'type'=>$question->attributes['type'], 'question'=>$question->attributes['question']); } return $aData; } else - return array('status' => 'No permission'); + return array('status' => 'No permission'); } else - return array('status' => 'Invalid Session Key'); + return array('status' => 'Invalid session key'); } - - /** - * RPC routine to return settings of a group of a survey - * Returns array of properties - * - * @access public - * @param string $sSessionKey - * @param int $iGroupID - * @param array $aGroupSettings - * @return array - */ - public function get_group_settings($sSessionKey, $iGroupID, $aGroupSettings) - { - if ($this->_checkSessionKey($sSessionKey)) - { - $current_group = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($current_group)) - return array('status' => 'Error: Invalid group ID'); - - $aBasicDestinationFields=Groups::model()->tableSchema->columnNames; - $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); - - if (hasSurveyPermission($current_group->sid, 'survey', 'read')) - { - $abasic_attrs = $current_group ->getAttributes(); - - if (empty($aGroupSettings)) - return array('status' => 'No valid Data'); - - foreach($aGroupSettings as $sGroupSetting) - { - if (isset($abasic_attrs[$sGroupSetting])) - $result[$sGroupSetting]=$abasic_attrs[$sGroupSetting]; - else - $result[$sGroupSetting]='Data not available'; - } - return $result; - } - else - return array('status' => 'No permission'); - } - else - return array('status' => 'Invalid Session Key'); - } + /* Participant-Token specific functions */ + /** - * RPC routine to modify group settings + * RPC routine to add a participant to a token table + * Returns the inserted data including additional new information like the Token entry ID and the token * * @access public * @param string $sSessionKey - * @param integer $iGroupID - ID of the survey - * @param array|struct $aGroupData - An array with the particular fieldnames as keys and their values to set on that particular survey - * @return array of succeeded and failed modifications according to internal validation. + * @param int $iSurveyID + * @param struct $aParticipantData + * @param bool Optional - Defaults to true and determins if the access token automatically created + * @return array */ - public function modify_group_settings($sSessionKey, $iGroupID, $aGroupData) - { - if ($this->_checkSessionKey($sSessionKey)) - { - $oGroup=Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (is_null($oGroup)) - { - return array('status' => 'Error: Invalid group ID'); - } - if (hasSurveyPermission($oGroup->sid, 'survey', 'update')) + public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $bCreateToken=true) + { + if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); + $oSurvey=Survey::model()->findByPk($iSurveyID); + if (is_null($oSurvey)) + { + return array('status' => 'Error: Invalid survey ID'); + } + + if (hasSurveyPermission($iSurveyID, 'tokens', 'create')) + { + if (!Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}')) + return array('status' => 'No token table'); + + $aDestinationFields = Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}')->getColumnNames(); + $aDestinationFields = array_flip($aDestinationFields); + + foreach ($aParticipantData as &$aParticipant) { - $succeded = array(); - $failed = array(); - // Remove fields that may not be modified - unset($aGroupData['sid']); - unset($aGroupData['gid']); - // Remove invalid fields - $aDestinationFields=array_flip(Groups::model()->tableSchema->columnNames); - $aGroupData=array_intersect_key($aGroupData,$aDestinationFields); - - if (empty($aGroupData)) - return array('status' => 'No valid Data'); - - foreach($aGroupData as $sFieldName=>$sValue) - { - $valid_value = $this->_internal_validate($sFieldName,$sValue); - - if ($valid_value === false) - $failed[$sFieldName]=$sValue; - else - { - //all dependencies this group has - $has_dependencies=getGroupDepsForConditions($oGroup->sid,$iGroupID); - //all dependencies on this group - $depented_on = getGroupDepsForConditions($oGroup->sid,"all",$iGroupID,"by-targgid"); - //We do not allow groups with dependencies to change order - that would lead to broken dependencies - - if((isset($has_dependencies) || isset($depented_on)) && $sFieldName == 'group_order') - $failed[$sFieldName]='Group with dependencies - Order cannot be changed'; - else - { - $oGroup->setAttribute($sFieldName,$valid_value); - $succeded[$sFieldName]=$sValue; - } - } - } - try - { - $oGroup->save(); // save the change to database - fixSortOrderGroups($oGroup->sid); - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; - } - catch(Exception $e) + $aParticipant=array_intersect_key($aParticipant,$aDestinationFields); + Tokens_dynamic::sid($iSurveyID); + $token = new Tokens_dynamic; + + if ($token->insert()) { - return array('status' => 'Error'); + foreach ($aParticipant as $k => $v) + $token->$k = $v; + $inresult = $token->save(); + $new_token_id = $token->primaryKey; + + if ($bCreateToken) + $token_string = Tokens_dynamic::model()->createToken($new_token_id); + else + $token_string = ''; + + $aParticipant = array_merge($aParticipant, array( + 'tid' => $new_token_id, + 'token' => $token_string, + )); } } - else - return array('status' => 'No permission'); + + return $aParticipantData; } else - return array('status' => 'Invalid Session key'); + return array('status' => 'No permission'); } - - /** - * RPC routine to import a question - imports lsq,csv - * - * @access public - * @param string $sSessionKey - * @param int $iSurveyID the id of the survey that the question will belong - * @param int $iGroupID the id of the group that the question will belong - * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv - * @param string $sImportDataType lsq,csv - * @param string $sMandatory - * @param string $sNewQuestionTitle Optional new title for the question - * @param string $sNewqQuestion An optional new question - * @param string $sNewQuestionHelp An optional new question help text - * @return integer iQuestionID - ID of the new question - */ - public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData, $sImportDataType, $sMandatory='N', $sNewQuestionTitle=NULL, $sNewqQuestion=NULL, $sNewQuestionHelp=NULL) - { + /** + * RPC routine to delete multiple participant token records + * Returns the id of the deleted token + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param array $aTokenIDs + * @return array + */ + public function delete_participants($sSessionKey, $iSurveyID, $aTokenIDs) + { if ($this->_checkSessionKey($sSessionKey)) - { - $oSurvey = Survey::model()->findByPk($iSurveyID); - if (!isset($oSurvey)) + { + $iSurveyID = sanitize_int($iSurveyID); + + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) return array('status' => 'Error: Invalid survey ID'); - - if($oSurvey->getAttribute('active') =='Y') - return array('status' => 'Error:Survey is Active and not editable'); - - $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($oGroup)) - return array('status' => 'Error: Invalid group ID'); - $gsid = $oGroup['sid']; - if($gsid != $iSurveyID) - return array('status' => 'Error: IMissmatch in surveyid and groupid'); + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); - if (hasSurveyPermission($iSurveyID, 'survey', 'update')) - { - if (!in_array($sImportDataType,array('csv','lsq'))) return array('status' => 'Invalid extension'); - libxml_use_internal_errors(true); - Yii::app()->loadHelper('admin/import'); - // First save the data to a temporary file - $sFullFilePath = Yii::app()->getConfig('tempdir') . DIRECTORY_SEPARATOR . randomChars(40).'.'.$sImportDataType; - file_put_contents($sFullFilePath,base64_decode(chunk_split($sImportData))); - - if (strtolower($sImportDataType)=='csv') - { - $aImportResults = CSVImportQuestion($sFullFilePath, $iSurveyID, $iGroupID); - } - elseif ( strtolower($sImportDataType)=='lsq') + if (hasSurveyPermission($iSurveyID, 'tokens', 'delete')) + { + $result=array(); + foreach($aTokenIDs as $iTokenID) { - - $xml = simplexml_load_file($sFullFilePath); - if(!$xml) + $tokenidExists = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($tokenidExists)) + $result[$iTokenID]='Invalid token ID'; + else { - unlink($sFullFilePath); - return array('status' => 'Error: Invalid LimeSurvey question structure XML '); + Survey_links::deleteTokenLink(array($iTokenID), $iSurveyID); + if(Tokens_dynamic::model($iSurveyID)->deleteRecords(array($iTokenID))) + $result[$iTokenID]='Deleted'; + else + $result[$iTokenID]='Deletion went wrong'; } - $aImportResults = XMLImportQuestion($sFullFilePath, $iSurveyID, $iGroupID); } - else - return array('status' => 'Really Invalid extension'); //just for symmetry! - - unlink($sFullFilePath); - - if (isset($aImportResults['fatalerror'])) return array('status' => 'Error: '.$aImportResults['fatalerror']); - else - { - fixLanguageConsistency($iSurveyID); - $iNewqid = $aImportResults['newqid']; - - $oQuestion = Questions::model()->findByAttributes(array('sid' => $iSurveyID, 'gid' => $iGroupID, 'qid' => $iNewqid)); - if($sNewQuestionTitle!=NULL) - $oQuestion->setAttribute('title',$sNewQuestionTitle); - if($sNewqQuestion!='') - $oQuestion->setAttribute('question',$sNewqQuestion); - if($sNewQuestionHelp!='') - $oQuestion->setAttribute('help',$sNewQuestionHelp); - if(in_array($sMandatory, array('Y','N'))) - $oQuestion->setAttribute('mandatory',$sMandatory); - else - $oQuestion->setAttribute('mandatory','N'); - - try - { - $oQuestion->save(); - } - catch(Exception $e) - { - // no need to throw exception - } - return $aImportResults['newqid']; - } + return $result; } else return array('status' => 'No permission'); } else - return array('status' => 'Invalid session key'); - } + return array('status' => 'Invalid Session Key'); + } /** - * RPC routine to delete a question of a survey - * Returns the id of the deleted question + * RPC routine to return settings of a token/participant of a survey + * Returns string * * @access public * @param string $sSessionKey - * @param int iQuestionID - * @return string + * @param int $iSurveyID + * @param int $iTokenID + * @param array $aTokenProperties + * @return array */ - public function delete_question($sSessionKey, $iQuestionID) + public function get_participant_properties($sSessionKey, $iSurveyID, $iTokenID, $aTokenProperties) { - if ($this->_checkSessionKey($sSessionKey)) - { - - $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); - if (!isset($oQuestion)) - return array('status' => 'Error: Invalid question ID'); - - $iSurveyID = $oQuestion['sid']; - $oSurvey = Survey::model()->findByPk($iSurveyID); - - if($oSurvey['active']=='Y') - return array('status' => 'Survey is active and not editable'); - $iGroupID=$oQuestion['gid']; + if ($this->_checkSessionKey($sSessionKey)) + { + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); - if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) - { - $oCondition = Conditions::model()->findAllByAttributes(array('cqid' => $iQuestionID)); - if(count($oCondition)>0) - return array('status' => 'Cannot delete Question. Others rely on this question'); - - LimeExpressionManager::RevertUpgradeConditionsToRelevance(NULL,$iQuestionID); - - try - { - Conditions::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); - Question_attributes::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); - Answers::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); - - $criteria = new CDbCriteria; - $criteria->addCondition('qid = :qid or parent_qid = :qid'); - $criteria->params[':qid'] = $iQuestionID; - Questions::model()->deleteAll($criteria); - - Defaultvalues::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); - Quota_members::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); - Questions::updateSortOrder($iGroupID, $iSurveyID); - - return $iQuestionID; + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($oToken)) + return array('status' => 'Error: Invalid tokenid'); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + { + $result=array(); + $aBasicDestinationFields=Tokens_dynamic::model()->tableSchema->columnNames; + $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); + $abasic_attrs = $oToken->getAttributes(); + + if (empty($aTokenProperties)) + return array('status' => 'No valid Data'); + + foreach($aTokenProperties as $sproperty_name ) + { + if (isset($abasic_attrs[$sproperty_name])) + $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + else + $result[$sproperty_name]='Data not available'; } - catch(Exception $e) - { - return array('status' => 'Error'); - } - - } - else - return array('status' => 'No permission'); - } + return $result; + } + else + return array('status' => 'No permission'); + } else - return array('status' => 'Invalid session key'); + return array('status' => 'Invalid Session Key'); } - - - /** - * RPC routine to return the ids and info of questions of a survey/group - * Returns array of ids and info + /** + * RPC routine to set properties of a survey participant/token + * Returns array * * @access public * @param string $sSessionKey * @param int $iSurveyID - * @param int $iGroupID + * @param int $iTokenID + * @param array|struct $aTokenData * @return array */ - public function get_question_list($sSessionKey, $iSurveyID, $iGroupID=NULL) + public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, $aTokenData) { if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); + + $surveyidExists = Survey::model()->findByPk($iSurveyID); if (!isset($surveyidExists)) return array('status' => 'Error: Invalid survey ID'); - - if (hasSurveyPermission($iSurveyID, 'survey', 'read')) - { - if($iGroupID!=NULL) - { - $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - $gsid = $oGroup['sid']; - - if($gsid != $iSurveyID) - return array('status' => 'Error: IMissmatch in surveyid and groupid'); + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($oToken)) + return array('status' => 'Error: Invalid tokenid'); + + $succeded = array(); + $failed = array(); + // Remove fields that may not be modified + unset($aTokenData['tid']); + + $aBasicDestinationFields=array_flip(Tokens_dynamic::model()->tableSchema->columnNames); + $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) + { + if (empty($aTokenData)) + return array('status' => 'No valid Data'); + + foreach($aTokenData as $sFieldName=>$sValue) + { + if($this->_internal_validate($sFieldName,$sValue)) + { + $oToken->$sFieldName=$sValue; + $succeded[$sFieldName]=$sValue; + } else - $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID, "gid"=>$iGroupID,"parent_qid"=>"0")); - } - else - $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID,"parent_qid"=>"0")); - - if(count($aQuestionList)==0) - return array('status' => 'No questions found'); - - foreach ($aQuestionList as $question) - { - $aData[]= array('id'=>$question->primaryKey,'type'=>$question->attributes['type'], 'question'=>$question->attributes['question']); - } - return $aData; + $failed[$sFieldName]=$sValue; + } + try + { + $oToken->save(); + $result = array('succeded'=>$succeded,'failed'=>$failed); + return $result; + } + catch(Exception $e) + { + return array('status' => 'Error'); + } } else - return array('status' => 'No permission'); - } + return array('status' => 'No permission'); + } else - return array('status' => 'Invalid session key'); + return array('status' => 'Invalid Session Key'); } - /** - * RPC routine to return properties of a question of a survey - * Returns string + + /** + * RPC routine to return the ids and info of token/participants of a survey + * Returns array of ids and info + * if $bUnused is true, user will get the list of not completed tokens (old token_return functionality) * * @access public * @param string $sSessionKey - * @param int $iQuestionID - * @param array $aQuestionSettings + * @param int $iSurveyID + * @param bool $bUnused * @return array */ - public function get_question_settings($sSessionKey, $iQuestionID, $aQuestionSettings) + public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) { - if ($this->_checkSessionKey($sSessionKey)) { - $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); - if (!isset($oQuestion)) - return array('status' => 'Error: Invalid questionid', 22); + $surveyidExists = Survey::model()->findByPk($iSurveyID); + if (!isset($surveyidExists)) + return array('status' => 'Error: Invalid survey ID'); + + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) + { + if($bUnused) + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); + else + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(); + + if(count($oTokens)==0) + return array('status' => 'No Tokens found'); - $aBasicDestinationFields=Questions::model()->tableSchema->columnNames; - array_push($aBasicDestinationFields,'available_answers') ; - $aQuestionSettings=array_intersect($aQuestionSettings,$aBasicDestinationFields); - - if (empty($aQuestionSettings)) - return array('status' => 'No valid Data'); - - if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) - { - $abasic_attrs = $oQuestion->getAttributes(); - $result=array(); - foreach ($aQuestionSettings as $sproperty_name ) - { - if ($sproperty_name == 'available_answers') + foreach ($oTokens as $token) { - $subgroups = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID),array('order'=>'title') ); - if (count($subgroups)>0) - { - foreach($subgroups as $subgroup) - $aData[$subgroup['title']]= $subgroup['question']; - - $result['available_answers']=$aData; - } - else - $result['available_answers']='No available answers'; - } - else - { - if (isset($abasic_attrs[$sproperty_name])) - $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; - else - $result[$sproperty_name]='Data not available'; - + $aData[] = array( + 'tid'=>$token->primarykey, + 'token'=>$token->attributes['token'], + 'participant_info'=>array( + 'firstname'=>$token->attributes['firstname'], + 'lastname'=>$token->attributes['lastname'], + 'email'=>$token->attributes['email'], + )); } - } - return $result; + return $aData; } else - return array('status' => 'No permission'); + return array('status' => 'No permission'); } else - return array('status' => 'Invalid session key'); + return array('status' => 'Invalid Session Key'); } /** - * RPC routine to modify group settings + * RPC routine to activate tokens * * @access public * @param string $sSessionKey - * @param integer $iQuestionID - ID of the question - * @param array|struct $aQuestionData - An array with the particular fieldnames as keys and their values to set on that particular question - * @return array of succeeded and failed modifications according to internal validation. + * @param integer $iSurveyID ID of the survey where a token table will be created for + * @param array $aAttributeFields An array of integer describing any additional attribute fields + * @return array Status=>OK when successfull, otherwise the error description */ - public function modify_question_settings($sSessionKey, $iQuestionID, $aQuestionData) - { - if ($this->_checkSessionKey($sSessionKey)) - { - $oQuestion=Questions::model()->findByAttributes(array('qid' => $iQuestionID)); - if (is_null($oQuestion)) - return array('status' => 'Error: Invalid group ID'); - - if (hasSurveyPermission($oQuestion->sid, 'survey', 'update')) + public function activate_participant_tokens($sSessionKey, $iSurveyID, $aAttributeFields=array()) + { + if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); + if (hasGlobalPermission('USER_RIGHT_CREATE_SURVEY')) + { + $oSurvey=Survey::model()->findByPk($iSurveyID); + if (is_null($oSurvey)) { - $succeded = array(); - $failed = array(); - // Remove fields that may not be modified - unset($aQuestionData['qid']); - unset($aQuestionData['gid']); - unset($aQuestionData['sid']); - unset($aQuestionData['parent_qid']); - unset($aQuestionData['language']); - unset($aQuestionData['type']); - // Remove invalid fields - $aDestinationFields=array_flip(Questions::model()->tableSchema->columnNames); - $aQuestionData=array_intersect_key($aQuestionData,$aDestinationFields); - - if (empty($aQuestionData)) - return array('status' => 'No valid Data'); - - foreach($aQuestionData as $sFieldName=>$sValue) - { - $valid_value = $this->_internal_validate($sFieldName,$sValue); - - if ($valid_value === false) - $failed[$sFieldName]=$sValue; - else - { - //all the dependencies that this question has to other questions - $dependencies=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,$iQuestionID); - //all dependencies by other questions to this question - $is_criteria_question=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,"all",$iQuestionID,"by-targqid"); - //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies - - if((isset($dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') - $failed[$sFieldName]='Questions with dependencies - Order cannot be changed'; - else - { - $oQuestion->setAttribute($sFieldName,$valid_value); - $succeded[$sFieldName]=$sValue; - } - } - } - try - { - $oQuestion->save(); // save the change to database - fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; - } - catch(Exception $e) + return array('status' => 'Error: Invalid survey ID'); + } + if (is_array($aAttributeFields) && count($aAttributeFields)>0) + { + foreach ($aAttributeFields as &$sField) { - return array('status' => 'Error'); + $sField= intval($sField); + $sField='attribute_'.$sField; } + $aAttributeFields=array_unique($aAttributeFields); + } + Yii::app()->loadHelper('admin/token'); + if (createTokenTable($iSurveyID, $aAttributeFields)) + { + return array('status' => 'OK'); } else - return array('status' => 'No permission'); + { + return array('status' => 'Token table could not be created'); + } } else - return array('status' => 'Invalid Session key'); + return array('status' => 'No permission'); } + /* Response specific functions */ + + + /** + * RPC routine to add a response to the survey response table + * Returns the id of the inserted survey response + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param struct $aResponseData + * @return int The response ID + */ + public function add_response($sSessionKey, $iSurveyID, $aResponseData) + { + if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); + $oSurvey=Survey::model()->findByPk($iSurveyID); + if (is_null($oSurvey)) + { + return array('status' => 'Error: Invalid survey ID'); + } + + if (hasSurveyPermission($iSurveyID, 'responses', 'create')) + { + if (!Yii::app()->db->schema->getTable('{{survey_' . $iSurveyID . '}}')) + return array('status' => 'No survey response table'); + + //set required values if not set + + // @todo: Some of this is part of the validation and should be done in the model instead + if (!isset($aResponseData['submitdate'])) + $aResponseData['submitdate'] = date("Y-m-d H:i:s"); + if (!isset($aResponseData['startlanguage'])) + $aResponseData['startlanguage'] = getBaseLanguageFromSurveyID($iSurveyID); + + if ($oSurvey->datestamp=='Y') + { + if (!isset($aResponseData['datestamp'])) + $aResponseData['datestamp'] = date("Y-m-d H:i:s"); + if (!isset($aResponseData['startdate'])) + $aResponseData['startdate'] = date("Y-m-d H:i:s"); + } + + Survey_dynamic::sid($iSurveyID); + $survey_dynamic = new Survey_dynamic; + $result = $survey_dynamic->insert($aResponseData); + + if ($result) + return $survey_dynamic->primaryKey; + else + return array('status' => 'Unable to add response'); + } + else + return array('status' => 'No permission'); + + } + + /** + * RPC routine to export responses + * Returns the requested file as base64 encoded string + * + * @access public + * @param string $sSessionKey + * @param int $iSurveyID + * @param string $sDocumentType pdf,csv,xls,doc + * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to complete + * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' + * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' + * @param integer $iFromResponseID Optional + * @param integer $iToResponseID Optional + * @return On success: Requested file as base 64-encoded string. On failure array with error information + **/ + public function export_responses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode=null, $sCompletionStatus='all', $sHeadingType='code', $sResponseType='short', $iFromResponseID=null, $iToResponseID=null, $aFields=null) + { + if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); + Yii::app()->loadHelper('admin/exportresults'); + if (!hasSurveyPermission($iSurveyID, 'responses', 'export')) return array('status' => 'No permission'); + if (is_null($sLanguageCode)) $sLanguageCode=getBaseLanguageFromSurveyID($iSurveyID); + if (is_null($aFields)) $aFields=array_keys(createFieldMap($iSurveyID,'full',true,false,$sLanguageCode)); + if($sDocumentType=='xls'){ + // Cut down to the first 255 fields + $aFields=array_slice($aFields,0,255); + } + $oFomattingOptions=new FormattingOptions(); + $oFomattingOptions->format=$sDocumentType; + $oFomattingOptions->responseMinRecord=$iFromResponseID; + $oFomattingOptions->responseMaxRecord=$iToResponseID; + $oFomattingOptions->selectedColumns=$aFields; + $oFomattingOptions->responseCompletionState=$sCompletionStatus; + $oFomattingOptions->headingFormat=$sHeadingType; + $oFomattingOptions->answerFormat=$sResponseType; + $oExport=new ExportSurveyResultsService(); + $sFileData=$oExport->exportSurvey($iSurveyID,$sLanguageCode,$oFomattingOptions,'return'); + return base64_encode($sFileData); + } + /** * Tries to login with username and password From f9a3b5ad9ec7d19eb630016fe900122c4ee775e8 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Fri, 27 Jul 2012 14:14:56 +0300 Subject: [PATCH 12/75] Documentation and Beautification --- .../controllers/admin/remotecontrol.php | 355 +++++++++--------- 1 file changed, 175 insertions(+), 180 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index bf3087ee7ed..82a7febf946 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -149,7 +149,7 @@ public function __construct(AdminController $controller) /** - * RPC routine to create a session key + * RPC routine to create a session key. * * @access public * @param string $username @@ -192,12 +192,12 @@ public function release_session_key($sSessionKey) } /** - * RPC routine to get settings + * RPC Routine to get settings. * * @access public - * @param string $sSessionKey - * @param string $sSetttingName - * @return string + * @param string $sSessionKey Auth Credentials + * @param string $sSetttingName Name of the setting to get + * @return string The requested value */ public function get_site_settings($sSessionKey,$sSetttingName) { @@ -223,15 +223,15 @@ public function get_site_settings($sSessionKey,$sSetttingName) /* Survey specific functions */ /** - * RPC routine to add an empty survey with minimum details - * Used as a placeholder for importing groups and/or questions + * RPC Routine to add an empty survey with minimum details. + * Used as a placeholder for importing groups and/or questions. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param string $sSurveyTitle - * @param string $sSurveyLanguage - * @param string $sformat + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID The wish id of the Survey to add + * @param string $sSurveyTitle Title of the new Survey + * @param string $sSurveyLanguage Default language of the Survey + * @param string $sformat Question appearance format * @return string */ public function add_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLanguage, $sformat = 'G') @@ -311,12 +311,12 @@ public function add_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLang } /** - * RPC routine to delete a survey + * RPC Routine to delete a survey. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID The id of the Survey to be deleted + * @return array Returns Status */ public function delete_survey($sSessionKey, $iSurveyID) { @@ -335,12 +335,13 @@ public function delete_survey($sSessionKey, $iSurveyID) } /** - * RPC routine to import a survey - imports lss,csv,xls or survey zip archive + * RPC Routine to import a survey - imports lss,csv,xls or survey zip archive. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth Credentials * @param string $sImportData String containing the BASE 64 encoded data of a lss,csv,xls or survey zip archive * @param string $sImportDataType lss,csv,xls or zip + * @param string $sNewSurveyName The optional new name of the survey * @param integer $DestSurveyID This is the new ID of the survey - if already used a random one will be taken instead * @return integer iSurveyID - ID of the new survey */ @@ -371,13 +372,12 @@ public function import_survey($sSessionKey, $sImportData, $sImportDataType, $sNe } /** - * RPC routine to get survey properties - * Properties are those defined in table surveys + * RPC Routine to get survey properties. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param array $aSurveySettings + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID The id of the Survey to be checked + * @param array $aSurveySettings The properties to get * @return array */ public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) @@ -419,14 +419,13 @@ public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) } /** - * RPC routine to set survey properties - * Properties are those defined in table surveys + * RPC Routine to set survey properties. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iSurveyID - ID of the survey * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey - * @return array of succeeded and failed nodifications according to internal validation. + * @return array Of succeeded and failed nodifications according to internal validation. */ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) { @@ -492,15 +491,15 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) } /** - * RPC routine to list the ids and info of surveys belonging to a user - * Returns array of ids and info - * If user is admin he can get surveys of every user - * else only the syrveys belonging to the user requesting will be shown - * + * RPC Routine to list the ids and info of surveys belonging to a user. + * Returns array of ids and info. + * If user is admin he can get surveys of every user (parameter sUser) + * else only the syrveys belonging to the user requesting will be shown. + * * @access public - * @param string $sSessionKey - * @param string $suser - * @return array + * @param string $sSessionKey Auth credentials + * @param string $suser Optional username to get list of surveys + * @return array The list of surveys */ public function list_surveys($sSessionKey, $suser='') { @@ -535,13 +534,12 @@ public function list_surveys($sSessionKey, $suser='') /** - * RPC routine to activate a survey + * RPC Routine that launches a newly created survey. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param int $iSurveyID The id of the survey to be activated - - * @return array the result of the activation + * @return array The result of the activation */ public function activate_survey($sSessionKey, $iSurveyID) { @@ -570,17 +568,17 @@ public function activate_survey($sSessionKey, $iSurveyID) } /** - * RPC routine to export statistics of a survey to a user - * Returns string - base64 encoding of the statistics + * RPC routine to export statistics of a survey to a user. + * Returns string - base64 encoding of the statistics. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param string $docType - * @param string $graph - * @return string + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey + * @param string $docType Type of documents the exported statistics should be + * @param string $graph Create graph option + * @return string Base64 encoded string with the statistics file */ - public function export_survey_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') + public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') { Yii::app()->loadHelper('admin/statistics'); @@ -641,15 +639,16 @@ public function export_survey_statistics($sSessionKey, $iSurveyID, $docType='pdf } /** - * RPC routine to get survey summary, regarding token usage and survey participation - * Return integer with the requested value + * RPC routine to get survey summary, regarding token usage and survey participation. + * Returns the requested value as string. + * * @access public - * @param string $sSessionKey - * @param int $sid - * @param string $stats_name - * @return string + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey to get summary + * @param string $stat_name Name of the sumamry option + * @return string The requested value */ - public function get_survey_summary($sSessionKey,$iSurveyID, $stat_name) + public function get_summary($sSessionKey,$iSurveyID, $stat_name) { $permitted_stats = array(); if ($this->_checkSessionKey($sSessionKey)) @@ -730,15 +729,15 @@ public function get_survey_summary($sSessionKey,$iSurveyID, $stat_name) /*Survey language specific functions */ /** - * RPC routine to add a survey language + * RPC Routine to add a survey language. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iSurveyID ID of the survey where a token table will be created for * @param string $sLanguage A valid language shortcut to add to the current survey. If the language already exists no error will be given. * @return array Status=>OK when successfull, otherwise the error description */ - public function add_survey_language($sSessionKey, $iSurveyID, $sLanguage) + public function add_language($sSessionKey, $iSurveyID, $sLanguage) { if ($this->_checkSessionKey($sSessionKey)) { @@ -795,15 +794,15 @@ public function add_survey_language($sSessionKey, $iSurveyID, $sLanguage) } /** - * RPC routine to delete a survey language + * RPC Routine to delete a survey language. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iSurveyID ID of the survey where a token table will be created for * @param string $sLanguage A valid language shortcut to delete from the current survey. If the language does not exist in that survey no error will be given. * @return array Status=>OK when successfull, otherwise the error description */ - public function delete_survey_language($sSessionKey, $iSurveyID, $sLanguage) + public function delete_language($sSessionKey, $iSurveyID, $sLanguage) { if ($this->_checkSessionKey($sSessionKey)) { @@ -851,17 +850,16 @@ public function delete_survey_language($sSessionKey, $iSurveyID, $sLanguage) /** - * RPC routine to get survey language properties - * Properties are those defined in table surveys_language_settings + * RPC Routine to get survey language properties. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param array $aSurveyLocaleSettings - * @param string $slang - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Dd of the Survey + * @param array $aSurveyLocaleSettings Properties to get + * @param string $slang Language to use + * @return array The requested values */ - public function get_survey_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $slang=NULL) + public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $slang=NULL) { Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) @@ -906,17 +904,16 @@ public function get_survey_language_properties($sSessionKey,$iSurveyID, $aSurvey } /** - * RPC routine to set survey language properties - * Properties are those defined in table surveys_languagesettings + * RPC Routine to set survey language properties. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iSurveyID - ID of the survey - * @param array|struct $aSurveyData - An array with the particular fieldnames as keys and their values to set on that particular survey - * @param string $aLanguage - Optional - Language to update - if not give the base language of the particular survey is used - * @return array status=>OK, when save successful otherwise error text. + * @param array|struct $aSurveyLocaleData - An array with the particular fieldnames as keys and their values to set on that particular survey + * @param string $sLanguage - Optional - Language to update - if not give the base language of the particular survey is used + * @return array Status=>OK, when save successful otherwise error text. */ - public function set_survey_language_properties($sSessionKey, $iSurveyID, $aSurveyLocaleData, $sLanguage=NULL) + public function set_language_properties($sSessionKey, $iSurveyID, $aSurveyLocaleData, $sLanguage=NULL) { Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) @@ -983,16 +980,16 @@ public function set_survey_language_properties($sSessionKey, $iSurveyID, $aSurve /* Group specific functions */ /** - * RPC routine to add an empty group with minimum details - * Used as a placeholder for importing questions - * Returns the groupid of the created group + * RPC Routine to add an empty group with minimum details. + * Used as a placeholder for importing questions. + * Returns the groupid of the created group. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param string $sGroupTitle - * @param string $sGroupDescription - * @return string + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Dd of the Survey to add the group + * @param string $sGroupTitle Name of the group + * @param string $sGroupDescription Optional description of the group + * @return string The id of the new group */ public function add_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescription='') { @@ -1026,14 +1023,14 @@ public function add_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescrip } /** - * RPC routine to delete a group of a survey - * Returns the id of the deleted group + * RPC Routine to delete a group of a survey . + * Returns the id of the deleted group. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iGroupID - * @return int + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the survey that the group belongs + * @param int $iGroupID Id of the group to delete + * @return int The id of the deleted group */ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) { @@ -1075,11 +1072,11 @@ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) } /** - * RPC routine to import a group - imports lsg,csv + * RPC Routine to import a group - imports lsg,csv * * @access public - * @param string $sSessionKey - * @param int $iSurveyID the id of the survey that the group will belong + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID The id of the survey that the group will belong * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv * @param string $sImportDataType lsg,csv * @param string $sNewGroupName Optional new name for the group @@ -1157,14 +1154,14 @@ public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDat /** - * RPC routine to return properties of a group of a survey + * RPC Routine to return properties of a group of a survey . * Returns array of properties * * @access public - * @param string $sSessionKey - * @param int $iGroupID - * @param array $aGroupSettings - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iGroupID Id of the group to get properties + * @param array $aGroupSettings The properties to get + * @return array The requested values */ public function get_group_properties($sSessionKey, $iGroupID, $aGroupSettings) { @@ -1202,13 +1199,13 @@ public function get_group_properties($sSessionKey, $iGroupID, $aGroupSettings) /** - * RPC routine to set group properties + * RPC Routine to set group properties. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iGroupID - ID of the survey * @param array|struct $aGroupData - An array with the particular fieldnames as keys and their values to set on that particular survey - * @return array of succeeded and failed modifications according to internal validation. + * @return array Of succeeded and failed modifications according to internal validation. */ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) { @@ -1276,13 +1273,13 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) } /** - * RPC routine to return the ids and info of groups belonging to survey - * Returns array of ids and info + * RPC Routine to return the ids and info of groups belonging to survey . + * Returns array of ids and info. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey containing the groups + * @return array The list of groups */ public function list_groups($sSessionKey, $iSurveyID) { @@ -1316,13 +1313,13 @@ public function list_groups($sSessionKey, $iSurveyID) /** - * RPC routine to delete a question of a survey - * Returns the id of the deleted question + * RPC Routine to delete a question of a survey . + * Returns the id of the deleted question. * * @access public - * @param string $sSessionKey - * @param int iQuestionID - * @return string + * @param string $sSessionKey Auth credentials + * @param int iQuestionID Id of the question to delete + * @return string Id of the deleted Question */ public function delete_question($sSessionKey, $iQuestionID) { @@ -1380,15 +1377,15 @@ public function delete_question($sSessionKey, $iQuestionID) /** - * RPC routine to import a question - imports lsq,csv + * RPC Routine to import a question - imports lsq,csv. * * @access public * @param string $sSessionKey - * @param int $iSurveyID the id of the survey that the question will belong - * @param int $iGroupID the id of the group that the question will belong + * @param int $iSurveyID The id of the survey that the question will belong + * @param int $iGroupID The id of the group that the question will belong * @param string $sImportData String containing the BASE 64 encoded data of a lsg,csv * @param string $sImportDataType lsq,csv - * @param string $sMandatory + * @param string $sMandatory Optional Mandatory question option (default to No) * @param string $sNewQuestionTitle Optional new title for the question * @param string $sNewqQuestion An optional new question * @param string $sNewQuestionHelp An optional new question help text @@ -1480,14 +1477,14 @@ public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData /** - * RPC routine to return properties of a question of a survey + * RPC Routine to return properties of a question of a survey. * Returns string * * @access public - * @param string $sSessionKey - * @param int $iQuestionID - * @param array $aQuestionSettings - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iQuestionID Id of the question to get properties + * @param array $aQuestionSettings The properties to get + * @return array The requested values */ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSettings) { @@ -1543,13 +1540,13 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe } /** - * RPC routine to set question properties + * RPC Routine to set question properties. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iQuestionID - ID of the question * @param array|struct $aQuestionData - An array with the particular fieldnames as keys and their values to set on that particular question - * @return array of succeeded and failed modifications according to internal validation. + * @return array Of succeeded and failed modifications according to internal validation. */ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionData) { @@ -1621,14 +1618,14 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa /** - * RPC routine to return the ids and info of questions of a survey/group - * Returns array of ids and info + * RPC Routine to return the ids and info of questions of a survey/group. + * Returns array of ids and info. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iGroupID - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the survey to list questions + * @param int $iGroupID Optional id of the group to list questions + * @return array The list of questions */ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) { @@ -1674,15 +1671,15 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) /** - * RPC routine to add a participant to a token table - * Returns the inserted data including additional new information like the Token entry ID and the token + * RPC Routine to add a participant to the tokens placeholder of the survey. + * Returns the inserted data including additional new information like the Token entry ID and the token string. * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param struct $aParticipantData + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey + * @param struct $aParticipantData Data of the participants to be added * @param bool Optional - Defaults to true and determins if the access token automatically created - * @return array + * @return array The values added */ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $bCreateToken=true) { @@ -1733,14 +1730,14 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b } /** - * RPC routine to delete multiple participant token records + * RPC Routine to delete multiple participants of a Survey. * Returns the id of the deleted token * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param array $aTokenIDs - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey that the participants belong to + * @param array $aTokenIDs Id of the tokens/participants to delete + * @return array Result of deletion */ public function delete_participants($sSessionKey, $iSurveyID, $aTokenIDs) { @@ -1783,15 +1780,14 @@ public function delete_participants($sSessionKey, $iSurveyID, $aTokenIDs) /** - * RPC routine to return settings of a token/participant of a survey - * Returns string + * RPC Routine to return settings of a token/participant of a survey . * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iTokenID - * @param array $aTokenProperties - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey to get token properties + * @param int $iTokenID Id of the participant to check + * @param array $aTokenProperties The properties to get + * @return array The requested values */ public function get_participant_properties($sSessionKey, $iSurveyID, $iTokenID, $aTokenProperties) { @@ -1835,15 +1831,15 @@ public function get_participant_properties($sSessionKey, $iSurveyID, $iTokenID, } /** - * RPC routine to set properties of a survey participant/token + * RPC Routine to set properties of a survey participant/token. * Returns array * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param int $iTokenID - * @param array|struct $aTokenData - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the survey that participants belong + * @param int $iTokenID Id of the participant to alter + * @param array|struct $aTokenData Data to change + * @return array Result of the change action */ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, $aTokenData) { @@ -1905,15 +1901,14 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, /** - * RPC routine to return the ids and info of token/participants of a survey - * Returns array of ids and info - * if $bUnused is true, user will get the list of not completed tokens (old token_return functionality) + * RPC Routine to return the ids and info of token/participants of a survey. + * if $bUnused is true, user will get the list of not completed tokens (token_return functionality). * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param bool $bUnused - * @return array + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the survey to list participants + * @param bool $bUnused If you want unused tokensm, set true + * @return array The list of tokens */ public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) { @@ -1957,15 +1952,15 @@ public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) } /** - * RPC routine to activate tokens + * RPC routine to to initialise the survey's placeholder where new participant tokens may be later added. * * @access public - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @param integer $iSurveyID ID of the survey where a token table will be created for * @param array $aAttributeFields An array of integer describing any additional attribute fields * @return array Status=>OK when successfull, otherwise the error description */ - public function activate_participant_tokens($sSessionKey, $iSurveyID, $aAttributeFields=array()) + public function activate_tokens($sSessionKey, $iSurveyID, $aAttributeFields=array()) { if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); if (hasGlobalPermission('USER_RIGHT_CREATE_SURVEY')) @@ -2003,13 +1998,13 @@ public function activate_participant_tokens($sSessionKey, $iSurveyID, $aAttribut /** - * RPC routine to add a response to the survey response table + * RPC Routine to add a response to the survey responses collection. * Returns the id of the inserted survey response * * @access public - * @param string $sSessionKey - * @param int $iSurveyID - * @param struct $aResponseData + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey to insert responses + * @param struct $aResponseData The actual response * @return int The response ID */ public function add_response($sSessionKey, $iSurveyID, $aResponseData) @@ -2057,19 +2052,21 @@ public function add_response($sSessionKey, $iSurveyID, $aResponseData) } /** - * RPC routine to export responses + * RPC Routine to export responses. * Returns the requested file as base64 encoded string * * @access public - * @param string $sSessionKey - * @param int $iSurveyID + * @param string $sSessionKey Auth credentials + * @param int $iSurveyID Id of the Survey * @param string $sDocumentType pdf,csv,xls,doc + * @param string $sLanguageCode The language to be used * @param string $sCompletionStatus Optional 'complete','incomplete' or 'all' - defaults to complete * @param string $sHeadingType 'code','full' or 'abbreviated' Optional defaults to 'code' * @param string $sResponseType 'short' or 'long' Optional defaults to 'short' * @param integer $iFromResponseID Optional * @param integer $iToResponseID Optional - * @return On success: Requested file as base 64-encoded string. On failure array with error information + * @param array $aFields Optional Selected fields + * @return array On success: Requested file as base 64-encoded string. On failure array with error information **/ public function export_responses($sSessionKey, $iSurveyID, $sDocumentType, $sLanguageCode=null, $sCompletionStatus='all', $sHeadingType='code', $sResponseType='short', $iFromResponseID=null, $iToResponseID=null, $aFields=null) { @@ -2100,8 +2097,8 @@ public function export_responses($sSessionKey, $iSurveyID, $sDocumentType, $sLan * Tries to login with username and password * * @access protected - * @param string $sUsername - * @param mixed $sPassword + * @param string $sUsername The username + * @param mixed $sPassword The Password * @return bool */ protected function _doLogin($sUsername, $sPassword) @@ -2124,7 +2121,7 @@ protected function _doLogin($sUsername, $sPassword) * Fills the session with necessary user info on the fly * * @access protected - * @param string $sUsername + * @param string $username The username * @return bool */ protected function _jumpStartSession($username) @@ -2153,9 +2150,8 @@ protected function _jumpStartSession($username) * This function checks if the XML-RPC session key is valid. If yes returns true, otherwise false and sends an error message with error code 1 * * @access protected - * @param string $sSessionKey + * @param string $sSessionKey Auth credentials * @return bool - * @throws Zend_XmlRpc_Server_Exception */ protected function _checkSessionKey($sSessionKey) { @@ -2174,13 +2170,12 @@ protected function _checkSessionKey($sSessionKey) } /** - * This function validates parameters to be inserted in survey model + * This function validates parameters to be changed * * @access protected - * @param string $sparam_name - * @param string $sparam_value - * @return bool|string - * @throws Zend_XmlRpc_Server_Exception + * @param string $sparam_name Name of the parameter + * @param string $sparam_value Value to be validated + * @return bool|string Result valid value or false */ protected function _internal_validate($sparam_name, $sparam_value) { From 27ebd205910917ac68362f72d068015cd7deecc7 Mon Sep 17 00:00:00 2001 From: jcleeland Date: Sun, 29 Jul 2012 11:23:53 +1000 Subject: [PATCH 13/75] Fixed issue #6067 (partial fix) - jqGrid behaviours for editing attributes fixed - dropdown appears when dropdown should, dropdown doesn't appear when it shouldn't! --- scripts/admin/displayParticipant.js | 96 ++++++++++++++++------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/scripts/admin/displayParticipant.js b/scripts/admin/displayParticipant.js index ad2af270d2c..4fc38cb0ee8 100644 --- a/scripts/admin/displayParticipant.js +++ b/scripts/admin/displayParticipant.js @@ -209,6 +209,7 @@ $(document).ready(function() { } } }); + /* Subgrid that displays user attributes */ jQuery("#"+subgrid_table_id).jqGrid( { url: getAttribute_json+'/'+row_id, @@ -219,15 +220,18 @@ $(document).ready(function() { recordtext:'', pgtext:'', caption: attributesHeadingTxt, - editable:true, + editable: true, loadonce : true, colNames: [actionsColTxt,participantIdColTxt,attributeTypeColTxt,attributeNameColTxt,attributeValueColTxt,attributePosValColTxt], - colModel: [ { name:'act',index:'act',width:55,align:'center',sortable:false,formatter:'actions',formatoptions : { keys:true,onEdit:function(id){ }}}, + colModel: [ { name:'act',index:'act',width:55,align:'center',sortable:false,formatter:'actions',formatoptions : { keys:true,onEdit:function(id){ + var iRow = $('#' + $.jgrid.jqID(id))[0].rowIndex; + editModifier(id,iRow, method='edit'); + }}}, { name:'participant_id',index:'participant_id', width:150, sorttype:"string",align:"center",editable:true,hidden:true}, - { name:'atttype',index:'atttype', width:150, sorttype:"string",align:"center",editable:true,hidden:true}, + { name:'atttype',index:'atttype', width:150, sorttype:"string",align:"center",editable:false,hidden:true}, { name:'attname',index:'attname', width:150, sorttype:"string",align:"center",editable:false}, { name:'attvalue',index:'attvalue', width:150, sorttype:"string",align:"center",editable:true}, - { name:'attpvalues',index:'attpvalues', width:150, sorttype:"string",align:"center",editable:true,hidden:true}], + { name:'attpvalues',index:'attpvalues', width:150, sorttype:"string",align:"center",editable:false,hidden:true}], rowNum:20, pager: pager_id, gridComplete: function () { @@ -236,44 +240,7 @@ $(document).ready(function() { $("#gview_"+subgrid_table_id).css("margin-top", "20px"); //Some spacing after the subgrid }, ondblClickRow: function(id,subgrid_id) { - var parid = id.split('_'); - var participant_id = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'participant_id'); - var lsel = parid[0]; - var can_edit = $('#displayparticipants').getCell(participant_id,'can_edit'); - if(can_edit == 'false') { - var dialog_buttons={}; - dialog_buttons[okBtn]=function(){ - $( this ).dialog( closeTxt ); - }; - /* End of building array for button functions */ - $('#notauthorised').dialog({ - modal: true, - title: accessDeniedTxt, - buttons: dialog_buttons - }); - } else { - var att_type = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'atttype'); - if(att_type=="DP") { //Date - $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ editoptions:{ dataInit:function (elem) {$(elem).datepicker();}}}); - } - if(att_type=="DD") { //Dropdown - var att_p_values = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'attpvalues'); - $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ edittype:'select',editoptions:{ value:":Select One;"+att_p_values}}); - } - if(att_type=="TB") { //Textbox - $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ edittype:'text'}); - $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ editoptions:''}); - } - var attap = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'attap'); - if(id && id!==lastSel2) { //If there was already another row open for editin save it before editing this one - jQuery("#displayparticipants_"+parid[0]+"_t").saveRow(lastSel2); - //jQuery.fn.fmatter.rowactions('97358ea2-8227-483b-a225-5d13a522402e_50','displayparticipants_97358ea2-8227-483b-a225-5d13a522402e_t','cancel',0); - lastSel2=id; - } - $.fn.fmatter.rowactions(id,'displayparticipants_'+parid[0]+'_t','edit',0); - jQuery("#displayparticipants_"+parid[0]+"_t").jqGrid('editRow',id,true); - jQuery("#displayparticipants_"+parid[0]+"_t").editRow(id,true); - } + editModifier(id, subgrid_id, method='click'); }, height: '100%' }); @@ -702,4 +669,49 @@ $(document).ready(function() { } }); + function editModifier(id, subgrid_id, method) { + var parid = id.split('_'); + var participant_id = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'participant_id'); + var lsel = parid[0]; + var can_edit = $('#displayparticipants').getCell(participant_id,'can_edit'); + if(can_edit == 'false') { + var dialog_buttons={}; + dialog_buttons[okBtn]=function(){ + $( this ).dialog( closeTxt ); + }; + /* End of building array for button functions */ + $('#notauthorised').dialog({ + modal: true, + title: accessDeniedTxt, + buttons: dialog_buttons + }); + } else { + var att_type = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'atttype'); + if(att_type=="DP") { //Date + $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ editoptions:{ dataInit:function (elem) {$(elem).datepicker();}}}); + } + if(att_type=="DD") { //Dropdown + var att_p_values = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'attpvalues'); + $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ edittype:'select',editoptions:{ value:":Select One;"+att_p_values}}); + } + if(att_type=="TB") { //Textbox + $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ edittype:'text'}); + $("#displayparticipants_"+parid[0]+"_t").setColProp('attvalue',{ editoptions:''}); + } + var attap = $("#displayparticipants_"+parid[0]+"_t").getCell(id,'attap'); + if(id && id!==lastSel2) { //If there was already another row open for editin save it before editing this one + jQuery("#displayparticipants_"+parid[0]+"_t").saveRow(lastSel2); + //jQuery.fn.fmatter.rowactions('97358ea2-8227-483b-a225-5d13a522402e_50','displayparticipants_97358ea2-8227-483b-a225-5d13a522402e_t','cancel',0); + lastSel2=id; + } + $.fn.fmatter.rowactions(id,'displayparticipants_'+parid[0]+'_t','edit',0); + if(method=='edit') { + jQuery("#displayparticipants_"+parid[0]+"_t").jqGrid('restoreRow',id); + jQuery("#displayparticipants_"+parid[0]+"_t").restoreRow(id); + } + jQuery("#displayparticipants_"+parid[0]+"_t").jqGrid('editRow',id,true); + jQuery("#displayparticipants_"+parid[0]+"_t").editRow(id,true); + } + } + }); \ No newline at end of file From 710709ccee285ba06290714169bf3ee47bc324a6 Mon Sep 17 00:00:00 2001 From: jcleeland Date: Sun, 29 Jul 2012 12:03:20 +1000 Subject: [PATCH 14/75] Fixed issue #6067 - changed save methodology to see if it resolves @fred's issues (params entered via different method) --- .../controllers/admin/participantsaction.php | 54 +++++++++++-------- .../models/ParticipantAttributeNames.php | 39 +++++++++----- application/models/Participants.php | 6 ++- 3 files changed, 64 insertions(+), 35 deletions(-) diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index 86cf94c1c58..900de8eea42 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -1142,11 +1142,14 @@ function getAttribute_json() $aData->rows[0]['cell'] = array(); $i = 0; - $doneattributes = array(); + $doneattributes = array(); //If the user has any actual attribute values, they'll be stored here + + /* Iterate through each attribute owned by this user */ foreach ($records as $row) { $aData->rows[$i]['id'] = $row['participant_id'] . "_" . $row['attribute_id']; $aData->rows[$i]['cell'] = array("", $row['participant_id'], $row['attribute_type'], $row['attribute_name'], $row['value']); + /* Collect allowed values for a DropDown attribute */ if ($row['attribute_type'] == "DD") { $attvalues = ParticipantAttributeNames::model()->getAttributesValues($row['attribute_id']); @@ -1173,47 +1176,54 @@ function getAttribute_json() array_push($doneattributes, $row['attribute_id']); $i++; } + + /* Build a list of attribute names for which this user has NO values stored, keep it in $attributenotdone */ + $attributenotdone=array(); + /* The user has NO values stored against any attribute */ if (count($doneattributes) == 0) { $attributenotdone = ParticipantAttributeNames::model()->getAttributes(); } + /* The user has SOME values stored against attributes */ else { $attributenotdone = ParticipantAttributeNames::model()->getnotaddedAttributes($doneattributes); } - if ($attributenotdone > 0) + + /* Go through the empty attributes and build an entry in the output for them */ + foreach ($attributenotdone as $row) { - foreach ($attributenotdone as $row) + $aData->rows[$i]['id'] = $iParticipantId . "_" . $row['attribute_id']; + $aData->rows[$i]['cell'] = array("", $iParticipantId, $row['attribute_type'], $row['attribute_name'], ""); + if ($row['attribute_type'] == "DD") { - - $aData->rows[$i]['id'] = $iParticipantId . "_" . $row['attribute_id']; - $aData->rows[$i]['cell'] = array("", $iParticipantId, $row['attribute_type'], $row['attribute_name'], ""); - if ($row['attribute_type'] == "DD") + $attvalues = ParticipantAttributeNames::model()->getAttributesValues($row['attribute_id']); + if (!empty($attvalues)) { - $attvalues = ParticipantAttributeNames::model()->getAttributesValues($row['attribute_id']); - if (!empty($attvalues)) - { - $attval = ""; - foreach ($attvalues as $val) - { - $attval .= $val['value'] . ":" . $val['value']; - $attval .= ";"; - } - $attval = substr($attval, 0, -1); - array_push($aData->rows[$i]['cell'], $attval); - } - else + $attval = ""; + foreach ($attvalues as $val) { - array_push($aData->rows[$i]['cell'], ""); + $attval .= $val['value'] . ":" . $val['value']; + $attval .= ";"; } + $attval = substr($attval, 0, -1); + array_push($aData->rows[$i]['cell'], $attval); } else { array_push($aData->rows[$i]['cell'], ""); } - $i++; } + else + { + array_push($aData->rows[$i]['cell'], ""); + } + $i++; } + /* TODO: It'd be nice to do a natural sort on the attribute list at some point. + Currently they're returned in order of attributes WITH values, then WITHOUT values + */ + echo ls_json_encode($aData); } diff --git a/application/models/ParticipantAttributeNames.php b/application/models/ParticipantAttributeNames.php index ecf0cec425f..2da202d815d 100644 --- a/application/models/ParticipantAttributeNames.php +++ b/application/models/ParticipantAttributeNames.php @@ -171,19 +171,26 @@ function getnotaddedAttributes($attributeid) $notin[] = $row; } $attrid = array('not in','{{participant_attribute_names}}.attribute_id', $notin); - return Yii::app()->db->createCommand()->select('*')->from('{{participant_attribute_names}}')->join('{{participant_attribute_names_lang}}', '{{participant_attribute_names}}.attribute_id = {{participant_attribute_names_lang}}.attribute_id')->where($attrid)->queryAll(); + return Yii::app()->db->createCommand() + ->select('*') + ->from('{{participant_attribute_names}}') + ->join('{{participant_attribute_names_lang}}', '{{participant_attribute_names}}.attribute_id = {{participant_attribute_names_lang}}.attribute_id') + ->where($attrid) + ->queryAll(); } function storeAttribute($data) { $insertnames = array('attribute_type' => $data['attribute_type'], 'visible' => $data['visible']); - Yii::app()->db->createCommand()->insert('{{participant_attribute_names}}',$insertnames); + Yii::app()->db->createCommand() + ->insert('{{participant_attribute_names}}',$insertnames); $attribute_id = Yii::app()->db->getLastInsertID(); $insertnameslang = array('attribute_id' => intval($attribute_id), 'attribute_name'=> $data['attribute_name'], 'lang' => Yii::app()->session['adminlang']); - Yii::app()->db->createCommand()->insert('{{participant_attribute_names_lang}}',$insertnameslang); + Yii::app()->db->createCommand() + ->insert('{{participant_attribute_names_lang}}',$insertnameslang); return $attribute_id; @@ -191,15 +198,23 @@ function storeAttribute($data) function editParticipantAttributeValue($data) { - $query = Yii::app()->db->createCommand()->where('participant_id = :participant_id AND attribute_id = :attribute_id')->from('{{participant_attribute}}')->select('*')->bindParam(":participant_id", $data["participant_id"], PDO::PARAM_INT)->bindParam(":attribute_id", $data["attribute_id"], PDO::PARAM_INT)->queryAll(); - if(count($query) == 0) - { - Yii::app()->db->createCommand()->insert('{{participant_attribute}}',$data); - } - else - { - Yii::app()->db->createCommand()->update('{{participant_attribute}}',$data,'participant_id = :participant_id AND attribute_id = :attribute_id')->bindParam(":participant_id", $data["participant_id"], PDO::PARAM_INT)->bindParam(":attribute_id", $data["attribute_id"], PDO::PARAM_INT); - } + $query = Participant_attribute::model()->find('participant_id = :participant_id AND attribute_id=:attribute_id', + array(':participant_id'=>$data['participant_id'], + ':attribute_id'=>$data['attribute_id']) + ); + if(count($query) == 0) + { + Yii::app()->db->createCommand() + ->insert('{{participant_attribute}}',$data); + } + else + { + Yii::app()->db->createCommand() + ->update('{{participant_attribute}}', + $data, + 'participant_id = :participant_id AND attribute_id = :attribute_id', + array(':participant_id' => $data['participant_id'], ':attribute_id'=>$data['attribute_id'])); + } } diff --git a/application/models/Participants.php b/application/models/Participants.php index 8b5beb74181..87572af4c22 100644 --- a/application/models/Participants.php +++ b/application/models/Participants.php @@ -150,7 +150,11 @@ function insertParticipant($data) function updateRow($data) { - Yii::app()->db->createCommand()->update('{{participants}}', $data, 'participant_id = :participant_id')->bindParam(":participant_id", $data["participant_id"], PDO::PARAM_INT); + Yii::app()->db->createCommand() + ->update('{{participants}}', + $data, + 'participant_id = :participant_id', + array(':participant_id'=>$data['participant_id'])); } /* From 15bb15acc8aa4af26b89d04f4c20d27b191e26ee Mon Sep 17 00:00:00 2001 From: root Date: Mon, 30 Jul 2012 00:05:47 +0200 Subject: [PATCH 15/75] Dev Automatic translation update --- locale/_template/limesurvey.pot | 40 ++++++++++++++++----------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index 80b6224299d..226c9ddd77d 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-07-28 15:19:58+00:00\n" +"POT-Creation-Date: 2012-07-29 22:05:45+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -1683,7 +1683,7 @@ msgstr "" #: application/controllers/admin/dataentry.php:306 #: application/controllers/admin/labels.php:100 #: application/controllers/admin/labels.php:133 -#: application/controllers/admin/participantsaction.php:1358 +#: application/controllers/admin/participantsaction.php:1369 #: application/controllers/admin/question.php:55 #: application/controllers/admin/questiongroup.php:55 #: application/controllers/admin/surveyadmin.php:204 @@ -2375,63 +2375,63 @@ msgstr "" msgid "Assessment group score" msgstr "" -#: application/controllers/admin/participantsaction.php:286 +#: application/controllers/admin/participantsaction.php:287 #: application/views/admin/participants/attributeControl_view.php:5 #: application/views/admin/participants/attributeControl_view.php:6 msgid "Drop-down list" msgstr "" -#: application/controllers/admin/participantsaction.php:287 +#: application/controllers/admin/participantsaction.php:288 #: application/views/admin/participants/attributeControl_view.php:5 #: application/views/admin/participants/attributeControl_view.php:6 msgid "Date" msgstr "" -#: application/controllers/admin/participantsaction.php:288 +#: application/controllers/admin/participantsaction.php:289 #: application/views/admin/participants/attributeControl_view.php:5 #: application/views/admin/participants/attributeControl_view.php:6 msgid "Text box" msgstr "" -#: application/controllers/admin/participantsaction.php:344 +#: application/controllers/admin/participantsaction.php:345 msgid "Attribute display setting updated" msgstr "" -#: application/controllers/admin/participantsaction.php:530 -#: application/controllers/admin/participantsaction.php:550 +#: application/controllers/admin/participantsaction.php:531 +#: application/controllers/admin/participantsaction.php:551 msgid "Export %s participant(s) to CSV" msgstr "" -#: application/controllers/admin/participantsaction.php:651 -#: application/controllers/admin/participantsaction.php:665 +#: application/controllers/admin/participantsaction.php:652 +#: application/controllers/admin/participantsaction.php:666 msgid "%s participant(s) are to be copied " msgstr "" -#: application/controllers/admin/participantsaction.php:1721 +#: application/controllers/admin/participantsaction.php:1732 msgid "%s participants have been shared" msgstr "" -#: application/controllers/admin/participantsaction.php:1741 +#: application/controllers/admin/participantsaction.php:1752 msgid "%s participants have been copied to the central participants table" msgstr "" -#: application/controllers/admin/participantsaction.php:1744 -#: application/controllers/admin/participantsaction.php:1768 -#: application/controllers/admin/participantsaction.php:1798 +#: application/controllers/admin/participantsaction.php:1755 +#: application/controllers/admin/participantsaction.php:1779 +#: application/controllers/admin/participantsaction.php:1809 msgid "%s entries were not copied because they already existed" msgstr "" -#: application/controllers/admin/participantsaction.php:1748 +#: application/controllers/admin/participantsaction.php:1759 msgid "Attribute values for existing participants have been updated from the token records" msgstr "" -#: application/controllers/admin/participantsaction.php:1765 -#: application/controllers/admin/participantsaction.php:1795 +#: application/controllers/admin/participantsaction.php:1776 +#: application/controllers/admin/participantsaction.php:1806 msgid "%s participants have been copied to the survey token table" msgstr "" -#: application/controllers/admin/participantsaction.php:1772 -#: application/controllers/admin/participantsaction.php:1802 +#: application/controllers/admin/participantsaction.php:1783 +#: application/controllers/admin/participantsaction.php:1813 msgid "Attribute values for existing participants have been updated from the participants records" msgstr "" From 7525cbda0a46c478b6256339ea44cd520afa7889 Mon Sep 17 00:00:00 2001 From: jcleeland Date: Mon, 30 Jul 2012 11:54:27 +1000 Subject: [PATCH 16/75] Fixed issue #6402 adding participants to survey without selecting individual ones copies participants you don't own --- .../controllers/admin/participantsaction.php | 17 +++++++++++++++-- application/models/Participants.php | 2 +- scripts/admin/displayParticipant.js | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index 900de8eea42..793f64d1228 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -682,12 +682,20 @@ function getSearchIDs() { $participantid = ""; $condition = explode("||", $searchcondition); // explode the condition to the array - $query = Participants::model()->getParticipantsSearchMultiple($condition, 0, 0); foreach ($query as $key => $value) { - $participantid = $participantid . "," . $value['participant_id']; // combine the participant id's in an string + if (Yii::app()->session['USER_RIGHT_SUPERADMIN']) + { + $participantid .= "," . $value['participant_id']; // combine the participant id's in an string + } else + { + if(Participants::model()->is_owner($value['participant_id'])) + { + $participantid .= "," . $value['participant_id']; // combine the participant id's in an string + } + } } echo $participantid; //echo the participant id's } @@ -1951,11 +1959,16 @@ function attributeMapToken() $this->_renderWrappedTemplate('participants', 'attributeMapToken', $aData); } + /** + * This function deletes the uploaded csv file if the import is cancelled + * + */ function mapCSVcancelled() { unlink(Yii::app()->getConfig('tempdir') . '/' . basename(Yii::app()->request->getPost('fullfilepath'))); } + function blacklistParticipant() { $this->load->model('participants_model'); diff --git a/application/models/Participants.php b/application/models/Participants.php index 87572af4c22..9aa0338e051 100644 --- a/application/models/Participants.php +++ b/application/models/Participants.php @@ -650,7 +650,7 @@ function copytosurveyatt($surveyid, $mapped, $newcreate, $participantid, $overwr $duplicate = 0; $sucessfull = 0; $participantid = explode(",", $participantid); //List of participant ids to add to tokens table - if ($participantid[0] == "") { $participantid = array_slice($participantid, 1); } + if ($participantid[0] == "") { $participantid = array_slice($participantid, 1); } $number2add = sanitize_int(count($newcreate)); //Number of tokens being created $tokenattributefieldnames=array(); //Will contain descriptions of existing token attribute fields $tokenfieldnames=array(); //Will contain the actual field names of existing token attribute fields diff --git a/scripts/admin/displayParticipant.js b/scripts/admin/displayParticipant.js index 4fc38cb0ee8..399591370f8 100644 --- a/scripts/admin/displayParticipant.js +++ b/scripts/admin/displayParticipant.js @@ -484,6 +484,7 @@ $(document).ready(function() { /* if it is empty, then no items have been ticked */ var rows = myGrid.getGridParam('selarrrow'); + /* Show summary of how many participants will be added to the survey */ if(rows=="") { var totalitems = myGrid.getGridParam('records'); $('#allinview').text(addAllInViewTxt.replace('%s', totalitems)); From 5648dd3d709988a3e02de500704afca44bfb9a8b Mon Sep 17 00:00:00 2001 From: jcleeland Date: Mon, 30 Jul 2012 14:33:14 +1000 Subject: [PATCH 17/75] Fixed issue #6403 Link from participants grid to surveys bypasses survey permissions --- .../controllers/admin/participantsaction.php | 11 ++++++++- application/controllers/admin/tokens.php | 24 +++++++++++++++++-- application/models/Participants.php | 6 +++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index 793f64d1228..b5c6e129e97 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -492,7 +492,16 @@ function getSurveyInfo_json() foreach ($records as $row) { $surveyname = Surveys_languagesettings::model()->getSurveyNames($row['survey_id']); - $aData->rows[$i]['cell'] = array($surveyname[0]['surveyls_title'], '' . $row['survey_id'], $row['token_id'], $row['date_created'], $row['date_invited'], $row['date_completed']); + $surveylink = ""; + /* Check permissions of each survey before creating a link*/ + if (!hasSurveyPermission($row['survey_id'], 'tokens', 'read')) + { + $surveylink = $row['survey_id']; + } else + { + $surveylink = '' . $row['survey_id'].''; + } + $aData->rows[$i]['cell'] = array($surveyname[0]['surveyls_title'], $surveylink, $row['token_id'], $row['date_created'], $row['date_invited'], $row['date_completed']); $i++; } diff --git a/application/controllers/admin/tokens.php b/application/controllers/admin/tokens.php index 31d2aa18786..47ce7828e6f 100644 --- a/application/controllers/admin/tokens.php +++ b/application/controllers/admin/tokens.php @@ -34,7 +34,7 @@ function index($iSurveyId) if (!hasSurveyPermission($iSurveyId, 'tokens', 'read')) { - die("no permissions"); // TODO Replace + die("You do not have permission to view this page"); // TODO Replace } Yii::app()->loadHelper("surveytranslator"); @@ -244,6 +244,12 @@ function bounceprocessing($iSurveyId) */ function browse($iSurveyId, $limit = 50, $start = 0, $order = false, $searchstring = false) { + /* Check permissions */ + if (!hasSurveyPermission($iSurveyId, 'tokens', 'read')) + { + die("You do not have permission to view this page"); // TODO Replace + } + // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) //If no tokens table exists @@ -870,6 +876,11 @@ function edit($iSurveyId, $iTokenId) */ function delete($iSurveyId) { + /* Check permissions */ + if (!hasSurveyPermission($iSurveyId, 'tokens', 'read')) + { + die("You do not have permission to view this page"); // TODO Replace + } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) //If no tokens table exists @@ -1053,6 +1064,11 @@ function addDummies($iSurveyId, $subaction = '') */ function managetokenattributes($iSurveyId) { + /* Check permissions */ + if (!hasSurveyPermission($iSurveyId, 'tokens', 'read')) + { + die("You do not have permission to view this page"); // TODO Replace + } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) //If no tokens table exists @@ -1183,6 +1199,11 @@ function updatetokenattributedescriptions($iSurveyId) */ function email($iSurveyId, $aTokenIds = null) { + /* Check permissions */ + if (!hasSurveyPermission($iSurveyId, 'tokens', 'read')) + { + die("You do not have permission to view this page"); // TODO Replace + } // CHECK TO SEE IF A TOKEN TABLE EXISTS FOR THIS SURVEY $bTokenExists = tableExists('{{tokens_' . $iSurveyId . '}}'); if (!$bTokenExists) //If no tokens table exists @@ -2039,7 +2060,6 @@ function import($iSurveyId) $this->_renderWrappedTemplate('token', array('tokenbar', 'csvpost'), $aData); } - } else { diff --git a/application/models/Participants.php b/application/models/Participants.php index 9aa0338e051..1bba4ead6b7 100644 --- a/application/models/Participants.php +++ b/application/models/Participants.php @@ -603,6 +603,12 @@ function getParticipantsSearchMultiple($condition, $page, $limit) return $data; } + /** + * Returns true if participant_id has ownership or shared rights over this participant false if not + * + * @param mixed $participant_id + * @returns bool true/false + */ function is_owner($participant_id) { $userid = Yii::app()->session['loginID']; From 39b5089519acbd1c950066dd62fb9f672bebcdf8 Mon Sep 17 00:00:00 2001 From: jcleeland Date: Mon, 30 Jul 2012 14:46:25 +1000 Subject: [PATCH 18/75] Fixed issue #6113 Import participants from CSV does not work. Adjusted system settings to cope with mac file endings Dev note: (check the diff and have a laugh at why this wasn't working before!) --- application/controllers/admin/participantsaction.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index b5c6e129e97..f34a7bfc420 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -1437,21 +1437,24 @@ function uploadCSV() $filterblankemails = Yii::app()->request->getPost('filterbea'); $overwrite = Yii::app()->request->getPost('overwrite'); $errorinupload = ""; - $tokenlistarray = file($sFilePath); $recordcount = 0; $mandatory = 0; $mincriteria = 0; $imported = 0; $dupcount = 0; $overwritten = 0; - $dupreason="nameemail"; + $dupreason="nameemail"; //Default duplicate comparison method $duplicatelist = array(); $invalidemaillist = array(); $invalidformatlist = array(); $invalidattribute = array(); $invalidparticipantid = array(); - // This allows to read file with MAC line endings too + + /* Adjust system settings to read file with MAC line endings */ @ini_set('auto_detect_line_endings', true); + /* Open the uploaded file into an array */ + $tokenlistarray = file($sFilePath); + // open it and trim the endings $separator = Yii::app()->request->getPost('seperatorused'); $uploadcharset = Yii::app()->request->getPost('characterset'); From 0017dd951cd4d62b5121cddaf1e99cbf19c9c5d7 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Mon, 30 Jul 2012 12:10:08 +0300 Subject: [PATCH 19/75] Fixed issue: Fix naming according to hungarian rule --- .../controllers/admin/remotecontrol.php | 350 +++++++++--------- 1 file changed, 175 insertions(+), 175 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 82a7febf946..bca7fe7d3bf 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -395,21 +395,21 @@ public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) $aBasicDestinationFields=Survey::model()->tableSchema->columnNames; $aSurveySettings=array_intersect($aSurveySettings,$aBasicDestinationFields); - $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); + $aBasicAttributes = Survey::model()->findByPk($iSurveyID)->getAttributes(); - $result = array(); + $aResult = array(); if (empty($aSurveySettings)) return array('status' => 'No valid Data'); - foreach($aSurveySettings as $sproperty_name) + foreach($aSurveySettings as $sPropertyName) { - if (isset($abasic_attrs[$sproperty_name])) - $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + if (isset($aBasicAttributes[$sPropertyName])) + $aResult[$sPropertyName]=$aBasicAttributes[$sPropertyName]; else - $result[$sproperty_name]='Not available'; + $aResult[$sPropertyName]='Not available'; } - return $result; + return $aResult; } else return array('status' => 'No permission'); @@ -446,8 +446,8 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) $aDestinationFields=array_flip(Survey::model()->tableSchema->columnNames); $aSurveyData=array_intersect_key($aSurveyData,$aDestinationFields); $oSurvey=Survey::model()->findByPk($iSurveyID); - $succeded = array(); - $failed = array(); + $aSucceded = array(); + $aFailed = array(); if ($oSurvey->active=='Y') { // remove all fields that may not be changed when a survey is active @@ -467,16 +467,16 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) if($this->_internal_validate($sFieldName,$sValue)) { $oSurvey->$sFieldName=$sValue; - $succeded[$sFieldName]=$sValue; + $aSucceded[$sFieldName]=$sValue; } else - $failed[$sFieldName]=$sValue; + $aFailed[$sFieldName]=$sValue; } try { $oSurvey->save(); // save the change to database - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; + $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); + return $aResult; } catch(Exception $e) { @@ -513,18 +513,18 @@ public function list_surveys($sSessionKey, $suser='') if (!isset($aUserData)) return array('status' => 'Invalid user'); - $user_surveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); - if(count($user_surveys)==0) + $aUserSurveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); + if(count($aUserSurveys)==0) return array('status' => 'No surveys found'); - foreach ($user_surveys as $asurvey) + foreach ($aUserSurveys as $aSurvey) { - $asurvey_ls = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $asurvey->primaryKey, 'surveyls_language' => $asurvey->language)); - if (!isset($asurvey_ls)) - $asurvey_title = ''; + $aSurveyLanguageSettings = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $aSurvey->primaryKey, 'surveyls_language' => $aSurvey->language)); + if (!isset($aSurveyLanguageSettings)) + $aSurveyTitle = ''; else - $asurvey_title = $asurvey_ls->attributes['surveyls_title']; - $aData[]= array('sid'=>$asurvey->primaryKey,'surveyls_title'=>$asurvey_title,'startdate'=>$asurvey->attributes['startdate'],'expires'=>$asurvey->attributes['expires'],'active'=>$asurvey->attributes['active']); + $aSurveyTitle = $aSurveyLanguageSettings->attributes['surveyls_title']; + $aData[]= array('sid'=>$aSurvey->primaryKey,'surveyls_title'=>$aSurveyTitle,'startdate'=>$aSurvey->attributes['startdate'],'expires'=>$aSurvey->attributes['expires'],'active'=>$aSurvey->attributes['active']); } return $aData; } @@ -584,47 +584,47 @@ public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $gra if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID');; if(Survey::model()->findByPk($iSurveyID)->owner_id != $_SESSION['loginID']) return array('status' => 'Error: No Permission'); - $allqs = Questions::model()->findAll("sid = '".$iSurveyID."'"); - foreach($allqs as $field) + $oAllQuestions = Questions::model()->findAll("sid = '".$iSurveyID."'"); + foreach($oAllQuestions as $sField) { - $myField = $iSurveyID."X".$field['gid']."X".$field['qid']; + $sMyField = $iSurveyID."X".$sField['gid']."X".$sField['qid']; // Multiple choice get special treatment - if ($field['type'] == "M" || $field['type'] == "P") {$myField = "M$myField";} + if ($sField['type'] == "M" || $sField['type'] == "P") {$sMyField = "M$myField";} //numerical input will get special treatment (arihtmetic mean, standard derivation, ...) - if ($field['type'] == "N") {$myField = "N$myField";} - if ($field['type'] == "Q") {$myField = "Q$myField";} + if ($sField['type'] == "N") {$sMyField = "N$myField";} + if ($sField['type'] == "Q") {$sMyField = "Q$myField";} // textfields get special treatment - if ($field['type'] == "S" || $field['type'] == "T" || $field['type'] == "U"){$myField = "T$myField";} + if ($sField['type'] == "S" || $sField['type'] == "T" || $sField['type'] == "U"){$sMyField = "T$myField";} //statistics for Date questions are not implemented yet. - if ($field['type'] == "D") {$myField = "D$myField";} - if ($field['type'] == "F" || $field['type'] == "H") + if ($sField['type'] == "D") {$sMyField = "D$myField";} + if ($sField['type'] == "F" || $sField['type'] == "H") { - $result3 = Answers::model()->findAllByAttributes(array('qid' => $field['qid'],'language' => getBaseLanguageFromSurveyID($sid)), array('order' => 'sortorder, answer')); + $result3 = Answers::model()->findAllByAttributes(array('qid' => $sField['qid'],'language' => getBaseLanguageFromSurveyID($iSurveyID)), array('order' => 'sortorder, answer')); foreach ($result3 as $row) { - $myField = "$myField{$row['code']}"; + $sMyField = "$sMyField{$row['code']}"; } } - $summary[]=$myField; + $aSummary[]=$myField; } switch ($docType) { case 'pdf': - $tempFile = generate_statistics($iSurveyID,$summary,'all',$graph,$docType,'F'); + $tempFile = generate_statistics($iSurveyID,$aSummary,'all',$graph,$docType,'F'); break; case 'xls': - $tempFile = generate_statistics($iSurveyID,$summary,'all',0,$docType, 'F'); + $tempFile = generate_statistics($iSurveyID,$aSummary,'all',0,$docType, 'F'); break; case 'html': - $html = generate_statistics($iSurveyID,$summary,'all',0,$docType, 'F'); + $html = generate_statistics($iSurveyID,$aSummary,'all',0,$docType, 'F'); break; } @@ -632,9 +632,9 @@ public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $gra return base64_encode($html); else { - $result = file_get_contents($tempfile); + $sResult = file_get_contents($tempfile); unlink($tempfile); - return base64_encode($result); + return base64_encode($sResult); } } @@ -645,30 +645,30 @@ public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $gra * @access public * @param string $sSessionKey Auth credentials * @param int $iSurveyID Id of the Survey to get summary - * @param string $stat_name Name of the sumamry option + * @param string $sStatName Name of the sumamry option * @return string The requested value */ - public function get_summary($sSessionKey,$iSurveyID, $stat_name) + public function get_summary($sSessionKey,$iSurveyID, $sStatName) { - $permitted_stats = array(); + $aPermittedStats = array(); if ($this->_checkSessionKey($sSessionKey)) { - $permitted_token_stats = array('token_count', + $aPermittedTokenStats = array('token_count', 'token_invalid', 'token_sent', 'token_opted_out', 'token_completed' ); - $permitted_survey_stats = array('completed_responses', + $aPermittedSurveyStats = array('completed_responses', 'incomplete_responses', 'full_responses' ); - $permitted_stats = array_merge($permitted_survey_stats, $permitted_token_stats); - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $aPermittedStats = array_merge($aPermittedSurveyStats, $aPermittedTokenStats); + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Invalid surveyid'); - if(in_array($stat_name, $permitted_token_stats)) + if(in_array($sStatName, $aPermittedTokenStats)) { if (tableExists('{{tokens_' . $iSurveyID . '}}')) $summary = Tokens_dynamic::model($iSurveyID)->summary(); @@ -676,15 +676,15 @@ public function get_summary($sSessionKey,$iSurveyID, $stat_name) return array('status' => 'No available data'); } - if(in_array($stat_name, $permitted_survey_stats) && !tableExists('{{survey_' . $iSurveyID . '}}')) + if(in_array($sStatName, $aPermittedSurveyStats) && !tableExists('{{survey_' . $iSurveyID . '}}')) return array('status' => 'No available data'); - if (!in_array($stat_name, $permitted_stats)) + if (!in_array($sStatName, $aPermittedStats)) return array('status' => 'No such property'); if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { - switch($stat_name) + switch($sStatName) { case 'token_count': if (isset($summary)) @@ -856,10 +856,10 @@ public function delete_language($sSessionKey, $iSurveyID, $sLanguage) * @param string $sSessionKey Auth credentials * @param int $iSurveyID Dd of the Survey * @param array $aSurveyLocaleSettings Properties to get - * @param string $slang Language to use + * @param string $sLang Language to use * @return array The requested values */ - public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $slang=NULL) + public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleSettings, $sLang=NULL) { Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) @@ -875,26 +875,26 @@ public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleS $aSurveyLocaleSettings=array_intersect($aSurveyLocaleSettings,$aBasicDestinationFields); - $abasic_attrs = Survey::model()->findByPk($iSurveyID)->getAttributes(); + $aBasicAttributes = Survey::model()->findByPk($iSurveyID)->getAttributes(); - if ($slang == NULL || !array_key_exists($slang,getLanguageDataRestricted())) - $slang = $abasic_attrs['language']; + if ($sLang == NULL || !array_key_exists($sLang,getLanguageDataRestricted())) + $sLang = $aBasicAttributes['language']; - $alang_attrs = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $slang))->getAttributes(); + $aLangAttributes = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLang))->getAttributes(); - $result = array(); + $aResult = array(); if (empty($aSurveyLocaleSettings)) return array('status' => 'No valid Data'); - foreach($aSurveyLocaleSettings as $sproperty_name) + foreach($aSurveyLocaleSettings as $sPropertyName) { - if (isset($alang_attrs[$sproperty_name])) - $result[$sproperty_name]=$alang_attrs[$sproperty_name]; + if (isset($alangAttributes[$sPropertyName])) + $aResult[$sPropertyName]=$aLangAttributes[$sPropertyName]; else - $result[$sproperty_name]='Not available'; + $aResult[$sPropertyName]='Not available'; } - return $result; + return $aResult; } else return array('status' => 'No permission'); @@ -943,8 +943,8 @@ public function set_language_properties($sSessionKey, $iSurveyID, $aSurveyLocale $aSurveyLocaleData=array_intersect_key($aSurveyLocaleData,$aDestinationFields); $oSurveyLocale = Surveys_languagesettings::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLanguage)); - $succeded = array(); - $failed = array(); + $aSucceded = array(); + $aFailed = array(); if (empty($aSurveyLocaleData)) return array('status' => 'No valid Data'); @@ -954,16 +954,16 @@ public function set_language_properties($sSessionKey, $iSurveyID, $aSurveyLocale if($this->_internal_validate($sFieldName,$sValue)) { $oSurveyLocale->$sFieldName=$sValue; - $succeded[$sFieldName]=$sValue; + $aSucceded[$sFieldName]=$sValue; } else - $failed[$sFieldName]=$sValue; + $aFailed[$sFieldName]=$sValue; } try { $oSurveyLocale->save(); // save the change to database - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; + $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); + return $aResult; } catch(Exception $e) { @@ -997,21 +997,21 @@ public function add_group($sSessionKey, $iSurveyID, $sGroupTitle, $sGroupDescrip { if (hasSurveyPermission($iSurveyID, 'survey', 'update')) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - if($surveyidExists['active']=='Y') + if($oSurvey['active']=='Y') return array('status' => 'Error:Survey is active and not editable'); - $group = new Groups; - $group->sid = $iSurveyID; - $group->group_name = $sGroupTitle; - $group->description = $sGroupDescription; - $group->group_order = getMaxGroupOrder($iSurveyID); - $group->language = Survey::model()->findByPk($iSurveyID)->language; - if($group->save()) - return $group->gid; + $oGroup = new Groups; + $oGroup->sid = $iSurveyID; + $oGroup->group_name = $sGroupTitle; + $oGroup->description = $sGroupDescription; + $oGroup->group_order = getMaxGroupOrder($iSurveyID); + $oGroup->language = Survey::model()->findByPk($iSurveyID)->language; + if($oGroup->save()) + return $oGroup->gid; else return array('status' => 'Creation Failed'); } @@ -1038,15 +1038,15 @@ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) { $iSurveyID = sanitize_int($iSurveyID); $iGroupID = sanitize_int($iGroupID); - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - $groupidExists = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($groupidExists)) + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($oGroup)) return array('status' => 'Error: Invalid group ID'); - if($surveyidExists['active']=='Y') + if($oSurvey['active']=='Y') return array('status' => 'Error:Survey is active and not editable'); if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) @@ -1088,11 +1088,11 @@ public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDat if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - if($surveyidExists->getAttribute('active') =='Y') + if($oSurvey->getAttribute('active') =='Y') return array('status' => 'Error:Survey is aCctive and not editable'); if (hasSurveyPermission($iSurveyID, 'survey', 'update')) @@ -1128,15 +1128,15 @@ public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDat { $iNewgid = $aImportResults['newgid']; - $group = Groups::model()->findByAttributes(array('gid' => $iNewgid)); - $slang=$group['language']; + $oGroup = Groups::model()->findByAttributes(array('gid' => $iNewgid)); + $slang=$oGroup['language']; if($sNewGroupName!='') - $group->setAttribute('group_name',$sNewGroupName); + $oGroup->setAttribute('group_name',$sNewGroupName); if($sNewGroupDescription!='') - $group->setAttribute('description',$sNewGroupDescription); + $oGroup->setAttribute('description',$sNewGroupDescription); try { - $group->save(); + $oGroup->save(); } catch(Exception $e) { @@ -1167,28 +1167,28 @@ public function get_group_properties($sSessionKey, $iGroupID, $aGroupSettings) { if ($this->_checkSessionKey($sSessionKey)) { - $current_group = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($current_group)) + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($oGroup)) return array('status' => 'Error: Invalid group ID'); $aBasicDestinationFields=Groups::model()->tableSchema->columnNames; $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); - if (hasSurveyPermission($current_group->sid, 'survey', 'read')) + if (hasSurveyPermission($oGroup->sid, 'survey', 'read')) { - $abasic_attrs = $current_group ->getAttributes(); + $aBasicAttributes = $oGroup ->getAttributes(); if (empty($aGroupSettings)) return array('status' => 'No valid Data'); foreach($aGroupSettings as $sGroupSetting) { - if (isset($abasic_attrs[$sGroupSetting])) - $result[$sGroupSetting]=$abasic_attrs[$sGroupSetting]; + if (isset($aBasicAttributes[$sGroupSetting])) + $aResult[$sGroupSetting]=$aBasicAttributes[$sGroupSetting]; else - $result[$sGroupSetting]='Data not available'; + $aResult[$sGroupSetting]='Data not available'; } - return $result; + return $aResult; } else return array('status' => 'No permission'); @@ -1218,8 +1218,8 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) } if (hasSurveyPermission($oGroup->sid, 'survey', 'update')) { - $succeded = array(); - $failed = array(); + $aSucceded = array(); + $aFailed = array(); // Remove fields that may not be modified unset($aGroupData['sid']); unset($aGroupData['gid']); @@ -1232,10 +1232,10 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) foreach($aGroupData as $sFieldName=>$sValue) { - $valid_value = $this->_internal_validate($sFieldName,$sValue); + $sValidValue = $this->_internal_validate($sFieldName,$sValue); - if ($valid_value === false) - $failed[$sFieldName]=$sValue; + if ($sValidValue === false) + $aFailed[$sFieldName]=$sValue; else { //all dependencies this group has @@ -1245,11 +1245,11 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) //We do not allow groups with dependencies to change order - that would lead to broken dependencies if((isset($has_dependencies) || isset($depented_on)) && $sFieldName == 'group_order') - $failed[$sFieldName]='Group with dependencies - Order cannot be changed'; + $aFailed[$sFieldName]='Group with dependencies - Order cannot be changed'; else { - $oGroup->setAttribute($sFieldName,$valid_value); - $succeded[$sFieldName]=$sValue; + $oGroup->setAttribute($sFieldName,$sValidValue); + $aSucceded[$sFieldName]=$sValue; } } } @@ -1257,8 +1257,8 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) { $oGroup->save(); // save the change to database fixSortOrderGroups($oGroup->sid); - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; + $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); + return $aResult; } catch(Exception $e) { @@ -1285,19 +1285,19 @@ public function list_groups($sSessionKey, $iSurveyID) { if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { - $group_list = Groups::model()->findAllByAttributes(array("sid"=>$iSurveyID)); - if(count($group_list)==0) + $oGroupList = Groups::model()->findAllByAttributes(array("sid"=>$iSurveyID)); + if(count($oGroupList)==0) return array('status' => 'No groups found'); - foreach ($group_list as $group) + foreach ($oGroupList as $oGroup) { - $aData[]= array('id'=>$group->primaryKey,'group_name'=>$group->attributes['group_name']); + $aData[]= array('id'=>$oGroup->primaryKey,'group_name'=>$oGroup->attributes['group_name']); } return $aData; } @@ -1351,10 +1351,10 @@ public function delete_question($sSessionKey, $iQuestionID) Question_attributes::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); Answers::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); - $criteria = new CDbCriteria; - $criteria->addCondition('qid = :qid or parent_qid = :qid'); - $criteria->params[':qid'] = $iQuestionID; - Questions::model()->deleteAll($criteria); + $sCriteria = new CDbCriteria; + $sCriteria->addCondition('qid = :qid or parent_qid = :qid'); + $sCriteria->params[':qid'] = $iQuestionID; + Questions::model()->deleteAll($sCriteria); Defaultvalues::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); Quota_members::model()->deleteAllByAttributes(array('qid' => $iQuestionID)); @@ -1406,9 +1406,9 @@ public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData if (!isset($oGroup)) return array('status' => 'Error: Invalid group ID'); - $gsid = $oGroup['sid']; - if($gsid != $iSurveyID) - return array('status' => 'Error: IMissmatch in surveyid and groupid'); + $sGroupSurveyID = $oGroup['sid']; + if($sGroupSurveyID != $iSurveyID) + return array('status' => 'Error: Missmatch in surveyid and groupid'); if (hasSurveyPermission($iSurveyID, 'survey', 'update')) { @@ -1504,33 +1504,33 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) { - $abasic_attrs = $oQuestion->getAttributes(); - $result=array(); - foreach ($aQuestionSettings as $sproperty_name ) + $aBasicAttributes = $oQuestion->getAttributes(); + $aResult=array(); + foreach ($aQuestionSettings as $sPropertyName ) { - if ($sproperty_name == 'available_answers') + if ($sPropertyName == 'available_answers') { - $subgroups = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID),array('order'=>'title') ); - if (count($subgroups)>0) + $oSubQuestions = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID),array('order'=>'title') ); + if (count($oSubQuestions)>0) { - foreach($subgroups as $subgroup) - $aData[$subgroup['title']]= $subgroup['question']; + foreach($oSubQuestions as $oSubQuestion) + $aData[$oSubQuestion['title']]= $oSubQuestion['question']; - $result['available_answers']=$aData; + $aResult['available_answers']=$aData; } else - $result['available_answers']='No available answers'; + $aResult['available_answers']='No available answers'; } else { - if (isset($abasic_attrs[$sproperty_name])) - $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + if (isset($aBasicAttributes[$sPropertyName])) + $aResult[$sPropertyName]=$aBasicAttributes[$sPropertyName]; else - $result[$sproperty_name]='Data not available'; + $aResult[$sPropertyName]='Data not available'; } } - return $result; + return $aResult; } else return array('status' => 'No permission'); @@ -1558,8 +1558,8 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa if (hasSurveyPermission($oQuestion->sid, 'survey', 'update')) { - $succeded = array(); - $failed = array(); + $aSucceded = array(); + $aFailed = array(); // Remove fields that may not be modified unset($aQuestionData['qid']); unset($aQuestionData['gid']); @@ -1579,7 +1579,7 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa $valid_value = $this->_internal_validate($sFieldName,$sValue); if ($valid_value === false) - $failed[$sFieldName]=$sValue; + $aFailed[$sFieldName]=$sValue; else { //all the dependencies that this question has to other questions @@ -1589,11 +1589,11 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies if((isset($dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') - $failed[$sFieldName]='Questions with dependencies - Order cannot be changed'; + $aFailed[$sFieldName]='Questions with dependencies - Order cannot be changed'; else { $oQuestion->setAttribute($sFieldName,$valid_value); - $succeded[$sFieldName]=$sValue; + $aSucceded[$sFieldName]=$sValue; } } } @@ -1601,8 +1601,8 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa { $oQuestion->save(); // save the change to database fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); - $result = array('succeded'=>$succeded,'failed'=>$failed); - return $result; + $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); + return $aResult; } catch(Exception $e) { @@ -1631,8 +1631,8 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) { if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); if (hasSurveyPermission($iSurveyID, 'survey', 'read')) @@ -1640,9 +1640,9 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) if($iGroupID!=NULL) { $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - $gsid = $oGroup['sid']; + $sGroupSurveyID = $oGroup['sid']; - if($gsid != $iSurveyID) + if($sGroupSurveyID != $iSurveyID) return array('status' => 'Error: IMissmatch in surveyid and groupid'); else $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID, "gid"=>$iGroupID,"parent_qid"=>"0")); @@ -1653,9 +1653,9 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) if(count($aQuestionList)==0) return array('status' => 'No questions found'); - foreach ($aQuestionList as $question) + foreach ($aQuestionList as $oQuestion) { - $aData[]= array('id'=>$question->primaryKey,'type'=>$question->attributes['type'], 'question'=>$question->attributes['question']); + $aData[]= array('id'=>$oQuestion->primaryKey,'type'=>$oQuestion->attributes['type'], 'question'=>$oQuestion->attributes['question']); } return $aData; } @@ -1745,8 +1745,8 @@ public function delete_participants($sSessionKey, $iSurveyID, $aTokenIDs) { $iSurveyID = sanitize_int($iSurveyID); - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); if(!tableExists("{{tokens_$iSurveyID}}")) @@ -1754,22 +1754,22 @@ public function delete_participants($sSessionKey, $iSurveyID, $aTokenIDs) if (hasSurveyPermission($iSurveyID, 'tokens', 'delete')) { - $result=array(); + $aResult=array(); foreach($aTokenIDs as $iTokenID) { $tokenidExists = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); if (!isset($tokenidExists)) - $result[$iTokenID]='Invalid token ID'; + $aResult[$iTokenID]='Invalid token ID'; else { Survey_links::deleteTokenLink(array($iTokenID), $iSurveyID); if(Tokens_dynamic::model($iSurveyID)->deleteRecords(array($iTokenID))) - $result[$iTokenID]='Deleted'; + $aResult[$iTokenID]='Deleted'; else - $result[$iTokenID]='Deletion went wrong'; + $aResult[$iTokenID]='Deletion went wrong'; } } - return $result; + return $aResult; } else return array('status' => 'No permission'); @@ -1806,22 +1806,22 @@ public function get_participant_properties($sSessionKey, $iSurveyID, $iTokenID, if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) { - $result=array(); + $aResult=array(); $aBasicDestinationFields=Tokens_dynamic::model()->tableSchema->columnNames; $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); - $abasic_attrs = $oToken->getAttributes(); + $aBasicAttributes = $oToken->getAttributes(); if (empty($aTokenProperties)) return array('status' => 'No valid Data'); - foreach($aTokenProperties as $sproperty_name ) + foreach($aTokenProperties as $sPropertyName ) { - if (isset($abasic_attrs[$sproperty_name])) - $result[$sproperty_name]=$abasic_attrs[$sproperty_name]; + if (isset($aBasicAttributes[$sPropertyName])) + $aResult[$sPropertyName]=$aBasicAttributes[$sPropertyName]; else - $result[$sproperty_name]='Data not available'; + $aResult[$sPropertyName]='Data not available'; } - return $result; + return $aResult; } else return array('status' => 'No permission'); @@ -1846,8 +1846,8 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); if(!tableExists("{{tokens_$iSurveyID}}")) @@ -1857,8 +1857,8 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, if (!isset($oToken)) return array('status' => 'Error: Invalid tokenid'); - $succeded = array(); - $failed = array(); + $aSucceded = array(); + $aFailed = array(); // Remove fields that may not be modified unset($aTokenData['tid']); @@ -1875,15 +1875,15 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, if($this->_internal_validate($sFieldName,$sValue)) { $oToken->$sFieldName=$sValue; - $succeded[$sFieldName]=$sValue; + $aSucceded[$sFieldName]=$sValue; } else - $failed[$sFieldName]=$sValue; + $aFailed[$sFieldName]=$sValue; } try { $oToken->save(); - $result = array('succeded'=>$succeded,'failed'=>$failed); + $result = array('succeded'=>$aSucceded,'failed'=>$aFailed); return $result; } catch(Exception $e) @@ -1914,8 +1914,8 @@ public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) { if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); if(!tableExists("{{tokens_$iSurveyID}}")) From db996f5849e5e511470967e9890847e8e8e552b6 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Mon, 30 Jul 2012 16:35:10 +0300 Subject: [PATCH 20/75] Fixed issue: Move remotecontrol validation in model Dev: Deleted validation helper function from remote control Dev: Added validation rules in models Survey, Groups, Questions, Token_dynamic --- .../controllers/admin/remotecontrol.php | 195 ++---------------- application/models/Groups.php | 12 ++ application/models/Questions.php | 16 ++ application/models/Survey.php | 55 ++++- .../models/Surveys_languagesettings.php | 5 +- application/models/Tokens_dynamic.php | 26 ++- 6 files changed, 122 insertions(+), 187 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index bca7fe7d3bf..f04538b0349 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -464,13 +464,10 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) foreach($aSurveyData as $sFieldName=>$sValue) { - if($this->_internal_validate($sFieldName,$sValue)) - { + $oSurvey->$sFieldName=$sValue; $aSucceded[$sFieldName]=$sValue; - } - else - $aFailed[$sFieldName]=$sValue; + } try { @@ -889,7 +886,7 @@ public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleS foreach($aSurveyLocaleSettings as $sPropertyName) { - if (isset($alangAttributes[$sPropertyName])) + if (isset($aLangAttributes[$sPropertyName])) $aResult[$sPropertyName]=$aLangAttributes[$sPropertyName]; else $aResult[$sPropertyName]='Not available'; @@ -951,13 +948,10 @@ public function set_language_properties($sSessionKey, $iSurveyID, $aSurveyLocale foreach($aSurveyLocaleData as $sFieldName=>$sValue) { - if($this->_internal_validate($sFieldName,$sValue)) - { + $oSurveyLocale->$sFieldName=$sValue; $aSucceded[$sFieldName]=$sValue; - } - else - $aFailed[$sFieldName]=$sValue; + } try { @@ -1232,12 +1226,7 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) foreach($aGroupData as $sFieldName=>$sValue) { - $sValidValue = $this->_internal_validate($sFieldName,$sValue); - - if ($sValidValue === false) - $aFailed[$sFieldName]=$sValue; - else - { + //all dependencies this group has $has_dependencies=getGroupDepsForConditions($oGroup->sid,$iGroupID); //all dependencies on this group @@ -1248,10 +1237,10 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) $aFailed[$sFieldName]='Group with dependencies - Order cannot be changed'; else { - $oGroup->setAttribute($sFieldName,$sValidValue); + $oGroup->setAttribute($sFieldName,$sValue); $aSucceded[$sFieldName]=$sValue; } - } + } try { @@ -1576,12 +1565,7 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa foreach($aQuestionData as $sFieldName=>$sValue) { - $valid_value = $this->_internal_validate($sFieldName,$sValue); - - if ($valid_value === false) - $aFailed[$sFieldName]=$sValue; - else - { + //all the dependencies that this question has to other questions $dependencies=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,$iQuestionID); //all dependencies by other questions to this question @@ -1592,10 +1576,10 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa $aFailed[$sFieldName]='Questions with dependencies - Order cannot be changed'; else { - $oQuestion->setAttribute($sFieldName,$valid_value); + $oQuestion->setAttribute($sFieldName,$sValue); $aSucceded[$sFieldName]=$sValue; } - } + } try { @@ -1872,13 +1856,8 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, foreach($aTokenData as $sFieldName=>$sValue) { - if($this->_internal_validate($sFieldName,$sValue)) - { $oToken->$sFieldName=$sValue; - $aSucceded[$sFieldName]=$sValue; - } - else - $aFailed[$sFieldName]=$sValue; + $aSucceded[$sFieldName]=$sValue; } try { @@ -2169,154 +2148,6 @@ protected function _checkSessionKey($sSessionKey) } } - /** - * This function validates parameters to be changed - * - * @access protected - * @param string $sparam_name Name of the parameter - * @param string $sparam_value Value to be validated - * @return bool|string Result valid value or false - */ - protected function _internal_validate($sparam_name, $sparam_value) - { - $date_pattern = '/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/'; - $validation_categories = array( - 'active'=>'char', - 'anonymized'=>'char', - 'savetimings'=>'char', - 'datestamp'=>'char', - 'ipaddr'=>'char', - 'refurl'=>'char', - 'usecookie'=>'char', - 'allowregister'=>'char', - 'allowsave'=>'char', - 'autoredirect'=>'char', - 'allowprev'=>'char', - 'printanswers'=>'char', - 'publicstatistics'=>'char', - 'publicgraphs'=>'char', - 'listpublic'=>'char', - 'htmlemail'=>'char', - 'sendconfirmation'=>'char', - 'tokenanswerspersistence'=>'char', - 'assessments'=>'char', - 'usecaptcha'=>'captcha_format', - 'usetokens'=>'char', - 'showxquestions'=>'char', - 'showgroupinfo'=>'group_format', - 'shownoanswer'=>'char', - 'showqnumcode'=>'gnum_format', - 'showwelcome'=>'char', - 'showprogress'=>'char', - 'allowjumps'=>'char', - 'nokeyboard'=>'char', - 'alloweditaftercompletion'=>'char', - 'googleanalyticsstyle'=>'ga_format', - 'bounceprocessing'=>'char', - 'autonumber_start'=>'int', - 'tokenlength'=>'int', - 'bouncetime'=>'int', - 'navigationdelay'=>'int', - 'expires'=>'date', - 'startdate'=>'date', - 'datecreated'=>'date', - 'adminemail'=>'email', - 'bounce_email'=>'email', - 'surveyls_dateformat'=>'dateformat', - 'surveyls_numberformat'=>'numberformat', - 'template'=>'tmpl', - 'format'=>'gsa_format', - //group parameters - 'group_order'=>'int', - //question_parameters - 'other'=>'char', - 'mandatory'=>'char', - 'question_order'=>'int', - 'scale_id'=>'int', - 'same_default'=>'int', - //token parameters - 'email'=>'email', - 'remindercount'=>'int', - 'remindersent'=>'int', - 'usesleft'=>'int', - 'validfrom'=>'date', - 'validuntil'=>'date', - 'mpid'=>'int', - 'blacklisted'=>'char', - 'sent'=>'char', - 'completed'=>'char' - ); - - if (array_key_exists($sparam_name, $validation_categories)) - { - switch($validation_categories[$sparam_name]) - { - case 'char': - if(in_array($sparam_value, array('Y','N'))) - return $sparam_value; - else - return false; - break; - - case 'int': - return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>999999999))); - break; - - case 'date': - return filter_var($sparam_value, FILTER_VALIDATE_REGEXP,array("options"=>array("regexp"=>$date_pattern))); - break; - - case 'email': - return filter_var($sparam_value, FILTER_VALIDATE_EMAIL); - break; - - case 'dateformat': - return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>1, "max_range"=>12))); - break; - - case 'numberformat': - return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>0, "max_range"=>1))); - break; - case 'tmpl': - if(array_key_exists($sparam_value,getTemplateList())) - return $sparam_value; - else - return false; - break; - case 'gsa_format': - if(in_array($sparam_value, array('G','S','A'))) - return $sparam_value; - else - return false; - break; - case 'captcha_format': - if(in_array($sparam_value, array('A','B','C','D','X','R','S','N'))) - return $sparam_value; - else - return false; - break; - case 'group_format': - if(in_array($sparam_value, array('B','N','D','X'))) - return $sparam_value; - else - return false; - break; - case 'gnum_format': - if(in_array($sparam_value, array('B','N','C','X'))) - return $sparam_value; - else - return false; - break; - case 'ga_format': - return filter_var($sparam_value, FILTER_VALIDATE_INT, array("options" => array("min_range"=>0, "max_range"=>2))); - break; - default: - return $sparam_value; - - } - } - else - return $sparam_value; - } + } diff --git a/application/models/Groups.php b/application/models/Groups.php index 08e5ecc97e4..bc505a92f30 100644 --- a/application/models/Groups.php +++ b/application/models/Groups.php @@ -51,6 +51,18 @@ public function primaryKey() return 'gid'; } + + /** + * Returns this model's validation rules + * + */ + public function rules() + { + return array( + array('group_order','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + ); + } + /** * Defines the relations for this model * diff --git a/application/models/Questions.php b/application/models/Questions.php index e3641b46477..59dc9266d30 100644 --- a/application/models/Questions.php +++ b/application/models/Questions.php @@ -73,6 +73,22 @@ public function relations() ); } + /** + * Returns this model's validation rules + * + */ + public function rules() + { + return array( + array('other', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('mandatory', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('question_order','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('scale_id','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('same_default','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + ); + } + + /** * Fixes sort order for questions in a group * diff --git a/application/models/Survey.php b/application/models/Survey.php index 0cbbb7ee56c..83b2fe60587 100644 --- a/application/models/Survey.php +++ b/application/models/Survey.php @@ -95,7 +95,48 @@ public function rules() array('admin', 'xssfilter'), array('adminemail', 'xssfilter'), array('bounce_email', 'xssfilter'), - array('faxto', 'xssfilter') + array('faxto', 'xssfilter'), + array('active', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('anonymized', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('savetimings', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('datestamp', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('usecookie', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('allowregister', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('allowsave', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('autoredirect', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('allowprev', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('printanswers', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('ipaddr', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('refurl', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('publicstatistics', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('publicgraphs', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('listpublic', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('htmlemail', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('sendconfirmation', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('tokenanswerspersistence', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('assessments', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('usetokens', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('showxquestions', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('shownoanswer', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('showwelcome', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('showprogress', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('allowjumps', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('nokeyboard', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('alloweditaftercompletion', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('bounceprocessing', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('usecaptcha', 'in','range'=>array('A','B','C','D','X','R','S','N'), 'allowEmpty'=>true), + array('showgroupinfo', 'in','range'=>array('B','N','D','X'), 'allowEmpty'=>true), + array('showqnumcode', 'in','range'=>array('B','N','C','X'), 'allowEmpty'=>true), + array('format', 'in','range'=>array('G','S','A'), 'allowEmpty'=>true), + array('googleanalyticsstyle', 'numerical', 'integerOnly'=>true, 'min'=>'0', 'max'=>'2', 'allowEmpty'=>true), + array('autonumber_start','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('tokenlength','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('bouncetime','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('navigationdelay','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('expires','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true), + array('startdate','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true), + array('datecreated','date', 'format'=>'yyyy-MM-dd', 'allowEmpty'=>true), + array('template', 'tmplfilter'), ); } @@ -122,6 +163,18 @@ public function xssfilter($attribute,$params) } } + /** + * Defines the customs validation rule tmplfilter + * + * @param mixed $attribute + * @param mixed $params + */ + public function tmplfilter($attribute,$params) + { + if(!array_key_exists($this->$attribute,getTemplateList())) + $this->addError($attribute, 'Invalid template!'); + } + /** * permission scope for this model diff --git a/application/models/Surveys_languagesettings.php b/application/models/Surveys_languagesettings.php index 3f94b14125f..92c5db0fdb2 100644 --- a/application/models/Surveys_languagesettings.php +++ b/application/models/Surveys_languagesettings.php @@ -101,7 +101,10 @@ public function rules() array('surveyls_description','xssfilter'), array('surveyls_welcometext','xssfilter'), array('surveyls_endtext','xssfilter'), - array('surveyls_urldescription','xssfilter') + array('surveyls_urldescription','xssfilter'), + + array('surveyls_dateformat', 'numerical', 'integerOnly'=>true, 'min'=>'1', 'max'=>'12', 'allowEmpty'=>true), + array('surveyls_numberformat', 'numerical', 'integerOnly'=>true, 'min'=>'0', 'max'=>'1', 'allowEmpty'=>true), ); } diff --git a/application/models/Tokens_dynamic.php b/application/models/Tokens_dynamic.php index 2f9853479a2..6c56e4d9138 100644 --- a/application/models/Tokens_dynamic.php +++ b/application/models/Tokens_dynamic.php @@ -68,7 +68,27 @@ public function primaryKey() { return 'tid'; } - + + + /** + * Returns this model's validation rules + * + */ + public function rules() + { + return array( + array('remindercount','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('remindersent' ,'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('usesleft','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('mpid','numerical', 'integerOnly'=>true,'allowEmpty'=>true), + array('blacklisted', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('sent', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('completed', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('validfrom','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true), + array('validuntil','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true), + ); + } + /** * Returns summary information of this token table * @@ -163,7 +183,7 @@ function selectEmptyTokens($iSurveyID) { return Yii::app()->db->createCommand("SELECT tid FROM {{tokens_{$iSurveyID}}} WHERE token IS NULL OR token=''")->queryAll(); } - + /** * Creates and inserts token for a specific token record and returns the token string created * @@ -198,7 +218,7 @@ function createToken($iTokenID) $itresult = $this->updateToken($iTokenID, $newtoken); return $newtoken; } - + /** * Creates tokens for all token records that have empty token fields and returns the number * of tokens created From acbd4c296bade097672dec3396d0b8a3ec9f443a Mon Sep 17 00:00:00 2001 From: root Date: Tue, 31 Jul 2012 00:05:49 +0200 Subject: [PATCH 21/75] Updated translation: Czech by slansky Updated translation: Turkish by kayazeren --- locale/_template/limesurvey.pot | 258 ++++++++++++++++---------------- locale/cs/LC_MESSAGES/cs.mo | Bin 262727 -> 264370 bytes locale/tr/LC_MESSAGES/tr.mo | Bin 258367 -> 259179 bytes 3 files changed, 129 insertions(+), 129 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index 226c9ddd77d..9a16a86435d 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-07-29 22:05:45+00:00\n" +"POT-Creation-Date: 2012-07-30 22:05:44+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -101,7 +101,7 @@ msgstr "" #: application/controllers/AdminController.php:86 #: application/controllers/admin/surveyadmin.php:420 -#: application/controllers/admin/tokens.php:2164 +#: application/controllers/admin/tokens.php:2184 #: application/helpers/admin/import_helper.php:2612 #: application/views/admin/authentication/forgotpassword.php:15 #: application/views/admin/dataentry/active_html_view.php:95 @@ -844,7 +844,7 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:517 #: application/controllers/admin/surveyadmin.php:608 -#: application/controllers/admin/tokens.php:2081 +#: application/controllers/admin/tokens.php:2101 #: application/core/Survey_Common_Action.php:827 #: application/helpers/admin/statistics_helper.php:1456 #: application/helpers/admin/statistics_helper.php:1589 @@ -948,7 +948,7 @@ msgid "Yes" msgstr "" #: application/controllers/admin/conditionsaction.php:181 -#: application/controllers/admin/tokens.php:2144 +#: application/controllers/admin/tokens.php:2164 #: application/views/admin/assessments_view.php:122 #: application/views/admin/conditions/includes/conditions_scenario.php:13 #: application/views/admin/labels/labelview_view.php:161 @@ -978,7 +978,7 @@ msgid "We recommend that before you proceed, you export the entire survey from t msgstr "" #: application/controllers/admin/conditionsaction.php:190 -#: application/controllers/admin/tokens.php:1437 +#: application/controllers/admin/tokens.php:1458 #: application/controllers/admin/useraction.php:157 #: application/views/admin/dataentry/import.php:31 #: application/views/admin/survey/Question/questionbar_view.php:193 @@ -1006,8 +1006,8 @@ msgstr "" #: application/controllers/admin/surveypermission.php:329 #: application/controllers/admin/surveypermission.php:502 #: application/controllers/admin/surveypermission.php:595 -#: application/controllers/admin/tokens.php:2283 -#: application/controllers/admin/tokens.php:2318 +#: application/controllers/admin/tokens.php:2303 +#: application/controllers/admin/tokens.php:2338 #: application/controllers/admin/useraction.php:720 #: application/helpers/common_helper.php:6229 #: application/helpers/common_helper.php:6234 @@ -1096,7 +1096,7 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:518 #: application/controllers/admin/surveyadmin.php:612 -#: application/controllers/admin/tokens.php:2083 +#: application/controllers/admin/tokens.php:2103 #: application/core/Survey_Common_Action.php:823 #: application/helpers/admin/statistics_helper.php:1457 #: application/helpers/admin/statistics_helper.php:1590 @@ -1683,7 +1683,7 @@ msgstr "" #: application/controllers/admin/dataentry.php:306 #: application/controllers/admin/labels.php:100 #: application/controllers/admin/labels.php:133 -#: application/controllers/admin/participantsaction.php:1369 +#: application/controllers/admin/participantsaction.php:1386 #: application/controllers/admin/question.php:55 #: application/controllers/admin/questiongroup.php:55 #: application/controllers/admin/surveyadmin.php:204 @@ -1787,8 +1787,8 @@ msgid "Save" msgstr "" #: application/controllers/admin/dataentry.php:1587 -#: application/controllers/admin/tokens.php:848 -#: application/controllers/admin/tokens.php:1014 +#: application/controllers/admin/tokens.php:854 +#: application/controllers/admin/tokens.php:1025 #: application/controllers/admin/useraction.php:149 #: application/views/admin/dataentry/insert.php:73 #: application/views/admin/dataentry/iteratesurvey.php:5 @@ -1932,223 +1932,223 @@ msgid "The answer(s) must meet these array_filter criteria:" msgstr "" #: application/controllers/admin/dataentry.php:2495 -#: application/controllers/admin/tokens.php:1772 +#: application/controllers/admin/tokens.php:1793 #: application/views/admin/participants/importCSV_view.php:17 msgid "ARMSCII-8 Armenian" msgstr "" #: application/controllers/admin/dataentry.php:2496 -#: application/controllers/admin/tokens.php:1773 +#: application/controllers/admin/tokens.php:1794 #: application/views/admin/participants/importCSV_view.php:18 msgid "US ASCII" msgstr "" #: application/controllers/admin/dataentry.php:2497 -#: application/controllers/admin/tokens.php:1774 +#: application/controllers/admin/tokens.php:1795 #: application/views/admin/participants/importCSV_view.php:19 msgid "Automatic" msgstr "" #: application/controllers/admin/dataentry.php:2498 -#: application/controllers/admin/tokens.php:1775 +#: application/controllers/admin/tokens.php:1796 #: application/views/admin/participants/importCSV_view.php:20 msgid "Big5 Traditional Chinese" msgstr "" #: application/controllers/admin/dataentry.php:2499 -#: application/controllers/admin/tokens.php:1776 +#: application/controllers/admin/tokens.php:1797 #: application/views/admin/participants/importCSV_view.php:21 msgid "Binary pseudo charset" msgstr "" #: application/controllers/admin/dataentry.php:2500 -#: application/controllers/admin/tokens.php:1777 +#: application/controllers/admin/tokens.php:1798 #: application/views/admin/participants/importCSV_view.php:22 msgid "Windows Central European" msgstr "" #: application/controllers/admin/dataentry.php:2501 -#: application/controllers/admin/tokens.php:1778 +#: application/controllers/admin/tokens.php:1799 #: application/views/admin/participants/importCSV_view.php:23 msgid "Windows Cyrillic" msgstr "" #: application/controllers/admin/dataentry.php:2502 -#: application/controllers/admin/tokens.php:1779 +#: application/controllers/admin/tokens.php:1800 #: application/views/admin/participants/importCSV_view.php:24 msgid "Windows Arabic" msgstr "" #: application/controllers/admin/dataentry.php:2503 -#: application/controllers/admin/tokens.php:1780 +#: application/controllers/admin/tokens.php:1801 #: application/views/admin/participants/importCSV_view.php:25 msgid "Windows Baltic" msgstr "" #: application/controllers/admin/dataentry.php:2504 -#: application/controllers/admin/tokens.php:1781 +#: application/controllers/admin/tokens.php:1802 #: application/views/admin/participants/importCSV_view.php:26 msgid "DOS West European" msgstr "" #: application/controllers/admin/dataentry.php:2505 -#: application/controllers/admin/tokens.php:1782 +#: application/controllers/admin/tokens.php:1803 #: application/views/admin/participants/importCSV_view.php:27 msgid "DOS Central European" msgstr "" #: application/controllers/admin/dataentry.php:2506 -#: application/controllers/admin/tokens.php:1783 +#: application/controllers/admin/tokens.php:1804 #: application/views/admin/participants/importCSV_view.php:28 msgid "DOS Russian" msgstr "" #: application/controllers/admin/dataentry.php:2507 -#: application/controllers/admin/tokens.php:1784 +#: application/controllers/admin/tokens.php:1805 #: application/views/admin/participants/importCSV_view.php:29 msgid "SJIS for Windows Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2508 -#: application/controllers/admin/tokens.php:1785 +#: application/controllers/admin/tokens.php:1806 #: application/views/admin/participants/importCSV_view.php:30 msgid "DEC West European" msgstr "" #: application/controllers/admin/dataentry.php:2509 -#: application/controllers/admin/tokens.php:1786 +#: application/controllers/admin/tokens.php:1807 #: application/views/admin/participants/importCSV_view.php:31 msgid "UJIS for Windows Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2510 -#: application/controllers/admin/tokens.php:1787 +#: application/controllers/admin/tokens.php:1808 #: application/views/admin/participants/importCSV_view.php:32 msgid "EUC-KR Korean" msgstr "" #: application/controllers/admin/dataentry.php:2511 -#: application/controllers/admin/tokens.php:1788 +#: application/controllers/admin/tokens.php:1809 #: application/views/admin/participants/importCSV_view.php:33 msgid "GB2312 Simplified Chinese" msgstr "" #: application/controllers/admin/dataentry.php:2512 -#: application/controllers/admin/tokens.php:1789 +#: application/controllers/admin/tokens.php:1810 #: application/views/admin/participants/importCSV_view.php:34 msgid "GBK Simplified Chinese" msgstr "" #: application/controllers/admin/dataentry.php:2513 -#: application/controllers/admin/tokens.php:1790 +#: application/controllers/admin/tokens.php:1811 #: application/views/admin/participants/importCSV_view.php:35 msgid "GEOSTD8 Georgian" msgstr "" #: application/controllers/admin/dataentry.php:2514 -#: application/controllers/admin/tokens.php:1791 +#: application/controllers/admin/tokens.php:1812 #: application/views/admin/participants/importCSV_view.php:36 msgid "ISO 8859-7 Greek" msgstr "" #: application/controllers/admin/dataentry.php:2515 -#: application/controllers/admin/tokens.php:1792 +#: application/controllers/admin/tokens.php:1813 #: application/views/admin/participants/importCSV_view.php:37 msgid "ISO 8859-8 Hebrew" msgstr "" #: application/controllers/admin/dataentry.php:2516 -#: application/controllers/admin/tokens.php:1793 +#: application/controllers/admin/tokens.php:1814 #: application/views/admin/participants/importCSV_view.php:38 msgid "HP West European" msgstr "" #: application/controllers/admin/dataentry.php:2517 -#: application/controllers/admin/tokens.php:1794 +#: application/controllers/admin/tokens.php:1815 #: application/views/admin/participants/importCSV_view.php:39 msgid "DOS Kamenicky Czech-Slovak" msgstr "" #: application/controllers/admin/dataentry.php:2518 -#: application/controllers/admin/tokens.php:1795 +#: application/controllers/admin/tokens.php:1816 #: application/views/admin/participants/importCSV_view.php:40 msgid "KOI8-R Relcom Russian" msgstr "" #: application/controllers/admin/dataentry.php:2519 -#: application/controllers/admin/tokens.php:1796 +#: application/controllers/admin/tokens.php:1817 #: application/views/admin/participants/importCSV_view.php:41 msgid "KOI8-U Ukrainian" msgstr "" #: application/controllers/admin/dataentry.php:2520 -#: application/controllers/admin/tokens.php:1797 +#: application/controllers/admin/tokens.php:1818 #: application/views/admin/participants/importCSV_view.php:42 msgid "cp1252 West European" msgstr "" #: application/controllers/admin/dataentry.php:2521 -#: application/controllers/admin/tokens.php:1798 +#: application/controllers/admin/tokens.php:1819 #: application/views/admin/participants/importCSV_view.php:43 msgid "ISO 8859-2 Central European" msgstr "" #: application/controllers/admin/dataentry.php:2522 -#: application/controllers/admin/tokens.php:1799 +#: application/controllers/admin/tokens.php:1820 #: application/views/admin/participants/importCSV_view.php:44 msgid "ISO 8859-9 Turkish" msgstr "" #: application/controllers/admin/dataentry.php:2523 -#: application/controllers/admin/tokens.php:1800 +#: application/controllers/admin/tokens.php:1821 #: application/views/admin/participants/importCSV_view.php:45 msgid "ISO 8859-13 Baltic" msgstr "" #: application/controllers/admin/dataentry.php:2524 -#: application/controllers/admin/tokens.php:1801 +#: application/controllers/admin/tokens.php:1822 #: application/views/admin/participants/importCSV_view.php:46 msgid "Mac Central European" msgstr "" #: application/controllers/admin/dataentry.php:2525 -#: application/controllers/admin/tokens.php:1802 +#: application/controllers/admin/tokens.php:1823 #: application/views/admin/participants/importCSV_view.php:47 msgid "Mac West European" msgstr "" #: application/controllers/admin/dataentry.php:2526 -#: application/controllers/admin/tokens.php:1803 +#: application/controllers/admin/tokens.php:1824 #: application/views/admin/participants/importCSV_view.php:48 msgid "Shift-JIS Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2527 -#: application/controllers/admin/tokens.php:1804 +#: application/controllers/admin/tokens.php:1825 #: application/views/admin/participants/importCSV_view.php:49 msgid "7bit Swedish" msgstr "" #: application/controllers/admin/dataentry.php:2528 -#: application/controllers/admin/tokens.php:1805 +#: application/controllers/admin/tokens.php:1826 #: application/views/admin/participants/importCSV_view.php:50 msgid "TIS620 Thai" msgstr "" #: application/controllers/admin/dataentry.php:2529 -#: application/controllers/admin/tokens.php:1806 +#: application/controllers/admin/tokens.php:1827 #: application/views/admin/participants/importCSV_view.php:51 msgid "UCS-2 Unicode" msgstr "" #: application/controllers/admin/dataentry.php:2530 -#: application/controllers/admin/tokens.php:1807 +#: application/controllers/admin/tokens.php:1828 #: application/views/admin/participants/importCSV_view.php:52 msgid "EUC-JP Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2531 -#: application/controllers/admin/tokens.php:1808 +#: application/controllers/admin/tokens.php:1829 #: application/views/admin/participants/importCSV_view.php:53 msgid "UTF-8 Unicode" msgstr "" @@ -2397,41 +2397,41 @@ msgstr "" msgid "Attribute display setting updated" msgstr "" -#: application/controllers/admin/participantsaction.php:531 -#: application/controllers/admin/participantsaction.php:551 +#: application/controllers/admin/participantsaction.php:540 +#: application/controllers/admin/participantsaction.php:560 msgid "Export %s participant(s) to CSV" msgstr "" -#: application/controllers/admin/participantsaction.php:652 -#: application/controllers/admin/participantsaction.php:666 +#: application/controllers/admin/participantsaction.php:661 +#: application/controllers/admin/participantsaction.php:675 msgid "%s participant(s) are to be copied " msgstr "" -#: application/controllers/admin/participantsaction.php:1732 +#: application/controllers/admin/participantsaction.php:1752 msgid "%s participants have been shared" msgstr "" -#: application/controllers/admin/participantsaction.php:1752 +#: application/controllers/admin/participantsaction.php:1772 msgid "%s participants have been copied to the central participants table" msgstr "" -#: application/controllers/admin/participantsaction.php:1755 -#: application/controllers/admin/participantsaction.php:1779 -#: application/controllers/admin/participantsaction.php:1809 +#: application/controllers/admin/participantsaction.php:1775 +#: application/controllers/admin/participantsaction.php:1799 +#: application/controllers/admin/participantsaction.php:1829 msgid "%s entries were not copied because they already existed" msgstr "" -#: application/controllers/admin/participantsaction.php:1759 +#: application/controllers/admin/participantsaction.php:1779 msgid "Attribute values for existing participants have been updated from the token records" msgstr "" -#: application/controllers/admin/participantsaction.php:1776 -#: application/controllers/admin/participantsaction.php:1806 +#: application/controllers/admin/participantsaction.php:1796 +#: application/controllers/admin/participantsaction.php:1826 msgid "%s participants have been copied to the survey token table" msgstr "" -#: application/controllers/admin/participantsaction.php:1783 -#: application/controllers/admin/participantsaction.php:1813 +#: application/controllers/admin/participantsaction.php:1803 +#: application/controllers/admin/participantsaction.php:1833 msgid "Attribute values for existing participants have been updated from the participants records" msgstr "" @@ -3006,8 +3006,8 @@ msgid "Delete" msgstr "" #: application/controllers/admin/surveypermission.php:109 -#: application/controllers/admin/tokens.php:402 -#: application/controllers/admin/tokens.php:479 +#: application/controllers/admin/tokens.php:408 +#: application/controllers/admin/tokens.php:485 #: application/views/admin/assessments_view.php:32 #: application/views/admin/responses/browseidheader_view.php:14 #: application/views/admin/saved/savedlist_view.php:29 @@ -3379,237 +3379,237 @@ msgstr "" msgid "We are sorry but you don't have permissions to do this." msgstr "" -#: application/controllers/admin/tokens.php:394 -#: application/controllers/admin/tokens.php:470 +#: application/controllers/admin/tokens.php:400 +#: application/controllers/admin/tokens.php:476 msgid "Do survey" msgstr "" -#: application/controllers/admin/tokens.php:398 -#: application/controllers/admin/tokens.php:474 +#: application/controllers/admin/tokens.php:404 +#: application/controllers/admin/tokens.php:480 #: application/views/admin/responses/browseallrow_view.php:4 #: application/views/admin/responses/browsetimerow_view.php:4 msgid "View response details" msgstr "" -#: application/controllers/admin/tokens.php:402 -#: application/controllers/admin/tokens.php:479 +#: application/controllers/admin/tokens.php:408 +#: application/controllers/admin/tokens.php:485 msgid "Delete token entry" msgstr "" -#: application/controllers/admin/tokens.php:408 -#: application/controllers/admin/tokens.php:485 +#: application/controllers/admin/tokens.php:414 +#: application/controllers/admin/tokens.php:491 msgid "Send invitation email to this person (if they have not yet been sent an invitation email)" msgstr "" -#: application/controllers/admin/tokens.php:410 -#: application/controllers/admin/tokens.php:487 +#: application/controllers/admin/tokens.php:416 +#: application/controllers/admin/tokens.php:493 msgid "Send reminder email to this person (if they have already received the invitation email)" msgstr "" -#: application/controllers/admin/tokens.php:417 -#: application/controllers/admin/tokens.php:492 +#: application/controllers/admin/tokens.php:423 +#: application/controllers/admin/tokens.php:498 #: application/views/admin/token/tokenform.php:5 msgid "Edit token entry" msgstr "" -#: application/controllers/admin/tokens.php:419 -#: application/controllers/admin/tokens.php:494 +#: application/controllers/admin/tokens.php:425 +#: application/controllers/admin/tokens.php:500 msgid "View this person in the central participants database" msgstr "" -#: application/controllers/admin/tokens.php:596 -#: application/controllers/admin/tokens.php:627 -#: application/controllers/admin/tokens.php:733 -#: application/controllers/admin/tokens.php:838 -#: application/controllers/admin/tokens.php:961 +#: application/controllers/admin/tokens.php:602 +#: application/controllers/admin/tokens.php:633 +#: application/controllers/admin/tokens.php:739 +#: application/controllers/admin/tokens.php:844 +#: application/controllers/admin/tokens.php:972 msgid "%s cannot be empty" msgstr "" -#: application/controllers/admin/tokens.php:849 +#: application/controllers/admin/tokens.php:855 msgid "The token entry was successfully updated." msgstr "" -#: application/controllers/admin/tokens.php:850 -#: application/controllers/admin/tokens.php:1016 +#: application/controllers/admin/tokens.php:856 #: application/controllers/admin/tokens.php:1027 +#: application/controllers/admin/tokens.php:1038 #: application/views/admin/token/addtokenpost.php:7 #: application/views/admin/token/addtokenpost.php:14 #: application/views/admin/token/tokenbar.php:12 msgid "Display tokens" msgstr "" -#: application/controllers/admin/tokens.php:856 -#: application/controllers/admin/tokens.php:1023 +#: application/controllers/admin/tokens.php:862 +#: application/controllers/admin/tokens.php:1034 #: application/views/admin/token/addtokenpost.php:12 #: application/views/admin/token/ldappost.php:5 msgid "Failed" msgstr "" -#: application/controllers/admin/tokens.php:857 +#: application/controllers/admin/tokens.php:863 #: application/views/admin/token/addtokenpost.php:13 msgid "There is already an entry with that exact token in the table. The same token cannot be used in multiple entries." msgstr "" -#: application/controllers/admin/tokens.php:858 +#: application/controllers/admin/tokens.php:864 msgid "Show this token entry" msgstr "" -#: application/controllers/admin/tokens.php:1015 +#: application/controllers/admin/tokens.php:1026 msgid "New dummy tokens were added." msgstr "" -#: application/controllers/admin/tokens.php:1024 +#: application/controllers/admin/tokens.php:1035 msgid "Only %s new dummy tokens were added after %s trials." msgstr "" -#: application/controllers/admin/tokens.php:1025 +#: application/controllers/admin/tokens.php:1036 msgid "Try with a bigger token length." msgstr "" -#: application/controllers/admin/tokens.php:1125 +#: application/controllers/admin/tokens.php:1141 msgid "%s field(s) were successfully added." msgstr "" -#: application/controllers/admin/tokens.php:1126 -#: application/controllers/admin/tokens.php:1177 +#: application/controllers/admin/tokens.php:1142 +#: application/controllers/admin/tokens.php:1193 msgid "Back to attribute field management." msgstr "" -#: application/controllers/admin/tokens.php:1176 +#: application/controllers/admin/tokens.php:1192 msgid "Token attribute descriptions were successfully updated." msgstr "" -#: application/controllers/admin/tokens.php:1369 +#: application/controllers/admin/tokens.php:1390 msgid "Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) delayed: Token is not yet valid." msgstr "" -#: application/controllers/admin/tokens.php:1373 +#: application/controllers/admin/tokens.php:1394 msgid "Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) skipped: Token is not valid anymore." msgstr "" -#: application/controllers/admin/tokens.php:1383 +#: application/controllers/admin/tokens.php:1404 msgid "Invitation sent to:" msgstr "" -#: application/controllers/admin/tokens.php:1388 +#: application/controllers/admin/tokens.php:1409 msgid "Reminder sent to:" msgstr "" -#: application/controllers/admin/tokens.php:1406 +#: application/controllers/admin/tokens.php:1427 msgid "Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) failed. Error Message:" msgstr "" -#: application/controllers/admin/tokens.php:1438 +#: application/controllers/admin/tokens.php:1459 msgid "There were no eligible emails to send. This will be because none satisfied the criteria of:" msgstr "" -#: application/controllers/admin/tokens.php:1439 +#: application/controllers/admin/tokens.php:1460 msgid "having a valid email address" msgstr "" -#: application/controllers/admin/tokens.php:1440 +#: application/controllers/admin/tokens.php:1461 msgid "not having been sent an invitation already" msgstr "" -#: application/controllers/admin/tokens.php:1441 +#: application/controllers/admin/tokens.php:1462 msgid "having already completed the survey" msgstr "" -#: application/controllers/admin/tokens.php:1442 +#: application/controllers/admin/tokens.php:1463 msgid "having a token" msgstr "" -#: application/controllers/admin/tokens.php:1524 +#: application/controllers/admin/tokens.php:1545 msgid "Uploading LDAP Query" msgstr "" -#: application/controllers/admin/tokens.php:1737 +#: application/controllers/admin/tokens.php:1758 msgid "Can't bind to the LDAP directory" msgstr "" -#: application/controllers/admin/tokens.php:1744 +#: application/controllers/admin/tokens.php:1765 msgid "Can't connect to the LDAP directory" msgstr "" -#: application/controllers/admin/tokens.php:2078 -#: application/controllers/admin/tokens.php:2105 +#: application/controllers/admin/tokens.php:2098 +#: application/controllers/admin/tokens.php:2125 msgid "Create tokens" msgstr "" -#: application/controllers/admin/tokens.php:2079 +#: application/controllers/admin/tokens.php:2099 msgid "Clicking 'Yes' will generate tokens for all those in this token list that have not been issued one. Continue?" msgstr "" -#: application/controllers/admin/tokens.php:2096 +#: application/controllers/admin/tokens.php:2116 msgid "Only %s token has been created." msgid_plural "Only %s tokens have been created." msgstr[0] "" msgstr[1] "" -#: application/controllers/admin/tokens.php:2097 +#: application/controllers/admin/tokens.php:2117 msgid "Need %s token." msgid_plural "Need %s tokens." msgstr[0] "" msgstr[1] "" -#: application/controllers/admin/tokens.php:2102 +#: application/controllers/admin/tokens.php:2122 msgid "%s token has been created." msgid_plural "%s tokens have been created." msgstr[0] "" msgstr[1] "" -#: application/controllers/admin/tokens.php:2138 -#: application/controllers/admin/tokens.php:2160 +#: application/controllers/admin/tokens.php:2158 +#: application/controllers/admin/tokens.php:2180 msgid "Delete Tokens Table" msgstr "" -#: application/controllers/admin/tokens.php:2139 +#: application/controllers/admin/tokens.php:2159 msgid "If you delete this table tokens will no longer be required to access this survey." msgstr "" -#: application/controllers/admin/tokens.php:2139 +#: application/controllers/admin/tokens.php:2159 msgid "A backup of this table will be made if you proceed. Your system administrator will be able to access this table." msgstr "" -#: application/controllers/admin/tokens.php:2142 +#: application/controllers/admin/tokens.php:2162 msgid "Delete Tokens" msgstr "" -#: application/controllers/admin/tokens.php:2161 +#: application/controllers/admin/tokens.php:2181 msgid "The tokens table has now been removed and tokens are no longer required to access this survey." msgstr "" -#: application/controllers/admin/tokens.php:2161 +#: application/controllers/admin/tokens.php:2181 msgid "A backup of this table has been made and can be accessed by your system administrator." msgstr "" -#: application/controllers/admin/tokens.php:2206 +#: application/controllers/admin/tokens.php:2226 #: application/views/admin/globalSettings_view.php:10 #: application/views/admin/token/bounce.php:1 #: application/views/admin/token/tokenbar.php:78 msgid "Bounce settings" msgstr "" -#: application/controllers/admin/tokens.php:2207 +#: application/controllers/admin/tokens.php:2227 msgid "Bounce settings have been saved." msgstr "" -#: application/controllers/admin/tokens.php:2280 +#: application/controllers/admin/tokens.php:2300 #: application/views/admin/export/exportresults_view.php:115 #: application/views/admin/token/tokenbar.php:3 #: application/views/admin/token/tokenwarning.php:3 msgid "Token control" msgstr "" -#: application/controllers/admin/tokens.php:2281 +#: application/controllers/admin/tokens.php:2301 msgid "A token table has been created for this survey." msgstr "" -#: application/controllers/admin/tokens.php:2315 +#: application/controllers/admin/tokens.php:2335 msgid "Import old tokens" msgstr "" -#: application/controllers/admin/tokens.php:2316 +#: application/controllers/admin/tokens.php:2336 msgid "A token table has been created for this survey and the old tokens were imported." msgstr "" diff --git a/locale/cs/LC_MESSAGES/cs.mo b/locale/cs/LC_MESSAGES/cs.mo index 44ef55c60b70de021b6bec204daa7e2b17c22004..d4d0a022b50e50fb66dc1c470ca35d956df8ed36 100644 GIT binary patch delta 48420 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 delta 47180 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 From b4727f5baa4ad408ad9ede8dc3de07f231319f61 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 31 Jul 2012 10:11:49 +0300 Subject: [PATCH 22/75] Fixed Issue: Removed obsolete features from add_survey Dev: Removed xss filtering check and email templates --- .../controllers/admin/remotecontrol.php | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index f04538b0349..8ca9c513253 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -251,17 +251,12 @@ public function add_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLang 'format' => $sformat ); - if(Yii::app()->getConfig('filterxsshtml') && Yii::app()->session['USER_RIGHT_SUPERADMIN'] != 1) - $xssfilter = true; - else - $xssfilter = false; - if (!is_null($iSurveyID)) $aInsertData['wishSID'] = $iSurveyID; try { - $iNewSurveyid = Survey::model()->insertNewSurvey($aInsertData, $xssfilter); + $iNewSurveyid = Survey::model()->insertNewSurvey($aInsertData); if (!$iNewSurveyid) return array('status' => 'Creation Failed'); @@ -277,23 +272,11 @@ public function add_survey($sSessionKey, $iSurveyID, $sSurveyTitle, $sSurveyLang $aInsertData = array( 'surveyls_survey_id' => $iNewSurveyid, 'surveyls_title' => $sTitle, - 'surveyls_language' => $sSurveyLanguage, - 'surveyls_email_invite_subj' => $aDefaultTexts['invitation_subject'], - 'surveyls_email_invite' => conditionalNewlineToBreak($aDefaultTexts['invitation'], $bIsHTMLEmail, 'unescaped'), - 'surveyls_email_remind_subj' => $aDefaultTexts['reminder_subject'], - 'surveyls_email_remind' => conditionalNewlineToBreak($aDefaultTexts['reminder'], $bIsHTMLEmail, 'unescaped'), - 'surveyls_email_confirm_subj' => $aDefaultTexts['confirmation_subject'], - 'surveyls_email_confirm' => conditionalNewlineToBreak($aDefaultTexts['confirmation'], $bIsHTMLEmail, 'unescaped'), - 'surveyls_email_register_subj' => $aDefaultTexts['registration_subject'], - 'surveyls_email_register' => conditionalNewlineToBreak($aDefaultTexts['registration'], $bIsHTMLEmail, 'unescaped'), - 'email_admin_notification_subj' => $aDefaultTexts['admin_notification_subject'], - 'email_admin_notification' => conditionalNewlineToBreak($aDefaultTexts['admin_notification'], $bIsHTMLEmail, 'unescaped'), - 'email_admin_responses_subj' => $aDefaultTexts['admin_detailed_notification_subject'], - 'email_admin_responses' => $aDefaultTexts['admin_detailed_notification'] + 'surveyls_language' => $sSurveyLanguage, ); $langsettings = new Surveys_languagesettings; - $langsettings->insertNewSurvey($aInsertData, $xssfilter); + $langsettings->insertNewSurvey($aInsertData); Survey_permissions::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'], $iNewSurveyid); return $iNewSurveyid; From 07cb8eb282accbcafc0c1a71a554f4143511cc0d Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 31 Jul 2012 13:01:48 +0300 Subject: [PATCH 23/75] Fixed Issue: Change get and set functions(Survey,Group,Question,Tokens) invalid properties check Dev: Simplify the way get functions aquire properties Dev: Removed excess check for invalid fields Dev: Provide actual result in set functions return --- .../controllers/admin/remotecontrol.php | 238 ++++++++---------- 1 file changed, 110 insertions(+), 128 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 8ca9c513253..ee936059682 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -368,8 +368,8 @@ public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) { return array('status' => 'Error: Invalid survey ID'); } @@ -377,20 +377,13 @@ public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) { $aBasicDestinationFields=Survey::model()->tableSchema->columnNames; $aSurveySettings=array_intersect($aSurveySettings,$aBasicDestinationFields); - - $aBasicAttributes = Survey::model()->findByPk($iSurveyID)->getAttributes(); - - $aResult = array(); - + if (empty($aSurveySettings)) - return array('status' => 'No valid Data'); - + return array('status' => 'No valid Data'); + $aResult = array(); foreach($aSurveySettings as $sPropertyName) { - if (isset($aBasicAttributes[$sPropertyName])) - $aResult[$sPropertyName]=$aBasicAttributes[$sPropertyName]; - else - $aResult[$sPropertyName]='Not available'; + $aResult[$sPropertyName]=$oSurvey->$sPropertyName; } return $aResult; } @@ -429,8 +422,9 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) $aDestinationFields=array_flip(Survey::model()->tableSchema->columnNames); $aSurveyData=array_intersect_key($aSurveyData,$aDestinationFields); $oSurvey=Survey::model()->findByPk($iSurveyID); - $aSucceded = array(); - $aFailed = array(); + $aBasicAttributes = $oSurvey->getAttributes(); + $aResult = array(); + if ($oSurvey->active=='Y') { // remove all fields that may not be changed when a survey is active @@ -439,7 +433,6 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) unset($aSurveyData['savetimings']); unset($aSurveyData['ipaddr']); unset($aSurveyData['refurl']); - } if (empty($aSurveyData)) @@ -447,21 +440,22 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) foreach($aSurveyData as $sFieldName=>$sValue) { - - $oSurvey->$sFieldName=$sValue; - $aSucceded[$sFieldName]=$sValue; - - } - try - { - $oSurvey->save(); // save the change to database - $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); - return $aResult; - } - catch(Exception $e) - { - return array('status' => 'Error'); + $oSurvey->$sFieldName=$sValue; + try + { + $bSaveResult=$oSurvey->save(); // save the change to database + //unset the value if it fails, so as to prevent future fails + $aResult[$sFieldName]=$bSaveResult; + if (!$bSaveResult) + $oSurvey->$sFieldName=$aBasicAttributes[$sFieldName]; + } + catch(Exception $e) + { + //unset the value that caused the exception + $oSurvey->$sFieldName=$aBasicAttributes[$sFieldName]; + } } + return $aResult; } else return array('status' => 'No permission'); @@ -844,24 +838,21 @@ public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleS Yii::app()->loadHelper("surveytranslator"); if ($this->_checkSessionKey($sSessionKey)) { - $surveyidExists = Survey::model()->findByPk($iSurveyID); - if (!isset($surveyidExists)) + $oSurvey = Survey::model()->findByPk($iSurveyID); + if (!isset($oSurvey)) { return array('status' => 'Error: Invalid survey ID'); } if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) { $aBasicDestinationFields=Surveys_languagesettings::model()->tableSchema->columnNames; - $aSurveyLocaleSettings=array_intersect($aSurveyLocaleSettings,$aBasicDestinationFields); - $aBasicAttributes = Survey::model()->findByPk($iSurveyID)->getAttributes(); - if ($sLang == NULL || !array_key_exists($sLang,getLanguageDataRestricted())) - $sLang = $aBasicAttributes['language']; - - $aLangAttributes = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLang))->getAttributes(); + $sLang = $oSurvey->language; + + $oSurveyLocale=Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLang)); $aResult = array(); if (empty($aSurveyLocaleSettings)) @@ -869,10 +860,8 @@ public function get_language_properties($sSessionKey,$iSurveyID, $aSurveyLocaleS foreach($aSurveyLocaleSettings as $sPropertyName) { - if (isset($aLangAttributes[$sPropertyName])) - $aResult[$sPropertyName]=$aLangAttributes[$sPropertyName]; - else - $aResult[$sPropertyName]='Not available'; + $aResult[$sPropertyName]=$oSurveyLocale->$sPropertyName; + //$aResult[$sPropertyName]=$aLangAttributes[$sPropertyName]; } return $aResult; } @@ -923,29 +912,31 @@ public function set_language_properties($sSessionKey, $iSurveyID, $aSurveyLocale $aSurveyLocaleData=array_intersect_key($aSurveyLocaleData,$aDestinationFields); $oSurveyLocale = Surveys_languagesettings::model()->findByPk(array('surveyls_survey_id' => $iSurveyID, 'surveyls_language' => $sLanguage)); - $aSucceded = array(); - $aFailed = array(); + + $aLangAttributes = $oSurveyLocale->getAttributes(); + $aResult = array(); if (empty($aSurveyLocaleData)) return array('status' => 'No valid Data'); foreach($aSurveyLocaleData as $sFieldName=>$sValue) { - - $oSurveyLocale->$sFieldName=$sValue; - $aSucceded[$sFieldName]=$sValue; - - } - try - { - $oSurveyLocale->save(); // save the change to database - $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); - return $aResult; - } - catch(Exception $e) - { - return array('status' => 'Error'); + $oSurveyLocale->$sFieldName=$sValue; + try + { + // save the change to database - Every single change alone - to allow for validation to work + $bSaveResult=$oSurveyLocale->save(); + $aResult[$sFieldName]=$bSaveResult; + //unset failed values + if (!$bSaveResult) + $oSurveyLocale->$sFieldName=$aLangAttributes[$sFieldName]; + } + catch(Exception $e) + { + $oSurveyLocale->$sFieldName=$aLangAttributes[$sFieldName]; + } } + return $aResult; } else return array('status' => 'No permission'); @@ -1152,18 +1143,13 @@ public function get_group_properties($sSessionKey, $iGroupID, $aGroupSettings) $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); if (hasSurveyPermission($oGroup->sid, 'survey', 'read')) - { - $aBasicAttributes = $oGroup ->getAttributes(); - + { if (empty($aGroupSettings)) return array('status' => 'No valid Data'); foreach($aGroupSettings as $sGroupSetting) { - if (isset($aBasicAttributes[$sGroupSetting])) - $aResult[$sGroupSetting]=$aBasicAttributes[$sGroupSetting]; - else - $aResult[$sGroupSetting]='Data not available'; + $aResult[$sGroupSetting] = $oGroup->$sGroupSetting; } return $aResult; } @@ -1195,21 +1181,19 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) } if (hasSurveyPermission($oGroup->sid, 'survey', 'update')) { - $aSucceded = array(); - $aFailed = array(); + $aResult = array(); // Remove fields that may not be modified unset($aGroupData['sid']); unset($aGroupData['gid']); // Remove invalid fields $aDestinationFields=array_flip(Groups::model()->tableSchema->columnNames); $aGroupData=array_intersect_key($aGroupData,$aDestinationFields); - + $aGroupAttributes = $oGroup->getAttributes(); if (empty($aGroupData)) return array('status' => 'No valid Data'); foreach($aGroupData as $sFieldName=>$sValue) { - //all dependencies this group has $has_dependencies=getGroupDepsForConditions($oGroup->sid,$iGroupID); //all dependencies on this group @@ -1220,22 +1204,25 @@ public function set_group_properties($sSessionKey, $iGroupID, $aGroupData) $aFailed[$sFieldName]='Group with dependencies - Order cannot be changed'; else { - $oGroup->setAttribute($sFieldName,$sValue); - $aSucceded[$sFieldName]=$sValue; - } - - } - try - { - $oGroup->save(); // save the change to database - fixSortOrderGroups($oGroup->sid); - $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); - return $aResult; - } - catch(Exception $e) - { - return array('status' => 'Error'); + $oGroup->setAttribute($sFieldName,$sValue); + } + try + { + // save the change to database - one by one to allow for validation to work + $bSaveResult=$oGroup->save(); + fixSortOrderGroups($oGroup->sid); + $aResult[$sFieldName] = $bSaveResult; + //unset failed values + if (!$bSaveResult) + $oGroup->$sFieldName=$aGroupAttributes[$sFieldName]; + } + catch(Exception $e) + { + //unset values that cause exception + $oGroup->$sFieldName=$aGroupAttributes[$sFieldName]; + } } + return $aResult; } else return array('status' => 'No permission'); @@ -1475,8 +1462,7 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe return array('status' => 'No valid Data'); if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) - { - $aBasicAttributes = $oQuestion->getAttributes(); + { $aResult=array(); foreach ($aQuestionSettings as $sPropertyName ) { @@ -1494,12 +1480,8 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe $aResult['available_answers']='No available answers'; } else - { - if (isset($aBasicAttributes[$sPropertyName])) - $aResult[$sPropertyName]=$aBasicAttributes[$sPropertyName]; - else - $aResult[$sPropertyName]='Data not available'; - + { + $aResult[$sPropertyName]=$oQuestion->$sPropertyName; } } return $aResult; @@ -1529,9 +1511,7 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa return array('status' => 'Error: Invalid group ID'); if (hasSurveyPermission($oQuestion->sid, 'survey', 'update')) - { - $aSucceded = array(); - $aFailed = array(); + { // Remove fields that may not be modified unset($aQuestionData['qid']); unset($aQuestionData['gid']); @@ -1542,6 +1522,7 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa // Remove invalid fields $aDestinationFields=array_flip(Questions::model()->tableSchema->columnNames); $aQuestionData=array_intersect_key($aQuestionData,$aDestinationFields); + $aQuestionAttributes = $oQuestion->getAttributes(); if (empty($aQuestionData)) return array('status' => 'No valid Data'); @@ -1560,21 +1541,24 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa else { $oQuestion->setAttribute($sFieldName,$sValue); - $aSucceded[$sFieldName]=$sValue; - } - - } - try - { - $oQuestion->save(); // save the change to database - fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); - $aResult = array('succeded'=>$aSucceded,'failed'=>$aFailed); - return $aResult; - } - catch(Exception $e) - { - return array('status' => 'Error'); + } + + try + { + $bSaveResult=$oQuestion->save(); // save the change to database + fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); + $aResult[$sFieldName]=$bSaveResult; + //unset fields that failed + if (!$bSaveResult) + $oQuestion->$sFieldName=$aQuestionAttributes[$sFieldName]; + } + catch(Exception $e) + { + //unset fields that caused exception + $oQuestion->$sFieldName=$aQuestionAttributes[$sFieldName]; + } } + return $aResult; } else return array('status' => 'No permission'); @@ -1776,17 +1760,13 @@ public function get_participant_properties($sSessionKey, $iSurveyID, $iTokenID, $aResult=array(); $aBasicDestinationFields=Tokens_dynamic::model()->tableSchema->columnNames; $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); - $aBasicAttributes = $oToken->getAttributes(); if (empty($aTokenProperties)) return array('status' => 'No valid Data'); foreach($aTokenProperties as $sPropertyName ) { - if (isset($aBasicAttributes[$sPropertyName])) - $aResult[$sPropertyName]=$aBasicAttributes[$sPropertyName]; - else - $aResult[$sPropertyName]='Data not available'; + $aResult[$sPropertyName]=$oToken->$sPropertyName; } return $aResult; } @@ -1824,13 +1804,13 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, if (!isset($oToken)) return array('status' => 'Error: Invalid tokenid'); - $aSucceded = array(); - $aFailed = array(); + $aResult = array(); // Remove fields that may not be modified unset($aTokenData['tid']); $aBasicDestinationFields=array_flip(Tokens_dynamic::model()->tableSchema->columnNames); $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); + $aTokenAttributes = $oToken->getAttributes(); if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) { @@ -1839,19 +1819,21 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, foreach($aTokenData as $sFieldName=>$sValue) { - $oToken->$sFieldName=$sValue; - $aSucceded[$sFieldName]=$sValue; + $oToken->$sFieldName=$sValue; + try + { + $bSaveResult=$oToken->save(); + $aResult[$sFieldName]=$bSaveResult; + //unset fields that failed + if (!$bSaveResult) + $oToken->$sFieldName=$aTokenAttributes[$sFieldName]; + } + catch(Exception $e) + { + $oToken->$sFieldName=$aTokenAttributes[$sFieldName]; + } } - try - { - $oToken->save(); - $result = array('succeded'=>$aSucceded,'failed'=>$aFailed); - return $result; - } - catch(Exception $e) - { - return array('status' => 'Error'); - } + return $aResult; } else return array('status' => 'No permission'); From 0ed600016e41290118e2fb7703b908d296824341 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 31 Jul 2012 13:41:12 +0300 Subject: [PATCH 24/75] Fixed Issue : Remove obsolete RevertUpgradeConditionsToRelevance in delete_group Dev: Added check for groups with dependencies --- application/controllers/admin/remotecontrol.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index ee936059682..40aa56733e6 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1018,17 +1018,18 @@ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) return array('status' => 'Error:Survey is active and not editable'); if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) - { - LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); + { + $depented_on = getGroupDepsForConditions($oGroup->sid,"all",$iGroupID,"by-targgid"); + if(isset($depented_on)) + return array('status' => 'Group with depencdencies - deletion not allowed'); + $iGroupsDeleted = Groups::deleteWithDependency($iGroupID, $iSurveyID); - - if ($iGroupsDeleted === 1) - fixSortOrderGroups($iSurveyID); - - LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); if ($iGroupsDeleted === 1) + { + fixSortOrderGroups($iSurveyID); return $iGroupID; + } else return array('status' => 'Group deletion failed'); } From 20a69d62283320d54d9012bce62c67c98322743e Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 31 Jul 2012 15:16:57 +0300 Subject: [PATCH 25/75] Fixed Issue : Fixed error messages and functionality in list_surveys Dev: User gets message when he has no permission to list surveys Dev: Superuser now can list all surveys (besides certain users) Dev: Minor fix in Survey model --- .../controllers/admin/remotecontrol.php | 61 ++++++++++++------- application/models/Survey.php | 4 +- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 40aa56733e6..3d216850206 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -467,46 +467,65 @@ public function set_survey_properties($sSessionKey, $iSurveyID, $aSurveyData) /** * RPC Routine to list the ids and info of surveys belonging to a user. * Returns array of ids and info. - * If user is admin he can get surveys of every user (parameter sUser) - * else only the syrveys belonging to the user requesting will be shown. + * If user is admin he can get surveys of every user (parameter sUser) or all surveys (sUser=null) + * Else only the syrveys belonging to the user requesting will be shown. * * @access public * @param string $sSessionKey Auth credentials - * @param string $suser Optional username to get list of surveys + * @param string $sUser Optional username to get list of surveys * @return array The list of surveys */ - public function list_surveys($sSessionKey, $suser='') + public function list_surveys($sSessionKey, $sUser=NULL) { if ($this->_checkSessionKey($sSessionKey)) { - $current_user = Yii::app()->session['user']; - if( Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1 and $suser !='') - $current_user = $suser; - - $aUserData = User::model()->findByAttributes(array('users_name' => $current_user)); - if (!isset($aUserData)) - return array('status' => 'Invalid user'); - - $aUserSurveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); - if(count($aUserSurveys)==0) - return array('status' => 'No surveys found'); + $sCurrentUser = Yii::app()->session['user']; + + if( Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1) + { + if ($sUser == null) + $aUserSurveys = Survey::model()->findAll(); //list all surveys + else + { + $aUserData = User::model()->findByAttributes(array('users_name' => $sUser)); + if (!isset($aUserData)) + return array('status' => 'Invalid user'); + else + $aUserSurveys = Survey::model()->findAllByAttributes(array("owner_id"=>$aUserData->attributes['uid'])); + } + } + else + { + if (($sCurrentUser == $sUser) || ($sUser == null) ) + { + $sUid = User::model()->findByAttributes(array('users_name' => $sCurrentUser))->uid; + $aUserSurveys = Survey::model()->findAllByAttributes(array("owner_id"=>$sUid)); + } + else + return array('status' => 'No permission'); + } - foreach ($aUserSurveys as $aSurvey) + if(count($aUserSurveys)==0) + return array('status' => 'No surveys found'); + + foreach ($aUserSurveys as $oSurvey) { - $aSurveyLanguageSettings = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $aSurvey->primaryKey, 'surveyls_language' => $aSurvey->language)); - if (!isset($aSurveyLanguageSettings)) + $oSurveyLanguageSettings = Surveys_languagesettings::model()->findByAttributes(array('surveyls_survey_id' => $oSurvey->primaryKey, 'surveyls_language' => $oSurvey->language)); + if (!isset($oSurveyLanguageSettings)) $aSurveyTitle = ''; else - $aSurveyTitle = $aSurveyLanguageSettings->attributes['surveyls_title']; - $aData[]= array('sid'=>$aSurvey->primaryKey,'surveyls_title'=>$aSurveyTitle,'startdate'=>$aSurvey->attributes['startdate'],'expires'=>$aSurvey->attributes['expires'],'active'=>$aSurvey->attributes['active']); + $aSurveyTitle = $oSurveyLanguageSettings->attributes['surveyls_title']; + $aData[]= array('sid'=>$oSurvey->primaryKey,'surveyls_title'=>$aSurveyTitle,'startdate'=>$oSurvey->attributes['startdate'],'expires'=>$oSurvey->attributes['expires'],'active'=>$oSurvey->attributes['active']); } - return $aData; + return $aData; } else return array('status' => 'Invalid session key'); } + + /** * RPC Routine that launches a newly created survey. * diff --git a/application/models/Survey.php b/application/models/Survey.php index 83b2fe60587..4554718bb5e 100644 --- a/application/models/Survey.php +++ b/application/models/Survey.php @@ -97,7 +97,7 @@ public function rules() array('bounce_email', 'xssfilter'), array('faxto', 'xssfilter'), array('active', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), - array('anonymized', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), + array('anonymized', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), array('savetimings', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), array('datestamp', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), array('usecookie', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), @@ -172,7 +172,7 @@ public function xssfilter($attribute,$params) public function tmplfilter($attribute,$params) { if(!array_key_exists($this->$attribute,getTemplateList())) - $this->addError($attribute, 'Invalid template!'); + $this->$attribute = 'default'; } From 9d47f377d1804f203276cdbc5aae1c26ec50cd99 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Tue, 31 Jul 2012 15:22:57 +0300 Subject: [PATCH 26/75] Fixed Issue: Fix wrong function descriptions --- application/controllers/admin/remotecontrol.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 3d216850206..2b1ead15b4b 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1642,7 +1642,7 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) /** - * RPC Routine to add a participant to the tokens placeholder of the survey. + * RPC Routine to add participants to the tokens collection of the survey. * Returns the inserted data including additional new information like the Token entry ID and the token string. * * @access public @@ -1916,7 +1916,7 @@ public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) } /** - * RPC routine to to initialise the survey's placeholder where new participant tokens may be later added. + * RPC routine to to initialise the survey's collection of tokens where new participant tokens may be later added. * * @access public * @param string $sSessionKey Auth credentials From 2dcf19a7b86cf0439c4b3717530448cff6713603 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 31 Jul 2012 16:58:48 +0200 Subject: [PATCH 27/75] Fixed issue #6410: No options for some location atributes --- application/controllers/admin/question.php | 2 +- .../Question/advanced_settings_view.php | 86 +++++++++---------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/application/controllers/admin/question.php b/application/controllers/admin/question.php index 3a50ce21464..da09d63fb42 100644 --- a/application/controllers/admin/question.php +++ b/application/controllers/admin/question.php @@ -944,7 +944,7 @@ public function ajaxquestionattributes() } } } - + $aData['bIsActive'] = ($thissurvey['active']=='Y'); $aData['attributedata'] = $aAttributesPrepared; $this->getController()->render('/admin/survey/Question/advanced_settings_view', $aData); } diff --git a/application/views/admin/survey/Question/advanced_settings_view.php b/application/views/admin/survey/Question/advanced_settings_view.php index 327cfcbd2b5..0b1053ab4c4 100644 --- a/application/views/admin/survey/Question/advanced_settings_view.php +++ b/application/views/admin/survey/Question/advanced_settings_view.php @@ -1,55 +1,55 @@ $aAttribute) { if ($currentfieldset!=$aAttribute['category']) { if ($currentfieldset!='') {?> - -
- -
    - -
  • - - "; - foreach($aAttribute['options'] as $sOptionvalue=>$sOptiontext) - { - echo ""; - } - echo ""; - break; - case 'text':?> ' name='' value='' /> - ' name='' value='' /> - - +
    + +
      + +
    • + + "; + foreach($aAttribute['options'] as $sOptionvalue=>$sOptiontext) + { + echo ""; + } + echo ""; + break; + case 'text':?> ' name='' value='' /> + ' name='' value='' /> + +
    • - +
    From 7c7ba0c8f789d21792643d383371ff00a0f986a3 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 1 Aug 2012 11:07:00 +0300 Subject: [PATCH 28/75] Fixed Issue: Move hasSurveyPermission higher to avoid not needed calls --- .../controllers/admin/remotecontrol.php | 178 +++++++++--------- 1 file changed, 90 insertions(+), 88 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 2b1ead15b4b..b1ba5abdcce 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -372,7 +372,7 @@ public function get_survey_properties($sSessionKey,$iSurveyID, $aSurveySettings) if (!isset($oSurvey)) { return array('status' => 'Error: Invalid survey ID'); - } + } if (hasSurveyPermission($iSurveyID, 'surveysettings', 'read')) { $aBasicDestinationFields=Survey::model()->tableSchema->columnNames; @@ -660,23 +660,24 @@ public function get_summary($sSessionKey,$iSurveyID, $sStatName) $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) return array('status' => 'Invalid surveyid'); - - if(in_array($sStatName, $aPermittedTokenStats)) - { - if (tableExists('{{tokens_' . $iSurveyID . '}}')) - $summary = Tokens_dynamic::model($iSurveyID)->summary(); - else - return array('status' => 'No available data'); - } - - if(in_array($sStatName, $aPermittedSurveyStats) && !tableExists('{{survey_' . $iSurveyID . '}}')) - return array('status' => 'No available data'); - - if (!in_array($sStatName, $aPermittedStats)) - return array('status' => 'No such property'); if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { + if(in_array($sStatName, $aPermittedTokenStats)) + { + if (tableExists('{{tokens_' . $iSurveyID . '}}')) + $summary = Tokens_dynamic::model($iSurveyID)->summary(); + else + return array('status' => 'No available data'); + } + + if(in_array($sStatName, $aPermittedSurveyStats) && !tableExists('{{survey_' . $iSurveyID . '}}')) + return array('status' => 'No available data'); + + if (!in_array($sStatName, $aPermittedStats)) + return array('status' => 'No such property'); + + switch($sStatName) { case 'token_count': @@ -1029,15 +1030,15 @@ public function delete_group($sSessionKey, $iSurveyID, $iGroupID) if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($oGroup)) - return array('status' => 'Error: Invalid group ID'); - - if($oSurvey['active']=='Y') - return array('status' => 'Error:Survey is active and not editable'); - if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) - { + { + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($oGroup)) + return array('status' => 'Error: Invalid group ID'); + + if($oSurvey['active']=='Y') + return array('status' => 'Error:Survey is active and not editable'); + $depented_on = getGroupDepsForConditions($oGroup->sid,"all",$iGroupID,"by-targgid"); if(isset($depented_on)) return array('status' => 'Group with depencdencies - deletion not allowed'); @@ -1078,13 +1079,13 @@ public function import_group($sSessionKey, $iSurveyID, $sImportData, $sImportDat { $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) - return array('status' => 'Error: Invalid survey ID'); - - if($oSurvey->getAttribute('active') =='Y') - return array('status' => 'Error:Survey is aCctive and not editable'); + return array('status' => 'Error: Invalid survey ID'); if (hasSurveyPermission($iSurveyID, 'survey', 'update')) { + if($oSurvey->getAttribute('active') =='Y') + return array('status' => 'Error:Survey is active and not editable'); + if (!in_array($sImportDataType,array('csv','lsg'))) return array('status' => 'Invalid extension'); libxml_use_internal_errors(true); Yii::app()->loadHelper('admin/import'); @@ -1158,12 +1159,12 @@ public function get_group_properties($sSessionKey, $iGroupID, $aGroupSettings) $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); if (!isset($oGroup)) return array('status' => 'Error: Invalid group ID'); - - $aBasicDestinationFields=Groups::model()->tableSchema->columnNames; - $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); - + if (hasSurveyPermission($oGroup->sid, 'survey', 'read')) { + $aBasicDestinationFields=Groups::model()->tableSchema->columnNames; + $aGroupSettings=array_intersect($aGroupSettings,$aBasicDestinationFields); + if (empty($aGroupSettings)) return array('status' => 'No valid Data'); @@ -1304,20 +1305,20 @@ public function delete_question($sSessionKey, $iQuestionID) { if ($this->_checkSessionKey($sSessionKey)) { - $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); if (!isset($oQuestion)) return array('status' => 'Error: Invalid question ID'); $iSurveyID = $oQuestion['sid']; - $oSurvey = Survey::model()->findByPk($iSurveyID); - - if($oSurvey['active']=='Y') - return array('status' => 'Survey is active and not editable'); - $iGroupID=$oQuestion['gid']; - + if (hasSurveyPermission($iSurveyID, 'surveycontent', 'delete')) { + $oSurvey = Survey::model()->findByPk($iSurveyID); + + if($oSurvey['active']=='Y') + return array('status' => 'Survey is active and not editable'); + $iGroupID=$oQuestion['gid']; + $oCondition = Conditions::model()->findAllByAttributes(array('cqid' => $iQuestionID)); if(count($oCondition)>0) return array('status' => 'Cannot delete Question. Others rely on this question'); @@ -1378,19 +1379,21 @@ public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - if($oSurvey->getAttribute('active') =='Y') - return array('status' => 'Error:Survey is Active and not editable'); - - $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); - if (!isset($oGroup)) - return array('status' => 'Error: Invalid group ID'); - - $sGroupSurveyID = $oGroup['sid']; - if($sGroupSurveyID != $iSurveyID) - return array('status' => 'Error: Missmatch in surveyid and groupid'); + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) { + if($oSurvey->getAttribute('active') =='Y') + return array('status' => 'Error:Survey is Active and not editable'); + + $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); + if (!isset($oGroup)) + return array('status' => 'Error: Invalid group ID'); + + $sGroupSurveyID = $oGroup['sid']; + if($sGroupSurveyID != $iSurveyID) + return array('status' => 'Error: Missmatch in surveyid and groupid'); + if (!in_array($sImportDataType,array('csv','lsq'))) return array('status' => 'Invalid extension'); libxml_use_internal_errors(true); Yii::app()->loadHelper('admin/import'); @@ -1473,16 +1476,16 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); if (!isset($oQuestion)) return array('status' => 'Error: Invalid questionid', 22); - - $aBasicDestinationFields=Questions::model()->tableSchema->columnNames; - array_push($aBasicDestinationFields,'available_answers') ; - $aQuestionSettings=array_intersect($aQuestionSettings,$aBasicDestinationFields); - - if (empty($aQuestionSettings)) - return array('status' => 'No valid Data'); if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) { + $aBasicDestinationFields=Questions::model()->tableSchema->columnNames; + array_push($aBasicDestinationFields,'available_answers') ; + $aQuestionSettings=array_intersect($aQuestionSettings,$aBasicDestinationFields); + + if (empty($aQuestionSettings)) + return array('status' => 'No valid Data'); + $aResult=array(); foreach ($aQuestionSettings as $sPropertyName ) { @@ -1719,12 +1722,12 @@ public function delete_participants($sSessionKey, $iSurveyID, $aTokenIDs) $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - + if (hasSurveyPermission($iSurveyID, 'tokens', 'delete')) { + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + $aResult=array(); foreach($aTokenIDs as $iTokenID) { @@ -1766,17 +1769,17 @@ public function get_participant_properties($sSessionKey, $iSurveyID, $iTokenID, { $surveyidExists = Survey::model()->findByPk($iSurveyID); if (!isset($surveyidExists)) - return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - - $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); - if (!isset($oToken)) - return array('status' => 'Error: Invalid tokenid'); + return array('status' => 'Error: Invalid survey ID'); if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) - { + { + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($oToken)) + return array('status' => 'Error: Invalid tokenid'); + $aResult=array(); $aBasicDestinationFields=Tokens_dynamic::model()->tableSchema->columnNames; $aTokenProperties=array_intersect($aTokenProperties,$aBasicDestinationFields); @@ -1812,28 +1815,27 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, { if ($this->_checkSessionKey($sSessionKey)) { - $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - - $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); - if (!isset($oToken)) - return array('status' => 'Error: Invalid tokenid'); - - $aResult = array(); - // Remove fields that may not be modified - unset($aTokenData['tid']); - - $aBasicDestinationFields=array_flip(Tokens_dynamic::model()->tableSchema->columnNames); - $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); - $aTokenAttributes = $oToken->getAttributes(); - if (hasSurveyPermission($iSurveyID, 'tokens', 'update')) { + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + + $oToken = Tokens_dynamic::model($iSurveyID)->findByPk($iTokenID); + if (!isset($oToken)) + return array('status' => 'Error: Invalid tokenid'); + + $aResult = array(); + // Remove fields that may not be modified + unset($aTokenData['tid']); + + $aBasicDestinationFields=array_flip(Tokens_dynamic::model()->tableSchema->columnNames); + $aTokenData=array_intersect_key($aTokenData,$aBasicDestinationFields); + $aTokenAttributes = $oToken->getAttributes(); + if (empty($aTokenData)) return array('status' => 'No valid Data'); @@ -1881,12 +1883,12 @@ public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); - - if(!tableExists("{{tokens_$iSurveyID}}")) - return array('status' => 'Error: No token table'); - + if (hasSurveyPermission($iSurveyID, 'tokens', 'read')) { + if(!tableExists("{{tokens_$iSurveyID}}")) + return array('status' => 'Error: No token table'); + if($bUnused) $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); else From 8fbf9c977ffec64e36f33a5d2c3785e819578291 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 1 Aug 2012 12:36:55 +0300 Subject: [PATCH 29/75] Fixed issue : Fix get_question_properties, set_question_properties, list_questions to take into account multilingual questions --- .../controllers/admin/remotecontrol.php | 108 ++++++++++++------ 1 file changed, 71 insertions(+), 37 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index b1ba5abdcce..1a64228c02e 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1466,19 +1466,32 @@ public function import_question($sSessionKey, $iSurveyID,$iGroupID, $sImportData * @param string $sSessionKey Auth credentials * @param int $iQuestionID Id of the question to get properties * @param array $aQuestionSettings The properties to get + * @param string $sLanguage Optional parameter language for multilingual questions * @return array The requested values */ - public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSettings) + public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSettings, $sLanguage=NULL) { - if ($this->_checkSessionKey($sSessionKey)) { + Yii::app()->loadHelper("surveytranslator"); $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID)); if (!isset($oQuestion)) - return array('status' => 'Error: Invalid questionid', 22); - - if (hasSurveyPermission($oQuestion->sid, 'survey', 'read')) + return array('status' => 'Error: Invalid questionid'); + + $iSurveyID = $oQuestion->sid; + + if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { + if (is_null($sLanguage)) + $sLanguage=Survey::model()->findByPk($iSurveyID)->language; + + if (!array_key_exists($sLanguage,getLanguageDataRestricted())) + return array('status' => 'Error: Invalid language'); + + $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID, 'language'=>$sLanguage)); + if (!isset($oQuestion)) + return array('status' => 'Error: Invalid questionid'); + $aBasicDestinationFields=Questions::model()->tableSchema->columnNames; array_push($aBasicDestinationFields,'available_answers') ; $aQuestionSettings=array_intersect($aQuestionSettings,$aBasicDestinationFields); @@ -1491,7 +1504,7 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe { if ($sPropertyName == 'available_answers') { - $oSubQuestions = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID),array('order'=>'title') ); + $oSubQuestions = Questions::model()->findAllByAttributes(array('parent_qid' => $iQuestionID,'language'=>$sLanguage ),array('order'=>'title') ); if (count($oSubQuestions)>0) { foreach($oSubQuestions as $oSubQuestion) @@ -1523,18 +1536,32 @@ public function get_question_properties($sSessionKey, $iQuestionID, $aQuestionSe * @param string $sSessionKey Auth credentials * @param integer $iQuestionID - ID of the question * @param array|struct $aQuestionData - An array with the particular fieldnames as keys and their values to set on that particular question + * @param string $sLanguage Optional parameter language for multilingual questions * @return array Of succeeded and failed modifications according to internal validation. */ - public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionData) + public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionData,$sLanguage=NULL) { if ($this->_checkSessionKey($sSessionKey)) { + Yii::app()->loadHelper("surveytranslator"); $oQuestion=Questions::model()->findByAttributes(array('qid' => $iQuestionID)); if (is_null($oQuestion)) return array('status' => 'Error: Invalid group ID'); + + $iSurveyID = $oQuestion->sid; - if (hasSurveyPermission($oQuestion->sid, 'survey', 'update')) + if (hasSurveyPermission($iSurveyID, 'survey', 'update')) { + if (is_null($sLanguage)) + $sLanguage=Survey::model()->findByPk($iSurveyID)->language; + + if (!array_key_exists($sLanguage,getLanguageDataRestricted())) + return array('status' => 'Error: Invalid language'); + + $oQuestion = Questions::model()->findByAttributes(array('qid' => $iQuestionID, 'language'=>$sLanguage)); + if (!isset($oQuestion)) + return array('status' => 'Error: Invalid questionid'); + // Remove fields that may not be modified unset($aQuestionData['qid']); unset($aQuestionData['gid']); @@ -1552,34 +1579,33 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa foreach($aQuestionData as $sFieldName=>$sValue) { - - //all the dependencies that this question has to other questions - $dependencies=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,$iQuestionID); - //all dependencies by other questions to this question - $is_criteria_question=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,"all",$iQuestionID,"by-targqid"); - //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies + //all the dependencies that this question has to other questions + $dependencies=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,$iQuestionID); + //all dependencies by other questions to this question + $is_criteria_question=getQuestDepsForConditions($oQuestion->sid,$oQuestion->gid,"all",$iQuestionID,"by-targqid"); + //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies + + if((isset($dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') + $aFailed[$sFieldName]='Questions with dependencies - Order cannot be changed'; + else + { + $oQuestion->setAttribute($sFieldName,$sValue); + } - if((isset($dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') - $aFailed[$sFieldName]='Questions with dependencies - Order cannot be changed'; - else - { - $oQuestion->setAttribute($sFieldName,$sValue); - } - - try - { - $bSaveResult=$oQuestion->save(); // save the change to database - fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); - $aResult[$sFieldName]=$bSaveResult; - //unset fields that failed - if (!$bSaveResult) - $oQuestion->$sFieldName=$aQuestionAttributes[$sFieldName]; - } - catch(Exception $e) - { - //unset fields that caused exception + try + { + $bSaveResult=$oQuestion->save(); // save the change to database + fixSortOrderQuestions($oQuestion->gid, $oQuestion->sid); + $aResult[$sFieldName]=$bSaveResult; + //unset fields that failed + if (!$bSaveResult) $oQuestion->$sFieldName=$aQuestionAttributes[$sFieldName]; - } + } + catch(Exception $e) + { + //unset fields that caused exception + $oQuestion->$sFieldName=$aQuestionAttributes[$sFieldName]; + } } return $aResult; } @@ -1599,18 +1625,26 @@ public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionDa * @param string $sSessionKey Auth credentials * @param int $iSurveyID Id of the survey to list questions * @param int $iGroupID Optional id of the group to list questions + * @param string $sLanguage Optional parameter language for multilingual questions * @return array The list of questions */ - public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) + public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL, $sLanguage=NULL) { if ($this->_checkSessionKey($sSessionKey)) { + Yii::app()->loadHelper("surveytranslator"); $oSurvey = Survey::model()->findByPk($iSurveyID); if (!isset($oSurvey)) return array('status' => 'Error: Invalid survey ID'); if (hasSurveyPermission($iSurveyID, 'survey', 'read')) { + if (is_null($sLanguage)) + $sLanguage=$oSurvey->language; + + if (!array_key_exists($sLanguage,getLanguageDataRestricted())) + return array('status' => 'Error: Invalid language'); + if($iGroupID!=NULL) { $oGroup = Groups::model()->findByAttributes(array('gid' => $iGroupID)); @@ -1619,10 +1653,10 @@ public function list_questions($sSessionKey, $iSurveyID, $iGroupID=NULL) if($sGroupSurveyID != $iSurveyID) return array('status' => 'Error: IMissmatch in surveyid and groupid'); else - $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID, "gid"=>$iGroupID,"parent_qid"=>"0")); + $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID, "gid"=>$iGroupID,"parent_qid"=>"0","language"=>$sLanguage)); } else - $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID,"parent_qid"=>"0")); + $aQuestionList = Questions::model()->findAllByAttributes(array("sid"=>$iSurveyID,"parent_qid"=>"0", "language"=>$sLanguage)); if(count($aQuestionList)==0) return array('status' => 'No questions found'); From 5c81c6b70e91e9ed8d4b8bb030a0838e5f22ef46 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 1 Aug 2012 13:17:11 +0300 Subject: [PATCH 30/75] Fixed Issue: Add offset and limit to list_participant --- application/controllers/admin/remotecontrol.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 1a64228c02e..46ed8d1d911 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1903,14 +1903,17 @@ public function set_participant_properties($sSessionKey, $iSurveyID, $iTokenID, /** * RPC Routine to return the ids and info of token/participants of a survey. * if $bUnused is true, user will get the list of not completed tokens (token_return functionality). + * Parameters iStart and ilimit are used to limit the number of results of this call. * * @access public * @param string $sSessionKey Auth credentials * @param int $iSurveyID Id of the survey to list participants + * @param int $iStart Start id of the token list + * @param int $iLimit Number of participants to return * @param bool $bUnused If you want unused tokensm, set true * @return array The list of tokens */ - public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) + public function list_participants($sSessionKey, $iSurveyID, $iStart=0, $iLimit=10, $bUnused=false) { if ($this->_checkSessionKey($sSessionKey)) { @@ -1924,9 +1927,9 @@ public function list_participants($sSessionKey, $iSurveyID, $bUnused=false) return array('status' => 'Error: No token table'); if($bUnused) - $oTokens = Tokens_dynamic::model($iSurveyID)->findAll("completed = 'N'"); + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(array("completed = 'N'", 'limit' => $iLimit, 'offset' => $iStart)); else - $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(); + $oTokens = Tokens_dynamic::model($iSurveyID)->findAll(array('limit' => $iLimit, 'offset' => $iStart)); if(count($oTokens)==0) return array('status' => 'No Tokens found'); From 9214a0947290ca8776570ca0abefc96dde5f77c0 Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Wed, 1 Aug 2012 13:52:47 +0300 Subject: [PATCH 31/75] Fixed Issue : Move insertParticipant from remotecontrol to model Dev: Created new function insertParticipant in Tokens_dynamic model --- .../controllers/admin/remotecontrol.php | 14 ++++++-------- application/models/Tokens_dynamic.php | 18 +++++++++++++++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 46ed8d1d911..31bb323189e 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -1712,14 +1712,9 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b Tokens_dynamic::sid($iSurveyID); $token = new Tokens_dynamic; - if ($token->insert()) + if ($new_token_id=$token->insertParticipant($aParticipant)) { - foreach ($aParticipant as $k => $v) - $token->$k = $v; - $inresult = $token->save(); - $new_token_id = $token->primaryKey; - - if ($bCreateToken) + if ($bCreateToken) $token_string = Tokens_dynamic::model()->createToken($new_token_id); else $token_string = ''; @@ -1729,8 +1724,11 @@ public function add_participants($sSessionKey, $iSurveyID, $aParticipantData, $b 'token' => $token_string, )); } + else + { + $aParticipant=false; + } } - return $aParticipantData; } else diff --git a/application/models/Tokens_dynamic.php b/application/models/Tokens_dynamic.php index 6c56e4d9138..2942769509e 100644 --- a/application/models/Tokens_dynamic.php +++ b/application/models/Tokens_dynamic.php @@ -122,7 +122,7 @@ public function summary() * (some older tokens tables dont' get udated properly) * */ - public function checkColumns() { +public function checkColumns() { $sid = self::$sid; $surveytable='{{tokens_'.$sid.'}}'; $columncheck=array("tid", "participant_id", "firstname", "lastname", "email", "emailstatus","token","language","blacklisted","sent","remindersent","completed","usesleft","validfrom","validuntil"); @@ -160,6 +160,22 @@ public function findUninvited($aTokenIds = false, $iMaxEmails = 0, $bEmail = tru return Yii::app()->db->createCommand($emquery)->queryAll(); } + function insertParticipant($data) + { + $token = new self; + foreach ($data as $k => $v) + $token->$k = $v; + try + { + $token->save(); + return $token->tid; + } + catch(Exception $e) + { + return false; + } + } + function insertToken($iSurveyID, $data) { self::sid($iSurveyID); From 6bda4d305ee0d315c06f4aed15597209c87982bc Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 1 Aug 2012 09:35:28 -0400 Subject: [PATCH 32/75] Dev new EM function unique(args) which returns true if all non-empty responses are unique --- .../helpers/expressions/em_core_helper.php | 22 +++++++++++++++++++ scripts/expressions/em_javascript.js | 14 ++++++++++++ 2 files changed, 36 insertions(+) diff --git a/application/helpers/expressions/em_core_helper.php b/application/helpers/expressions/em_core_helper.php index d37180f1830..50ec14dfe0c 100644 --- a/application/helpers/expressions/em_core_helper.php +++ b/application/helpers/expressions/em_core_helper.php @@ -228,6 +228,7 @@ function __construct() 'time' => array('time', 'time', $this->gT('Return current UNIX timestamp'), 'number time()', 'http://www.php.net/manual/en/function.time.php', 0), 'trim' => array('trim', 'trim', $this->gT('Strip whitespace (or other characters) from the beginning and end of a string'), 'string trim(string [, charlist])', 'http://www.php.net/manual/en/function.trim.php', 1,2), 'ucwords' => array('ucwords', 'ucwords', $this->gT('Uppercase the first character of each word in a string'), 'string ucwords(string)', 'http://www.php.net/manual/en/function.ucwords.php', 1), +'unique' => array('exprmgr_unique', 'LEMunique', $this->gT('Returns true if all non-empty responses are unique'), 'boolean unique(arg1, ..., argN)', '', -1), ); } @@ -3494,4 +3495,25 @@ function exprmgr_fixnum($value) return $value; } +/** + * Returns true if all non-empty values are unique + * @param type $args + */ +function exprmgr_unique($args) +{ + $uniqs = array(); + foreach ($args as $arg) + { + if (trim($arg)=='') + { + continue; // ignore blank answers + } + if (isset($uniqs[$arg])) + { + return false; + } + $uniqs[$arg]=1; + } + return true; +} ?> diff --git a/scripts/expressions/em_javascript.js b/scripts/expressions/em_javascript.js index 063361249aa..08d6177b2cd 100644 --- a/scripts/expressions/em_javascript.js +++ b/scripts/expressions/em_javascript.js @@ -15,6 +15,20 @@ function LEMcount() return result; } +function LEMunique() +{ + var uniqs = new Array(); + for (i=0;i Date: Wed, 1 Aug 2012 14:48:29 -0500 Subject: [PATCH 33/75] Fix path error for certain CSS files. --- application/controllers/admin/conditionsaction.php | 2 +- application/controllers/admin/participantsaction.php | 4 ++-- application/controllers/admin/surveyadmin.php | 11 +++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/application/controllers/admin/conditionsaction.php b/application/controllers/admin/conditionsaction.php index 1bd97753871..40d14a0a8f3 100644 --- a/application/controllers/admin/conditionsaction.php +++ b/application/controllers/admin/conditionsaction.php @@ -1136,7 +1136,7 @@ function index($subaction, $surveyid=null, $gid=null, $qid=null) //END: PREPARE JAVASCRIPT TO SHOW MATCHING ANSWERS TO SELECTED QUESTION - $this->getController()->_css_admin_includes(Yii::app()->getConfig("generalscripts").'jquery/css/jquery.multiselect.css'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig("publicstyleurl").'jquery.multiselect.css'); $aViewUrls = array(); diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index f34a7bfc420..1ed52d81226 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -143,8 +143,8 @@ function displayParticipants() $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jqGrid/js/i18n/grid.locale-en.js'); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jqGrid/js/jquery.jqGrid.min.js'); - $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/css/jquery.multiselect.css'); - $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/css/jquery.multiselect.filter.css'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.css'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.filter.css'); $this->getController()->_css_admin_includes(Yii::app()->getConfig('adminstyleurl') . 'displayParticipants.css'); $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jqGrid/css/ui.jqgrid.css'); $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jqGrid/css/jquery.ui.datepicker.css'); diff --git a/application/controllers/admin/surveyadmin.php b/application/controllers/admin/surveyadmin.php index fdcc4be1a1e..a8f1627dbcf 100644 --- a/application/controllers/admin/surveyadmin.php +++ b/application/controllers/admin/surveyadmin.php @@ -52,12 +52,11 @@ public function index() $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/js/jquery.jqGrid.min.js"); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jquery.coookie.js"); $this->getController()->_js_admin_includes(Yii::app()->baseUrl . "/scripts/admin/listsurvey.js"); - $css_admin_includes[] = Yii::app()->getConfig('generalscripts') . "jquery/css/jquery.multiselect.css"; - $css_admin_includes[] = Yii::app()->getConfig('generalscripts') . "jquery/css/jquery.multiselect.filter.css"; - $css_admin_includes[] = Yii::app()->getConfig('adminstyleurl') . "displayParticipants.css"; - $css_admin_includes[] = Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/css/ui.jqgrid.css"; - $css_admin_includes[] = Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/css/jquery.ui.datepicker.css"; - $this->getController()->_css_admin_includes($css_admin_includes); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.css'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.filter.css'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('adminstyleurl') . "displayParticipants.css"); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/css/ui.jqgrid.css"); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/css/jquery.ui.datepicker.css"); Yii::app()->loadHelper('surveytranslator'); From 049fbe4dad9660947d2277184d0c9a60cd5d8ca6 Mon Sep 17 00:00:00 2001 From: Aaron Schmitz Date: Wed, 1 Aug 2012 14:58:20 -0500 Subject: [PATCH 34/75] Fix error: Invalid JSON: Strict Standards: Creating default object from empty value in C:\Users\Aaron Schmitz\Desktop\LimeSurvey\application\controllers\admin\participantsaction.php on line 1051 { "page":"1","records":"0","total":0 } (Error 200) Could not process your query. --- application/controllers/admin/participantsaction.php | 1 + 1 file changed, 1 insertion(+) diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index f34a7bfc420..7448866d08c 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -1047,6 +1047,7 @@ function subval_sort($a, $subkey, $order) if (Yii::app()->session['USER_RIGHT_SUPERADMIN']) { $records = Participants::model()->getParticipants($page, $limit); + $aData = new stdClass; $aData->page = $page; $aData->records = Participants::model()->count(); $aData->total = ceil($aData->records / $limit); From 93a131fc7c4e6f40fefa632de02d4b3069863813 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 2 Aug 2012 00:05:46 +0200 Subject: [PATCH 35/75] Dev Automatic translation update --- locale/_template/limesurvey.pot | 70 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index 9a16a86435d..56903dad70b 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-07-30 22:05:44+00:00\n" +"POT-Creation-Date: 2012-08-01 22:05:44+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -6628,118 +6628,122 @@ msgstr "" msgid "Uppercase the first character of each word in a string" msgstr "" -#: application/helpers/expressions/em_core_helper.php:258 +#: application/helpers/expressions/em_core_helper.php:231 +msgid "Returns true if all non-empty responses are unique" +msgstr "" + +#: application/helpers/expressions/em_core_helper.php:259 msgid "Unable to evaluate binary operator - fewer than 2 entries on stack" msgstr "" -#: application/helpers/expressions/em_core_helper.php:265 -#: application/helpers/expressions/em_core_helper.php:404 +#: application/helpers/expressions/em_core_helper.php:266 +#: application/helpers/expressions/em_core_helper.php:405 msgid "Invalid value(s) on the stack" msgstr "" -#: application/helpers/expressions/em_core_helper.php:398 +#: application/helpers/expressions/em_core_helper.php:399 msgid "Unable to evaluate unary operator - no entries on stack" msgstr "" -#: application/helpers/expressions/em_core_helper.php:453 +#: application/helpers/expressions/em_core_helper.php:454 msgid "Extra tokens found" msgstr "" -#: application/helpers/expressions/em_core_helper.php:468 +#: application/helpers/expressions/em_core_helper.php:469 msgid "Unbalanced equation - values left on stack" msgstr "" -#: application/helpers/expressions/em_core_helper.php:474 +#: application/helpers/expressions/em_core_helper.php:475 msgid "Not a valid expression" msgstr "" -#: application/helpers/expressions/em_core_helper.php:535 -#: application/helpers/expressions/em_core_helper.php:963 -#: application/helpers/expressions/em_core_helper.php:1044 +#: application/helpers/expressions/em_core_helper.php:536 +#: application/helpers/expressions/em_core_helper.php:964 +#: application/helpers/expressions/em_core_helper.php:1045 msgid "Poorly terminated expression - expected a constant or variable" msgstr "" -#: application/helpers/expressions/em_core_helper.php:580 +#: application/helpers/expressions/em_core_helper.php:581 msgid "Variable not declared until a later page" msgstr "" -#: application/helpers/expressions/em_core_helper.php:587 -#: application/helpers/expressions/em_core_helper.php:1699 +#: application/helpers/expressions/em_core_helper.php:588 +#: application/helpers/expressions/em_core_helper.php:1700 msgid "Undefined variable" msgstr "" -#: application/helpers/expressions/em_core_helper.php:594 +#: application/helpers/expressions/em_core_helper.php:595 msgid "Should never get to this line?" msgstr "" -#: application/helpers/expressions/em_core_helper.php:680 +#: application/helpers/expressions/em_core_helper.php:681 msgid "The value of this variable can not be changed" msgstr "" -#: application/helpers/expressions/em_core_helper.php:686 +#: application/helpers/expressions/em_core_helper.php:687 msgid "Only variables can be assigned values" msgstr "" -#: application/helpers/expressions/em_core_helper.php:742 +#: application/helpers/expressions/em_core_helper.php:743 msgid "Expected expressions separated by commas" msgstr "" -#: application/helpers/expressions/em_core_helper.php:750 +#: application/helpers/expressions/em_core_helper.php:751 msgid "Extra token found after expressions" msgstr "" -#: application/helpers/expressions/em_core_helper.php:766 -#: application/helpers/expressions/em_core_helper.php:1692 +#: application/helpers/expressions/em_core_helper.php:767 +#: application/helpers/expressions/em_core_helper.php:1693 msgid "Undefined function" msgstr "" -#: application/helpers/expressions/em_core_helper.php:772 +#: application/helpers/expressions/em_core_helper.php:773 msgid "Expected left parentheses after function name" msgstr "" -#: application/helpers/expressions/em_core_helper.php:796 +#: application/helpers/expressions/em_core_helper.php:797 msgid "Extra comma found in function" msgstr "" -#: application/helpers/expressions/em_core_helper.php:980 +#: application/helpers/expressions/em_core_helper.php:981 msgid "Expected right parentheses" msgstr "" -#: application/helpers/expressions/em_core_helper.php:1683 +#: application/helpers/expressions/em_core_helper.php:1684 msgid "Extra right parentheses detected" msgstr "" -#: application/helpers/expressions/em_core_helper.php:1704 +#: application/helpers/expressions/em_core_helper.php:1705 msgid "Unsupported syntax" msgstr "" -#: application/helpers/expressions/em_core_helper.php:1712 +#: application/helpers/expressions/em_core_helper.php:1713 msgid "Missing %s closing right parentheses" msgstr "" -#: application/helpers/expressions/em_core_helper.php:1997 +#: application/helpers/expressions/em_core_helper.php:1998 msgid "Function must have at least %s argument" msgid_plural "Function must have at least %s arguments" msgstr[0] "" msgstr[1] "" -#: application/helpers/expressions/em_core_helper.php:2088 +#: application/helpers/expressions/em_core_helper.php:2089 msgid "Unsupported number of arguments: %s" msgstr "" -#: application/helpers/expressions/em_core_helper.php:2093 +#: application/helpers/expressions/em_core_helper.php:2094 msgid "Function does not support %s arguments" msgstr "" -#: application/helpers/expressions/em_core_helper.php:2094 +#: application/helpers/expressions/em_core_helper.php:2095 msgid "Function supports this many arguments, where -1=unlimited: %s" msgstr "" -#: application/helpers/expressions/em_core_helper.php:2328 +#: application/helpers/expressions/em_core_helper.php:2329 msgid "Tried to pop value off of empty stack" msgstr "" -#: application/helpers/expressions/em_core_helper.php:3477 +#: application/helpers/expressions/em_core_helper.php:3478 msgid "Invalid PERL Regular Expression: %s" msgstr "" From 5c54305a467a662f89045b2d25977c72b9eb897e Mon Sep 17 00:00:00 2001 From: jcleeland Date: Thu, 2 Aug 2012 16:55:59 +1000 Subject: [PATCH 36/75] Fixed issue: Fix PHP notice that breaks participants display - strict standards creating default object from empty value (extended version of Aaron's fix) --- application/controllers/admin/participantsaction.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/controllers/admin/participantsaction.php b/application/controllers/admin/participantsaction.php index f34a7bfc420..f335810bb29 100644 --- a/application/controllers/admin/participantsaction.php +++ b/application/controllers/admin/participantsaction.php @@ -1043,6 +1043,7 @@ function subval_sort($a, $subkey, $order) array_push($participantfields, $value['attribute_id']); } + $aData = new stdClass; //If super admin all the participants will be visible if (Yii::app()->session['USER_RIGHT_SUPERADMIN']) { @@ -1089,7 +1090,6 @@ function subval_sort($a, $subkey, $order) $i++; } } - echo ls_json_encode($aData); } // Only the owned and shared participants will be visible else @@ -1139,8 +1139,8 @@ function subval_sort($a, $subkey, $order) $i++; } } - echo ls_json_encode($aData); } + echo ls_json_encode($aData); } /* From db1450e58858052044ae574c0994f8c049ce671d Mon Sep 17 00:00:00 2001 From: Spiros Trougakos Date: Thu, 2 Aug 2012 15:34:27 +0300 Subject: [PATCH 37/75] Fixed Issue: Simplify in export_statistics Dev: Create helper function createCompleteSGQA Dev: Fixed missing filename in statistics helper generate_statistics Dev: Provided that generate_statistics functions properly, export_statistics generates results. --- .../controllers/admin/remotecontrol.php | 52 +++---- .../helpers/admin/statistics_helper.php | 5 +- application/helpers/common_helper.php | 131 ++++++++++++++++++ 3 files changed, 152 insertions(+), 36 deletions(-) diff --git a/application/controllers/admin/remotecontrol.php b/application/controllers/admin/remotecontrol.php index 31bb323189e..00505f19c49 100644 --- a/application/controllers/admin/remotecontrol.php +++ b/application/controllers/admin/remotecontrol.php @@ -568,13 +568,14 @@ public function activate_survey($sSessionKey, $iSurveyID) * @param string $sSessionKey Auth credentials * @param int $iSurveyID Id of the Survey * @param string $docType Type of documents the exported statistics should be + * $param string $sLanguage Optional language of the survey to use * @param string $graph Create graph option * @return string Base64 encoded string with the statistics file */ - public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $graph='0') + public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $sLanguage=null, $graph='0') { Yii::app()->loadHelper('admin/statistics'); - + $tempdir = Yii::app()->getConfig("tempdir"); if (!$this->_checkSessionKey($sSessionKey)) return array('status' => 'Invalid session key'); $oSurvey = Survey::model()->findByPk($iSurveyID); @@ -583,52 +584,33 @@ public function export_statistics($sSessionKey, $iSurveyID, $docType='pdf', $gra if(Survey::model()->findByPk($iSurveyID)->owner_id != $_SESSION['loginID']) return array('status' => 'Error: No Permission'); + $aAdditionalLanguages = array_filter(explode(" ", $oSurvey->additional_languages)); - $oAllQuestions = Questions::model()->findAll("sid = '".$iSurveyID."'"); - foreach($oAllQuestions as $sField) - { - $sMyField = $iSurveyID."X".$sField['gid']."X".$sField['qid']; - // Multiple choice get special treatment - if ($sField['type'] == "M" || $sField['type'] == "P") {$sMyField = "M$myField";} - //numerical input will get special treatment (arihtmetic mean, standard derivation, ...) - if ($sField['type'] == "N") {$sMyField = "N$myField";} - if ($sField['type'] == "Q") {$sMyField = "Q$myField";} - // textfields get special treatment - if ($sField['type'] == "S" || $sField['type'] == "T" || $sField['type'] == "U"){$sMyField = "T$myField";} - //statistics for Date questions are not implemented yet. - if ($sField['type'] == "D") {$sMyField = "D$myField";} - if ($sField['type'] == "F" || $sField['type'] == "H") - { - $result3 = Answers::model()->findAllByAttributes(array('qid' => $sField['qid'],'language' => getBaseLanguageFromSurveyID($iSurveyID)), array('order' => 'sortorder, answer')); - foreach ($result3 as $row) - { - $sMyField = "$sMyField{$row['code']}"; - } - } - $aSummary[]=$myField; - } + if (is_null($sLanguage)|| !in_array($sLanguage,$aAdditionalLanguages)) + $sLanguage = $oSurvey->language; + + $oAllQuestions = Questions::model()->findAllByAttributes(array('sid' => $iSurveyID, 'parent_qid'=>'0','language'=>$sLanguage)); + $aSummary = createCompleteSGQA($iSurveyID,$oAllQuestions,$sLanguage); switch ($docType) { case 'pdf': - $tempFile = generate_statistics($iSurveyID,$aSummary,'all',$graph,$docType,'F'); + $sTempFile = generate_statistics($iSurveyID,$aSummary,$aSummary,$graph,$docType,'F',$sLanguage); + $sResult = file_get_contents($sTempFile); + unlink($sTempFile); break; case 'xls': - $tempFile = generate_statistics($iSurveyID,$aSummary,'all',0,$docType, 'F'); + $sTempFile = generate_statistics($iSurveyID,$aSummary,$aSummary,'0',$docType, 'F',$sLanguage); + $sResult = file_get_contents($sTempFile); + unlink($sTempFile); break; case 'html': - $html = generate_statistics($iSurveyID,$aSummary,'all',0,$docType, 'F'); + $sResult = generate_statistics($iSurveyID,$aSummary,$aSummary,'0',$docType, 'DD',$sLanguage); break; } - if(isset($html)) - return base64_encode($html); - else - { - $sResult = file_get_contents($tempfile); - unlink($tempfile); return base64_encode($sResult); - } + } /** diff --git a/application/helpers/admin/statistics_helper.php b/application/helpers/admin/statistics_helper.php index cfacea6f606..0f3332eafd9 100644 --- a/application/helpers/admin/statistics_helper.php +++ b/application/helpers/admin/statistics_helper.php @@ -3290,7 +3290,10 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, */ Yii::import('application.libraries.admin.pear.Spreadsheet.Excel.Xlswriter', true); if($pdfOutput=='F') - $workbook = new Xlswriter($tempdir.'/statistic-survey'.$surveyid.'.xls'); + { + $sFileName = $tempdir.'/statistic-survey'.$surveyid.'.xls' + $workbook = new Xlswriter($sFileName); + } else $workbook = new Xlswriter(); diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 80b8f915035..a70a2b292dc 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -2165,6 +2165,137 @@ function validateTemplateDir($templatename) } + +/** + *This functions generates a a summary containing the SGQA for questions of a survey, enriched with options per question + * It can be used for the generation of statistics. Derived from Statistics_userController + * @param int $iSurveyID Id of the Survey in question + * @param array $aFilters an array which is the result of a query in Questions model + * @param string $sLanguage + * @return array The summary + */ + function createCompleteSGQA($iSurveyID,$aFilters,$sLanguage) { + + foreach ($aFilters as $flt) + { + Yii::app()->loadHelper("surveytranslator"); + $myfield = "{$iSurveyID}X{$flt['gid']}X{$flt['qid']}"; + $oSurvey = Survey::model()->findByPk($iSurveyID); + $aAdditionalLanguages = array_filter(explode(" ", $oSurvey->additional_languages)); + if (is_null($sLanguage)|| !in_array($sLanguage,$aAdditionalLanguages)) + $sLanguage = $oSurvey->language; + + switch ($flt['type']) + { + case "K": // Multiple Numerical + case "Q": // Multiple Short Text + //get answers + $query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order"; + $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt['qid'], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll(); + + //go through all the (multiple) answers + foreach($result as $row) + { + $myfield2=$flt['type'].$myfield.reset($row); + $allfields[] = $myfield2; + } + break; + case "A": // ARRAY OF 5 POINT CHOICE QUESTIONS + case "B": // ARRAY OF 10 POINT CHOICE QUESTIONS + case "C": // ARRAY OF YES\No\$clang->gT("Uncertain") QUESTIONS + case "E": // ARRAY OF Increase/Same/Decrease QUESTIONS + case "F": // FlEXIBLE ARRAY + case "H": // ARRAY (By Column) + //get answers + $query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order"; + $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt['qid'], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll(); + + //go through all the (multiple) answers + foreach($result as $row) + { + $myfield2 = $myfield.reset($row); + $allfields[]=$myfield2; + } + break; + // all "free text" types (T, U, S) get the same prefix ("T") + case "T": // Long free text + case "U": // Huge free text + case "S": // Short free text + $myfield="T$myfield"; + $allfields[] = $myfield; + break; + case ";": //ARRAY (Multi Flex) (Text) + case ":": //ARRAY (Multi Flex) (Numbers) + $query = "SELECT title, question FROM {{questions}} WHERE parent_qid=:flt_0 AND language=:lang AND scale_id = 0 ORDER BY question_order"; + $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt['qid'], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll(); + foreach($result as $row) + { + $fquery = "SELECT * FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang AND scale_id = 1 ORDER BY question_order, title"; + $fresult = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt['qid'], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll(); + foreach($fresult as $frow) + { + $myfield2 = $myfield . reset($row) . "_" . $frow['title']; + $allfields[]=$myfield2; + } + } + break; + case "R": //RANKING + //get some answers + $query = "SELECT code, answer FROM {{answers}} WHERE qid = :flt_0 AND language = :lang ORDER BY sortorder, answer"; + $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt['qid'], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll(); + + //get number of answers + $count = $result->num_rows(); + + //loop through all answers. if there are 3 items to rate there will be 3 statistics + for ($i=1; $i<=$count; $i++) + { + $myfield2 = "R" . $myfield . $i . "-" . strlen($i); + $allfields[]=$myfield2; + } + break; + //Boilerplate questions are only used to put some text between other questions -> no analysis needed + case "X": //This is a boilerplate question and it has no business in this script + break; + case "1": // MULTI SCALE + //get answers + $query = "SELECT title, question FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang ORDER BY question_order"; + $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt['qid'], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll(); + + //loop through answers + foreach($result as $row) + { + //----------------- LABEL 1 --------------------- + $myfield2 = $myfield . reset($row[0])."#0"; + $allfields[]=$myfield2; + //----------------- LABEL 2 --------------------- + $myfield2 = $myfield . "$row[0]#1"; + $allfields[]=$myfield2; + } //end WHILE -> loop through all answers + break; + + case "P": //P - Multiple choice with comments + case "M": //M - Multiple choice + case "N": //N - Numerical input + case "D": //D - Date + $myfield2 = $flt['type'].$myfield; + $allfields[]=$myfield2; + break; + default: //Default settings + $allfields[] = $myfield; + break; + + } //end switch + } + +return $allfields; + +} + + + + + /** * This function generates an array containing the fieldcode, and matching data in the same order as the activate script * From 5bc0e7fb015f2d6ed1120f8862dc879dea34e659 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 3 Aug 2012 00:05:46 +0200 Subject: [PATCH 38/75] Dev Automatic translation update --- locale/_template/limesurvey.pot | 1194 +++++++++++++++---------------- 1 file changed, 597 insertions(+), 597 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index 56903dad70b..cd4980c70a9 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-08-01 22:05:44+00:00\n" +"POT-Creation-Date: 2012-08-02 22:05:44+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -100,7 +100,7 @@ msgid "Back" msgstr "" #: application/controllers/AdminController.php:86 -#: application/controllers/admin/surveyadmin.php:420 +#: application/controllers/admin/surveyadmin.php:419 #: application/controllers/admin/tokens.php:2184 #: application/helpers/admin/import_helper.php:2612 #: application/views/admin/authentication/forgotpassword.php:15 @@ -479,8 +479,8 @@ msgid "Title" msgstr "" #: application/controllers/UploaderController.php:264 -#: application/helpers/common_helper.php:2447 -#: application/helpers/common_helper.php:2660 +#: application/helpers/common_helper.php:2578 +#: application/helpers/common_helper.php:2791 #: application/helpers/qanda_helper.php:2790 #: application/views/admin/dataentry/content_view.php:139 msgid "Comment" @@ -576,7 +576,7 @@ msgid "Assessment mode for this survey is not activated. You can activate it in msgstr "" #: application/controllers/admin/assessments.php:136 -#: application/controllers/admin/surveyadmin.php:593 +#: application/controllers/admin/surveyadmin.php:592 #: application/views/admin/assessments_view.php:24 #: application/views/admin/quotas/viewquotasrow_view.php:28 msgid "Edit" @@ -843,7 +843,7 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1183 #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:517 -#: application/controllers/admin/surveyadmin.php:608 +#: application/controllers/admin/surveyadmin.php:607 #: application/controllers/admin/tokens.php:2101 #: application/core/Survey_Common_Action.php:827 #: application/helpers/admin/statistics_helper.php:1456 @@ -851,40 +851,40 @@ msgstr "" #: application/helpers/common_helper.php:1819 #: application/helpers/common_helper.php:1825 #: application/helpers/common_helper.php:1841 -#: application/helpers/common_helper.php:3064 -#: application/helpers/common_helper.php:3165 -#: application/helpers/common_helper.php:3275 -#: application/helpers/common_helper.php:3288 -#: application/helpers/common_helper.php:3299 -#: application/helpers/common_helper.php:3310 -#: application/helpers/common_helper.php:3321 -#: application/helpers/common_helper.php:3331 -#: application/helpers/common_helper.php:3342 -#: application/helpers/common_helper.php:3393 -#: application/helpers/common_helper.php:3424 -#: application/helpers/common_helper.php:3435 -#: application/helpers/common_helper.php:3542 -#: application/helpers/common_helper.php:3553 -#: application/helpers/common_helper.php:3573 -#: application/helpers/common_helper.php:3585 -#: application/helpers/common_helper.php:3615 -#: application/helpers/common_helper.php:3628 -#: application/helpers/common_helper.php:3639 -#: application/helpers/common_helper.php:3650 -#: application/helpers/common_helper.php:3670 -#: application/helpers/common_helper.php:3690 -#: application/helpers/common_helper.php:3727 -#: application/helpers/common_helper.php:3737 -#: application/helpers/common_helper.php:3747 -#: application/helpers/common_helper.php:3766 -#: application/helpers/common_helper.php:3809 -#: application/helpers/common_helper.php:3835 -#: application/helpers/common_helper.php:3871 -#: application/helpers/common_helper.php:3959 -#: application/helpers/common_helper.php:3969 -#: application/helpers/common_helper.php:4116 -#: application/helpers/common_helper.php:4127 -#: application/helpers/common_helper.php:4187 +#: application/helpers/common_helper.php:3195 +#: application/helpers/common_helper.php:3296 +#: application/helpers/common_helper.php:3406 +#: application/helpers/common_helper.php:3419 +#: application/helpers/common_helper.php:3430 +#: application/helpers/common_helper.php:3441 +#: application/helpers/common_helper.php:3452 +#: application/helpers/common_helper.php:3462 +#: application/helpers/common_helper.php:3473 +#: application/helpers/common_helper.php:3524 +#: application/helpers/common_helper.php:3555 +#: application/helpers/common_helper.php:3566 +#: application/helpers/common_helper.php:3673 +#: application/helpers/common_helper.php:3684 +#: application/helpers/common_helper.php:3704 +#: application/helpers/common_helper.php:3716 +#: application/helpers/common_helper.php:3746 +#: application/helpers/common_helper.php:3759 +#: application/helpers/common_helper.php:3770 +#: application/helpers/common_helper.php:3781 +#: application/helpers/common_helper.php:3801 +#: application/helpers/common_helper.php:3821 +#: application/helpers/common_helper.php:3858 +#: application/helpers/common_helper.php:3868 +#: application/helpers/common_helper.php:3878 +#: application/helpers/common_helper.php:3897 +#: application/helpers/common_helper.php:3940 +#: application/helpers/common_helper.php:3966 +#: application/helpers/common_helper.php:4002 +#: application/helpers/common_helper.php:4090 +#: application/helpers/common_helper.php:4100 +#: application/helpers/common_helper.php:4247 +#: application/helpers/common_helper.php:4258 +#: application/helpers/common_helper.php:4318 #: application/helpers/export_helper.php:241 #: application/helpers/export_helper.php:245 #: application/helpers/export_helper.php:253 @@ -1009,29 +1009,29 @@ msgstr "" #: application/controllers/admin/tokens.php:2303 #: application/controllers/admin/tokens.php:2338 #: application/controllers/admin/useraction.php:720 -#: application/helpers/common_helper.php:6229 -#: application/helpers/common_helper.php:6234 -#: application/helpers/common_helper.php:6239 -#: application/helpers/common_helper.php:6244 -#: application/helpers/common_helper.php:6249 -#: application/helpers/common_helper.php:6254 -#: application/helpers/common_helper.php:6259 -#: application/helpers/common_helper.php:6264 -#: application/helpers/common_helper.php:6269 -#: application/helpers/common_helper.php:6275 -#: application/helpers/common_helper.php:6281 -#: application/helpers/common_helper.php:6286 -#: application/helpers/common_helper.php:6291 -#: application/helpers/common_helper.php:6296 -#: application/helpers/common_helper.php:6301 -#: application/helpers/common_helper.php:6306 -#: application/helpers/common_helper.php:6312 -#: application/helpers/common_helper.php:6317 -#: application/helpers/common_helper.php:6326 -#: application/helpers/common_helper.php:6331 -#: application/helpers/common_helper.php:6338 -#: application/helpers/common_helper.php:6342 -#: application/helpers/common_helper.php:6346 +#: application/helpers/common_helper.php:6360 +#: application/helpers/common_helper.php:6365 +#: application/helpers/common_helper.php:6370 +#: application/helpers/common_helper.php:6375 +#: application/helpers/common_helper.php:6380 +#: application/helpers/common_helper.php:6385 +#: application/helpers/common_helper.php:6390 +#: application/helpers/common_helper.php:6395 +#: application/helpers/common_helper.php:6400 +#: application/helpers/common_helper.php:6406 +#: application/helpers/common_helper.php:6412 +#: application/helpers/common_helper.php:6417 +#: application/helpers/common_helper.php:6422 +#: application/helpers/common_helper.php:6427 +#: application/helpers/common_helper.php:6432 +#: application/helpers/common_helper.php:6437 +#: application/helpers/common_helper.php:6443 +#: application/helpers/common_helper.php:6448 +#: application/helpers/common_helper.php:6457 +#: application/helpers/common_helper.php:6462 +#: application/helpers/common_helper.php:6469 +#: application/helpers/common_helper.php:6473 +#: application/helpers/common_helper.php:6477 #: application/helpers/frontend_helper.php:1448 #: application/helpers/frontend_helper.php:1525 #: application/helpers/frontend_helper.php:1697 @@ -1095,48 +1095,48 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1185 #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:518 -#: application/controllers/admin/surveyadmin.php:612 +#: application/controllers/admin/surveyadmin.php:611 #: application/controllers/admin/tokens.php:2103 #: application/core/Survey_Common_Action.php:823 #: application/helpers/admin/statistics_helper.php:1457 #: application/helpers/admin/statistics_helper.php:1590 #: application/helpers/common_helper.php:1826 #: application/helpers/common_helper.php:1842 -#: application/helpers/common_helper.php:3063 -#: application/helpers/common_helper.php:3164 -#: application/helpers/common_helper.php:3274 -#: application/helpers/common_helper.php:3289 -#: application/helpers/common_helper.php:3300 -#: application/helpers/common_helper.php:3311 -#: application/helpers/common_helper.php:3322 -#: application/helpers/common_helper.php:3331 -#: application/helpers/common_helper.php:3342 -#: application/helpers/common_helper.php:3394 -#: application/helpers/common_helper.php:3423 -#: application/helpers/common_helper.php:3434 -#: application/helpers/common_helper.php:3541 -#: application/helpers/common_helper.php:3552 -#: application/helpers/common_helper.php:3572 -#: application/helpers/common_helper.php:3584 -#: application/helpers/common_helper.php:3614 -#: application/helpers/common_helper.php:3627 -#: application/helpers/common_helper.php:3638 -#: application/helpers/common_helper.php:3649 -#: application/helpers/common_helper.php:3669 -#: application/helpers/common_helper.php:3689 -#: application/helpers/common_helper.php:3726 -#: application/helpers/common_helper.php:3736 -#: application/helpers/common_helper.php:3746 -#: application/helpers/common_helper.php:3765 -#: application/helpers/common_helper.php:3808 +#: application/helpers/common_helper.php:3194 +#: application/helpers/common_helper.php:3295 +#: application/helpers/common_helper.php:3405 +#: application/helpers/common_helper.php:3420 +#: application/helpers/common_helper.php:3431 +#: application/helpers/common_helper.php:3442 +#: application/helpers/common_helper.php:3453 +#: application/helpers/common_helper.php:3462 +#: application/helpers/common_helper.php:3473 +#: application/helpers/common_helper.php:3525 +#: application/helpers/common_helper.php:3554 +#: application/helpers/common_helper.php:3565 +#: application/helpers/common_helper.php:3672 +#: application/helpers/common_helper.php:3683 +#: application/helpers/common_helper.php:3703 +#: application/helpers/common_helper.php:3715 +#: application/helpers/common_helper.php:3745 +#: application/helpers/common_helper.php:3758 +#: application/helpers/common_helper.php:3769 +#: application/helpers/common_helper.php:3780 +#: application/helpers/common_helper.php:3800 #: application/helpers/common_helper.php:3820 -#: application/helpers/common_helper.php:3834 -#: application/helpers/common_helper.php:3870 -#: application/helpers/common_helper.php:3958 -#: application/helpers/common_helper.php:3968 -#: application/helpers/common_helper.php:4115 -#: application/helpers/common_helper.php:4126 -#: application/helpers/common_helper.php:4186 +#: application/helpers/common_helper.php:3857 +#: application/helpers/common_helper.php:3867 +#: application/helpers/common_helper.php:3877 +#: application/helpers/common_helper.php:3896 +#: application/helpers/common_helper.php:3939 +#: application/helpers/common_helper.php:3951 +#: application/helpers/common_helper.php:3965 +#: application/helpers/common_helper.php:4001 +#: application/helpers/common_helper.php:4089 +#: application/helpers/common_helper.php:4099 +#: application/helpers/common_helper.php:4246 +#: application/helpers/common_helper.php:4257 +#: application/helpers/common_helper.php:4317 #: application/helpers/export_helper.php:254 #: application/helpers/export_helper.php:258 #: application/helpers/export_helper.php:1277 @@ -1353,20 +1353,20 @@ msgstr "" #: application/helpers/admin/statistics_helper.php:1947 #: application/helpers/common_helper.php:1811 #: application/helpers/common_helper.php:1874 -#: application/helpers/common_helper.php:2419 -#: application/helpers/common_helper.php:2679 -#: application/helpers/common_helper.php:3580 -#: application/helpers/common_helper.php:3594 -#: application/helpers/common_helper.php:3610 -#: application/helpers/common_helper.php:3666 -#: application/helpers/common_helper.php:3686 -#: application/helpers/common_helper.php:3900 -#: application/helpers/common_helper.php:3913 -#: application/helpers/common_helper.php:3923 -#: application/helpers/common_helper.php:4135 -#: application/helpers/common_helper.php:4144 -#: application/helpers/common_helper.php:4153 -#: application/helpers/common_helper.php:4162 +#: application/helpers/common_helper.php:2550 +#: application/helpers/common_helper.php:2810 +#: application/helpers/common_helper.php:3711 +#: application/helpers/common_helper.php:3725 +#: application/helpers/common_helper.php:3741 +#: application/helpers/common_helper.php:3797 +#: application/helpers/common_helper.php:3817 +#: application/helpers/common_helper.php:4031 +#: application/helpers/common_helper.php:4044 +#: application/helpers/common_helper.php:4054 +#: application/helpers/common_helper.php:4266 +#: application/helpers/common_helper.php:4275 +#: application/helpers/common_helper.php:4284 +#: application/helpers/common_helper.php:4293 #: application/helpers/export_helper.php:874 #: application/helpers/export_helper.php:883 #: application/helpers/export_helper.php:979 @@ -1683,11 +1683,11 @@ msgstr "" #: application/controllers/admin/dataentry.php:306 #: application/controllers/admin/labels.php:100 #: application/controllers/admin/labels.php:133 -#: application/controllers/admin/participantsaction.php:1386 +#: application/controllers/admin/participantsaction.php:1387 #: application/controllers/admin/question.php:55 #: application/controllers/admin/questiongroup.php:55 -#: application/controllers/admin/surveyadmin.php:204 -#: application/controllers/admin/surveyadmin.php:827 +#: application/controllers/admin/surveyadmin.php:203 +#: application/controllers/admin/surveyadmin.php:826 #: application/controllers/admin/templates.php:151 #: application/controllers/admin/templates.php:210 msgid "An error occurred uploading your file. This may be caused by incorrect permissions in your %s folder." @@ -1752,13 +1752,13 @@ msgid "Remove this item" msgstr "" #: application/controllers/admin/dataentry.php:1000 -#: application/helpers/common_helper.php:3918 +#: application/helpers/common_helper.php:4049 #: application/helpers/qanda_helper.php:2124 msgid "Your Choices" msgstr "" #: application/controllers/admin/dataentry.php:1005 -#: application/helpers/common_helper.php:3928 +#: application/helpers/common_helper.php:4059 #: application/helpers/qanda_helper.php:2132 msgid "Your Ranking" msgstr "" @@ -2196,18 +2196,18 @@ msgid "Logged in" msgstr "" #: application/controllers/admin/labels.php:54 -#: application/controllers/admin/surveyadmin.php:158 +#: application/controllers/admin/surveyadmin.php:157 msgid "Demo mode only: Uploading files is disabled in this system." msgstr "" #: application/controllers/admin/labels.php:68 -#: application/controllers/admin/surveyadmin.php:172 +#: application/controllers/admin/surveyadmin.php:171 #: application/controllers/admin/templates.php:96 msgid "Incorrect permissions in your %s folder." msgstr "" #: application/controllers/admin/labels.php:97 -#: application/controllers/admin/surveyadmin.php:201 +#: application/controllers/admin/surveyadmin.php:200 msgid "This ZIP archive contains no valid Resources files. Import failed." msgstr "" @@ -2407,31 +2407,31 @@ msgstr "" msgid "%s participant(s) are to be copied " msgstr "" -#: application/controllers/admin/participantsaction.php:1752 +#: application/controllers/admin/participantsaction.php:1753 msgid "%s participants have been shared" msgstr "" -#: application/controllers/admin/participantsaction.php:1772 +#: application/controllers/admin/participantsaction.php:1773 msgid "%s participants have been copied to the central participants table" msgstr "" -#: application/controllers/admin/participantsaction.php:1775 -#: application/controllers/admin/participantsaction.php:1799 -#: application/controllers/admin/participantsaction.php:1829 +#: application/controllers/admin/participantsaction.php:1776 +#: application/controllers/admin/participantsaction.php:1800 +#: application/controllers/admin/participantsaction.php:1830 msgid "%s entries were not copied because they already existed" msgstr "" -#: application/controllers/admin/participantsaction.php:1779 +#: application/controllers/admin/participantsaction.php:1780 msgid "Attribute values for existing participants have been updated from the token records" msgstr "" -#: application/controllers/admin/participantsaction.php:1796 -#: application/controllers/admin/participantsaction.php:1826 +#: application/controllers/admin/participantsaction.php:1797 +#: application/controllers/admin/participantsaction.php:1827 msgid "%s participants have been copied to the survey token table" msgstr "" -#: application/controllers/admin/participantsaction.php:1803 -#: application/controllers/admin/participantsaction.php:1833 +#: application/controllers/admin/participantsaction.php:1804 +#: application/controllers/admin/participantsaction.php:1834 msgid "Attribute values for existing participants have been updated from the participants records" msgstr "" @@ -2688,7 +2688,7 @@ msgstr "" #: application/controllers/admin/responses.php:130 #: application/controllers/admin/responses.php:465 -#: application/helpers/common_helper.php:5315 +#: application/helpers/common_helper.php:5446 #: application/helpers/replacements_helper.php:628 #: application/views/admin/export/exportresults_view.php:119 #: application/views/admin/participants/displayParticipants_view.php:63 @@ -2704,7 +2704,7 @@ msgstr "" #: application/controllers/admin/responses.php:131 #: application/controllers/admin/responses.php:466 -#: application/helpers/common_helper.php:5316 +#: application/helpers/common_helper.php:5447 #: application/helpers/replacements_helper.php:635 #: application/views/admin/export/exportresults_view.php:120 #: application/views/admin/participants/displayParticipants_view.php:64 @@ -2749,7 +2749,7 @@ msgstr[0] "" msgstr[1] "" #: application/controllers/admin/responses.php:647 -#: application/helpers/common_helper.php:2819 +#: application/helpers/common_helper.php:2950 msgid "Total time" msgstr "" @@ -2780,82 +2780,82 @@ msgstr "" msgid "You do not have the Freetype Library installed. Showing charts requires the Freetype library to function properly." msgstr "" -#: application/controllers/admin/surveyadmin.php:408 -#: application/controllers/admin/surveyadmin.php:425 +#: application/controllers/admin/surveyadmin.php:407 +#: application/controllers/admin/surveyadmin.php:424 #: application/views/admin/survey/activateSurvey_view.php:5 #: application/views/admin/survey/activateSurvey_view.php:35 msgid "Activate Survey" msgstr "" -#: application/controllers/admin/surveyadmin.php:411 +#: application/controllers/admin/surveyadmin.php:410 msgid "Survey table could not be created." msgstr "" -#: application/controllers/admin/surveyadmin.php:415 +#: application/controllers/admin/surveyadmin.php:414 msgid "Timings table could not be created." msgstr "" -#: application/controllers/admin/surveyadmin.php:418 +#: application/controllers/admin/surveyadmin.php:417 msgid "Database error!!" msgstr "" -#: application/controllers/admin/surveyadmin.php:426 +#: application/controllers/admin/surveyadmin.php:425 msgid "Survey has been activated. Results table has been successfully created." msgstr "" -#: application/controllers/admin/surveyadmin.php:431 +#: application/controllers/admin/surveyadmin.php:430 msgid "The required directory for saving the uploaded files couldn't be created. Please check file premissions on the /upload/surveys directory." msgstr "" -#: application/controllers/admin/surveyadmin.php:437 +#: application/controllers/admin/surveyadmin.php:436 msgid "This survey allows public registration. A token table must also be created." msgstr "" -#: application/controllers/admin/surveyadmin.php:438 +#: application/controllers/admin/surveyadmin.php:437 #: application/views/admin/token/tokenwarning.php:23 msgid "Initialise tokens" msgstr "" -#: application/controllers/admin/surveyadmin.php:442 +#: application/controllers/admin/surveyadmin.php:441 msgid "This survey is now active, and responses can be recorded." msgstr "" -#: application/controllers/admin/surveyadmin.php:443 +#: application/controllers/admin/surveyadmin.php:442 msgid "Open-access mode" msgstr "" -#: application/controllers/admin/surveyadmin.php:443 +#: application/controllers/admin/surveyadmin.php:442 msgid "No invitation code is needed to complete the survey." msgstr "" -#: application/controllers/admin/surveyadmin.php:443 +#: application/controllers/admin/surveyadmin.php:442 msgid "You can switch to the closed-access mode by initialising a token table with the button below." msgstr "" -#: application/controllers/admin/surveyadmin.php:444 +#: application/controllers/admin/surveyadmin.php:443 msgid "Switch to closed-access mode" msgstr "" -#: application/controllers/admin/surveyadmin.php:445 +#: application/controllers/admin/surveyadmin.php:444 #: application/views/admin/token/tokenwarning.php:24 msgid "No, thanks." msgstr "" -#: application/controllers/admin/surveyadmin.php:548 +#: application/controllers/admin/surveyadmin.php:547 #: application/views/admin/survey/surveybar_view.php:19 msgid "This survey is active but expired." msgstr "" -#: application/controllers/admin/surveyadmin.php:552 +#: application/controllers/admin/surveyadmin.php:551 #: application/views/admin/survey/surveybar_view.php:21 msgid "This survey is active but has a start date." msgstr "" -#: application/controllers/admin/surveyadmin.php:558 +#: application/controllers/admin/surveyadmin.php:557 msgid "This survey is active - click here to stop this survey." msgstr "" -#: application/controllers/admin/surveyadmin.php:562 +#: application/controllers/admin/surveyadmin.php:561 #: application/views/admin/survey/QuestionGroups/questiongroupbar_view.php:105 #: application/views/admin/survey/surveybar_view.php:23 #: application/views/admin/survey/surveybar_view.php:219 @@ -2863,66 +2863,66 @@ msgstr "" msgid "This survey is currently active." msgstr "" -#: application/controllers/admin/surveyadmin.php:572 +#: application/controllers/admin/surveyadmin.php:571 msgid "This survey is currently not active - click here to activate this survey." msgstr "" -#: application/controllers/admin/surveyadmin.php:576 +#: application/controllers/admin/surveyadmin.php:575 msgid "This survey is currently not active." msgstr "" -#: application/controllers/admin/surveyadmin.php:598 +#: application/controllers/admin/surveyadmin.php:597 #: application/views/admin/survey/listSurveys_view.php:36 msgid "Closed" msgstr "" -#: application/controllers/admin/surveyadmin.php:602 +#: application/controllers/admin/surveyadmin.php:601 #: application/views/admin/survey/listSurveys_view.php:35 msgid "Open" msgstr "" -#: application/controllers/admin/surveyadmin.php:673 +#: application/controllers/admin/surveyadmin.php:672 msgid "Survey deleted." msgstr "" -#: application/controllers/admin/surveyadmin.php:748 +#: application/controllers/admin/surveyadmin.php:747 #: application/views/admin/survey/Question/answerOptions_view.php:43 #: application/views/admin/survey/Question/subQuestion_view.php:41 #: application/views/admin/token/managetokenattributes.php:12 msgid "Base Language" msgstr "" -#: application/controllers/admin/surveyadmin.php:809 +#: application/controllers/admin/surveyadmin.php:808 msgid "Import survey data" msgstr "" -#: application/controllers/admin/surveyadmin.php:810 +#: application/controllers/admin/surveyadmin.php:809 msgid "Survey structure import summary" msgstr "" -#: application/controllers/admin/surveyadmin.php:815 +#: application/controllers/admin/surveyadmin.php:814 #: application/views/admin/survey/copySurvey_view.php:1 #: application/views/admin/survey/subview/tabCopy_view.php:21 msgid "Copy survey" msgstr "" -#: application/controllers/admin/surveyadmin.php:816 +#: application/controllers/admin/surveyadmin.php:815 msgid "Survey copy summary" msgstr "" -#: application/controllers/admin/surveyadmin.php:846 +#: application/controllers/admin/surveyadmin.php:845 msgid "Import failed. You specified an invalid file type." msgstr "" -#: application/controllers/admin/surveyadmin.php:883 +#: application/controllers/admin/surveyadmin.php:882 msgid "No survey ID has been provided. Cannot copy survey" msgstr "" -#: application/controllers/admin/surveyadmin.php:1018 +#: application/controllers/admin/surveyadmin.php:1017 msgid "The new question group/question order was successfully saved." msgstr "" -#: application/controllers/admin/surveyadmin.php:1286 +#: application/controllers/admin/surveyadmin.php:1285 #: application/views/admin/labels/labelview_view.php:136 #: application/views/admin/labels/labelview_view.php:148 #: application/views/admin/survey/Question/editQuestion_view.php:269 @@ -2934,21 +2934,21 @@ msgstr "" msgid "Please select a file to import!" msgstr "" -#: application/controllers/admin/surveyadmin.php:1289 +#: application/controllers/admin/surveyadmin.php:1288 #: application/views/admin/labels/labelview_view.php:148 #: application/views/admin/templates/importform_view.php:16 msgid "zip library not supported by PHP, Import ZIP Disabled" msgstr "" -#: application/controllers/admin/surveyadmin.php:1314 +#: application/controllers/admin/surveyadmin.php:1313 msgid "The survey was successfully expired by setting an expiration date in the survey settings." msgstr "" -#: application/controllers/admin/surveyadmin.php:1429 +#: application/controllers/admin/surveyadmin.php:1428 msgid "Survey could not be created because it did not have a title" msgstr "" -#: application/controllers/admin/surveyadmin.php:1561 +#: application/controllers/admin/surveyadmin.php:1560 msgid "Survey was successfully added." msgstr "" @@ -3656,10 +3656,10 @@ msgstr "" #: application/helpers/common_helper.php:621 #: application/helpers/common_helper.php:1274 #: application/helpers/common_helper.php:1344 -#: application/helpers/common_helper.php:6971 -#: application/helpers/common_helper.php:7008 -#: application/helpers/common_helper.php:7404 -#: application/helpers/common_helper.php:7447 +#: application/helpers/common_helper.php:7102 +#: application/helpers/common_helper.php:7139 +#: application/helpers/common_helper.php:7535 +#: application/helpers/common_helper.php:7578 #: application/helpers/qanda_helper.php:1293 #: application/helpers/qanda_helper.php:1474 #: application/helpers/qanda_helper.php:2085 @@ -4050,9 +4050,9 @@ msgstr "" #: application/helpers/common_helper.php:625 #: application/helpers/common_helper.php:1275 #: application/helpers/common_helper.php:1345 -#: application/helpers/common_helper.php:3891 -#: application/helpers/common_helper.php:7405 -#: application/helpers/common_helper.php:7448 +#: application/helpers/common_helper.php:4022 +#: application/helpers/common_helper.php:7536 +#: application/helpers/common_helper.php:7579 #: application/views/admin/token/bounce.php:14 #: application/views/admin/token/bounce.php:57 msgid "None" @@ -4549,7 +4549,7 @@ msgstr "" #: application/helpers/admin/statistics_helper.php:1284 #: application/helpers/admin/statistics_helper.php:1956 #: application/helpers/admin/statistics_helper.php:1977 -#: application/helpers/admin/statistics_helper.php:3400 +#: application/helpers/admin/statistics_helper.php:3403 msgid "Browse" msgstr "" @@ -4648,37 +4648,37 @@ msgid "Page" msgstr "" #: application/helpers/admin/statistics_helper.php:3230 -#: application/helpers/admin/statistics_helper.php:3352 -#: application/helpers/admin/statistics_helper.php:3469 -#: application/helpers/admin/statistics_helper.php:3470 +#: application/helpers/admin/statistics_helper.php:3355 +#: application/helpers/admin/statistics_helper.php:3472 #: application/helpers/admin/statistics_helper.php:3473 +#: application/helpers/admin/statistics_helper.php:3476 #: application/views/admin/participants/displayParticipants_view.php:281 #: application/views/admin/survey/listSurveys_view.php:11 #: application/views/admin/survey/surveybar_view.php:3 msgid "Survey" msgstr "" -#: application/helpers/admin/statistics_helper.php:3324 -#: application/helpers/admin/statistics_helper.php:3343 -#: application/helpers/admin/statistics_helper.php:3362 +#: application/helpers/admin/statistics_helper.php:3327 +#: application/helpers/admin/statistics_helper.php:3346 +#: application/helpers/admin/statistics_helper.php:3365 msgid "Number of records in this query:" msgstr "" -#: application/helpers/admin/statistics_helper.php:3327 -#: application/helpers/admin/statistics_helper.php:3344 -#: application/helpers/admin/statistics_helper.php:3364 +#: application/helpers/admin/statistics_helper.php:3330 +#: application/helpers/admin/statistics_helper.php:3347 +#: application/helpers/admin/statistics_helper.php:3367 msgid "Total records in survey:" msgstr "" -#: application/helpers/admin/statistics_helper.php:3333 -#: application/helpers/admin/statistics_helper.php:3347 -#: application/helpers/admin/statistics_helper.php:3371 +#: application/helpers/admin/statistics_helper.php:3336 +#: application/helpers/admin/statistics_helper.php:3350 +#: application/helpers/admin/statistics_helper.php:3374 msgid "Percentage of total:" msgstr "" -#: application/helpers/admin/statistics_helper.php:3351 -#: application/helpers/admin/statistics_helper.php:3352 -#: application/helpers/admin/statistics_helper.php:3361 +#: application/helpers/admin/statistics_helper.php:3354 +#: application/helpers/admin/statistics_helper.php:3355 +#: application/helpers/admin/statistics_helper.php:3364 msgid "Results" msgstr "" @@ -4999,24 +4999,24 @@ msgstr "" msgid "File count" msgstr "" -#: application/helpers/common_helper.php:2193 +#: application/helpers/common_helper.php:2324 #: application/views/admin/export/statistics_view.php:78 msgid "Response ID" msgstr "" -#: application/helpers/common_helper.php:2201 +#: application/helpers/common_helper.php:2332 msgid "Date submitted" msgstr "" -#: application/helpers/common_helper.php:2209 +#: application/helpers/common_helper.php:2340 msgid "Last page" msgstr "" -#: application/helpers/common_helper.php:2217 +#: application/helpers/common_helper.php:2348 msgid "Start language" msgstr "" -#: application/helpers/common_helper.php:2236 +#: application/helpers/common_helper.php:2367 #: application/helpers/frontend_helper.php:1668 #: application/views/admin/dataentry/caption_view.php:29 #: application/views/admin/export/exportresults_view.php:122 @@ -5028,416 +5028,416 @@ msgstr "" msgid "Token" msgstr "" -#: application/helpers/common_helper.php:2251 +#: application/helpers/common_helper.php:2382 msgid "Date started" msgstr "" -#: application/helpers/common_helper.php:2264 +#: application/helpers/common_helper.php:2395 msgid "Date last action" msgstr "" -#: application/helpers/common_helper.php:2280 +#: application/helpers/common_helper.php:2411 #: application/views/admin/dataentry/caption_view.php:74 #: application/views/admin/saved/savedlist_view.php:8 msgid "IP address" msgstr "" -#: application/helpers/common_helper.php:2291 +#: application/helpers/common_helper.php:2422 msgid "Referrer URL" msgstr "" -#: application/helpers/common_helper.php:2525 +#: application/helpers/common_helper.php:2656 msgid "Scale 1" msgstr "" -#: application/helpers/common_helper.php:2542 +#: application/helpers/common_helper.php:2673 msgid "Scale 2" msgstr "" -#: application/helpers/common_helper.php:2567 +#: application/helpers/common_helper.php:2698 msgid "Rank %s" msgstr "" -#: application/helpers/common_helper.php:2697 +#: application/helpers/common_helper.php:2828 msgid "Other comment" msgstr "" -#: application/helpers/common_helper.php:2826 +#: application/helpers/common_helper.php:2957 msgid "Group time" msgstr "" -#: application/helpers/common_helper.php:2833 +#: application/helpers/common_helper.php:2964 msgid "Question time" msgstr "" -#: application/helpers/common_helper.php:3060 -#: application/helpers/common_helper.php:3071 -#: application/helpers/common_helper.php:3081 -#: application/helpers/common_helper.php:3126 -#: application/helpers/common_helper.php:3142 -#: application/helpers/common_helper.php:3153 -#: application/helpers/common_helper.php:3161 -#: application/helpers/common_helper.php:3172 -#: application/helpers/common_helper.php:3180 -#: application/helpers/common_helper.php:3188 -#: application/helpers/common_helper.php:3197 -#: application/helpers/common_helper.php:3205 -#: application/helpers/common_helper.php:3214 -#: application/helpers/common_helper.php:3420 -#: application/helpers/common_helper.php:3431 -#: application/helpers/common_helper.php:3514 -#: application/helpers/common_helper.php:3522 -#: application/helpers/common_helper.php:3530 -#: application/helpers/common_helper.php:3538 -#: application/helpers/common_helper.php:3549 -#: application/helpers/common_helper.php:3624 -#: application/helpers/common_helper.php:3657 -#: application/helpers/common_helper.php:3677 -#: application/helpers/common_helper.php:3697 -#: application/helpers/common_helper.php:3723 -#: application/helpers/common_helper.php:3733 -#: application/helpers/common_helper.php:3743 -#: application/helpers/common_helper.php:3754 -#: application/helpers/common_helper.php:3816 -#: application/helpers/common_helper.php:3850 -#: application/helpers/common_helper.php:3859 -#: application/helpers/common_helper.php:3867 -#: application/helpers/common_helper.php:3879 -#: application/helpers/common_helper.php:3888 -#: application/helpers/common_helper.php:4100 +#: application/helpers/common_helper.php:3191 +#: application/helpers/common_helper.php:3202 +#: application/helpers/common_helper.php:3212 +#: application/helpers/common_helper.php:3257 +#: application/helpers/common_helper.php:3273 +#: application/helpers/common_helper.php:3284 +#: application/helpers/common_helper.php:3292 +#: application/helpers/common_helper.php:3303 +#: application/helpers/common_helper.php:3311 +#: application/helpers/common_helper.php:3319 +#: application/helpers/common_helper.php:3328 +#: application/helpers/common_helper.php:3336 +#: application/helpers/common_helper.php:3345 +#: application/helpers/common_helper.php:3551 +#: application/helpers/common_helper.php:3562 +#: application/helpers/common_helper.php:3645 +#: application/helpers/common_helper.php:3653 +#: application/helpers/common_helper.php:3661 +#: application/helpers/common_helper.php:3669 +#: application/helpers/common_helper.php:3680 +#: application/helpers/common_helper.php:3755 +#: application/helpers/common_helper.php:3788 +#: application/helpers/common_helper.php:3808 +#: application/helpers/common_helper.php:3828 +#: application/helpers/common_helper.php:3854 +#: application/helpers/common_helper.php:3864 +#: application/helpers/common_helper.php:3874 +#: application/helpers/common_helper.php:3885 +#: application/helpers/common_helper.php:3947 +#: application/helpers/common_helper.php:3981 +#: application/helpers/common_helper.php:3990 +#: application/helpers/common_helper.php:3998 +#: application/helpers/common_helper.php:4010 +#: application/helpers/common_helper.php:4019 +#: application/helpers/common_helper.php:4231 msgid "Display" msgstr "" -#: application/helpers/common_helper.php:3066 +#: application/helpers/common_helper.php:3197 msgid "Sort the answer options alphabetically" msgstr "" -#: application/helpers/common_helper.php:3067 +#: application/helpers/common_helper.php:3198 msgid "Sort answers alphabetically" msgstr "" -#: application/helpers/common_helper.php:3076 +#: application/helpers/common_helper.php:3207 msgid "Set the percentage width of the answer column (1-100)" msgstr "" -#: application/helpers/common_helper.php:3077 +#: application/helpers/common_helper.php:3208 msgid "Answer width" msgstr "" -#: application/helpers/common_helper.php:3085 +#: application/helpers/common_helper.php:3216 msgid "Repeat headings every X subquestions (Set to 0 to deactivate heading repeat, deactivate minimum repeat headings from config)." msgstr "" -#: application/helpers/common_helper.php:3086 +#: application/helpers/common_helper.php:3217 msgid "Repeat headers" msgstr "" -#: application/helpers/common_helper.php:3090 -#: application/helpers/common_helper.php:3098 -#: application/helpers/common_helper.php:3106 -#: application/helpers/common_helper.php:3117 -#: application/helpers/common_helper.php:3134 -#: application/helpers/common_helper.php:3231 -#: application/helpers/common_helper.php:3239 -#: application/helpers/common_helper.php:3247 -#: application/helpers/common_helper.php:3255 -#: application/helpers/common_helper.php:3263 -#: application/helpers/common_helper.php:3271 -#: application/helpers/common_helper.php:3442 -#: application/helpers/common_helper.php:3482 -#: application/helpers/common_helper.php:3635 -#: application/helpers/common_helper.php:3646 -#: application/helpers/common_helper.php:4171 +#: application/helpers/common_helper.php:3221 +#: application/helpers/common_helper.php:3229 +#: application/helpers/common_helper.php:3237 +#: application/helpers/common_helper.php:3248 +#: application/helpers/common_helper.php:3265 +#: application/helpers/common_helper.php:3362 +#: application/helpers/common_helper.php:3370 +#: application/helpers/common_helper.php:3378 +#: application/helpers/common_helper.php:3386 +#: application/helpers/common_helper.php:3394 +#: application/helpers/common_helper.php:3402 +#: application/helpers/common_helper.php:3573 +#: application/helpers/common_helper.php:3613 +#: application/helpers/common_helper.php:3766 +#: application/helpers/common_helper.php:3777 +#: application/helpers/common_helper.php:4302 msgid "Logic" msgstr "" -#: application/helpers/common_helper.php:3093 +#: application/helpers/common_helper.php:3224 msgid "Enter the code(s) of Multiple choice question(s) (separated by semicolons) to only show the matching answer options in this question." msgstr "" -#: application/helpers/common_helper.php:3094 +#: application/helpers/common_helper.php:3225 msgid "Array filter" msgstr "" -#: application/helpers/common_helper.php:3101 +#: application/helpers/common_helper.php:3232 msgid "Enter the code(s) of Multiple choice question(s) (separated by semicolons) to exclude the matching answer options in this question." msgstr "" -#: application/helpers/common_helper.php:3102 +#: application/helpers/common_helper.php:3233 msgid "Array filter exclusion" msgstr "" -#: application/helpers/common_helper.php:3109 +#: application/helpers/common_helper.php:3240 msgid "Hidden" msgstr "" -#: application/helpers/common_helper.php:3110 +#: application/helpers/common_helper.php:3241 #: application/views/admin/survey/QuestionGroups/questiongroupbar_view.php:105 #: application/views/admin/survey/surveybar_view.php:280 msgid "Disabled" msgstr "" -#: application/helpers/common_helper.php:3112 +#: application/helpers/common_helper.php:3243 msgid "Specify how array-filtered sub-questions should be displayed" msgstr "" -#: application/helpers/common_helper.php:3113 +#: application/helpers/common_helper.php:3244 msgid "Array filter style" msgstr "" -#: application/helpers/common_helper.php:3121 +#: application/helpers/common_helper.php:3252 msgid "If one of the subquestions is marked then for each marked subquestion this value is added as assessment." msgstr "" -#: application/helpers/common_helper.php:3122 +#: application/helpers/common_helper.php:3253 #: application/views/admin/labels/labelview_view.php:39 #: application/views/admin/survey/Question/answerOptions_view.php:22 #: application/views/admin/survey/Question/answerOptions_view.php:68 msgid "Assessment value" msgstr "" -#: application/helpers/common_helper.php:3129 -#: application/helpers/common_helper.php:3130 +#: application/helpers/common_helper.php:3260 +#: application/helpers/common_helper.php:3261 msgid "Category separator" msgstr "" -#: application/helpers/common_helper.php:3137 +#: application/helpers/common_helper.php:3268 msgid "Filter the available answers by this value" msgstr "" -#: application/helpers/common_helper.php:3138 +#: application/helpers/common_helper.php:3269 msgid "Code filter" msgstr "" -#: application/helpers/common_helper.php:3148 +#: application/helpers/common_helper.php:3279 msgid "The answer options will be distributed across the number of columns set here" msgstr "" -#: application/helpers/common_helper.php:3149 +#: application/helpers/common_helper.php:3280 msgid "Display columns" msgstr "" -#: application/helpers/common_helper.php:3156 +#: application/helpers/common_helper.php:3287 msgid "How many rows to display" msgstr "" -#: application/helpers/common_helper.php:3157 +#: application/helpers/common_helper.php:3288 msgid "Display rows" msgstr "" -#: application/helpers/common_helper.php:3167 +#: application/helpers/common_helper.php:3298 msgid "Use accessible dropdown boxes instead of calendar popup" msgstr "" -#: application/helpers/common_helper.php:3168 +#: application/helpers/common_helper.php:3299 msgid "Display dropdown boxes" msgstr "" -#: application/helpers/common_helper.php:3175 +#: application/helpers/common_helper.php:3306 msgid "Minimum year value in calendar" msgstr "" -#: application/helpers/common_helper.php:3176 +#: application/helpers/common_helper.php:3307 msgid "Minimum year" msgstr "" -#: application/helpers/common_helper.php:3183 +#: application/helpers/common_helper.php:3314 msgid "Maximum year value for calendar" msgstr "" -#: application/helpers/common_helper.php:3184 +#: application/helpers/common_helper.php:3315 msgid "Maximum year" msgstr "" -#: application/helpers/common_helper.php:3192 +#: application/helpers/common_helper.php:3323 msgid "Prefix|Suffix for dropdown lists" msgstr "" -#: application/helpers/common_helper.php:3193 +#: application/helpers/common_helper.php:3324 msgid "Dropdown prefix/suffix" msgstr "" -#: application/helpers/common_helper.php:3200 +#: application/helpers/common_helper.php:3331 msgid "Post-Answer-Separator|Inter-Dropdownlist-Separator for dropdown lists" msgstr "" -#: application/helpers/common_helper.php:3201 +#: application/helpers/common_helper.php:3332 msgid "Dropdown separator" msgstr "" -#: application/helpers/common_helper.php:3209 +#: application/helpers/common_helper.php:3340 msgid "Enter a header text for the first scale" msgstr "" -#: application/helpers/common_helper.php:3210 +#: application/helpers/common_helper.php:3341 msgid "Header for first scale" msgstr "" -#: application/helpers/common_helper.php:3218 +#: application/helpers/common_helper.php:3349 msgid "Enter a header text for the second scale" msgstr "" -#: application/helpers/common_helper.php:3219 +#: application/helpers/common_helper.php:3350 msgid "Header for second scale" msgstr "" -#: application/helpers/common_helper.php:3223 -#: application/helpers/common_helper.php:3450 -#: application/helpers/common_helper.php:3458 -#: application/helpers/common_helper.php:3474 -#: application/helpers/common_helper.php:3490 -#: application/helpers/common_helper.php:3498 -#: application/helpers/common_helper.php:3568 -#: application/helpers/common_helper.php:4084 -#: application/helpers/common_helper.php:4092 -#: application/helpers/common_helper.php:4183 +#: application/helpers/common_helper.php:3354 +#: application/helpers/common_helper.php:3581 +#: application/helpers/common_helper.php:3589 +#: application/helpers/common_helper.php:3605 +#: application/helpers/common_helper.php:3621 +#: application/helpers/common_helper.php:3629 +#: application/helpers/common_helper.php:3699 +#: application/helpers/common_helper.php:4215 +#: application/helpers/common_helper.php:4223 +#: application/helpers/common_helper.php:4314 msgid "Input" msgstr "" -#: application/helpers/common_helper.php:3226 +#: application/helpers/common_helper.php:3357 msgid "Multiple numeric inputs sum must equal this value" msgstr "" -#: application/helpers/common_helper.php:3227 +#: application/helpers/common_helper.php:3358 msgid "Equals sum value" msgstr "" -#: application/helpers/common_helper.php:3234 +#: application/helpers/common_helper.php:3365 msgid "Enter a boolean equation to validate the whole question." msgstr "" -#: application/helpers/common_helper.php:3235 +#: application/helpers/common_helper.php:3366 msgid "Question validation equation" msgstr "" -#: application/helpers/common_helper.php:3242 +#: application/helpers/common_helper.php:3373 msgid "This is a hint text that will be shown to the participant describing the question validation equation." msgstr "" -#: application/helpers/common_helper.php:3243 +#: application/helpers/common_helper.php:3374 msgid "Question validation tip" msgstr "" -#: application/helpers/common_helper.php:3250 +#: application/helpers/common_helper.php:3381 msgid "Enter a boolean equation to validate each sub-question." msgstr "" -#: application/helpers/common_helper.php:3251 +#: application/helpers/common_helper.php:3382 msgid "Sub-question validation equation" msgstr "" -#: application/helpers/common_helper.php:3258 +#: application/helpers/common_helper.php:3389 msgid "This is a tip shown to the participant describing the sub-question validation equation." msgstr "" -#: application/helpers/common_helper.php:3259 +#: application/helpers/common_helper.php:3390 msgid "Sub-question validation tip" msgstr "" -#: application/helpers/common_helper.php:3266 +#: application/helpers/common_helper.php:3397 msgid "Excludes all other options if a certain answer is selected - just enter the answer code(s) seperated with a semikolon." msgstr "" -#: application/helpers/common_helper.php:3267 +#: application/helpers/common_helper.php:3398 msgid "Exclusive option" msgstr "" -#: application/helpers/common_helper.php:3277 +#: application/helpers/common_helper.php:3408 msgid "If the participant marks all options, uncheck all and check the option set in the \"Exclusive option\" setting" msgstr "" -#: application/helpers/common_helper.php:3278 +#: application/helpers/common_helper.php:3409 msgid "Auto-check exclusive option if all others are checked" msgstr "" -#: application/helpers/common_helper.php:3285 -#: application/helpers/common_helper.php:3296 -#: application/helpers/common_helper.php:3307 -#: application/helpers/common_helper.php:3318 -#: application/helpers/common_helper.php:3361 -#: application/helpers/common_helper.php:3372 -#: application/helpers/common_helper.php:3381 -#: application/helpers/common_helper.php:3390 -#: application/helpers/common_helper.php:3401 -#: application/helpers/common_helper.php:3409 +#: application/helpers/common_helper.php:3416 +#: application/helpers/common_helper.php:3427 +#: application/helpers/common_helper.php:3438 +#: application/helpers/common_helper.php:3449 +#: application/helpers/common_helper.php:3492 +#: application/helpers/common_helper.php:3503 +#: application/helpers/common_helper.php:3512 +#: application/helpers/common_helper.php:3521 +#: application/helpers/common_helper.php:3532 +#: application/helpers/common_helper.php:3540 msgid "Location" msgstr "" -#: application/helpers/common_helper.php:3290 +#: application/helpers/common_helper.php:3421 msgid "Store the city?" msgstr "" -#: application/helpers/common_helper.php:3291 +#: application/helpers/common_helper.php:3422 msgid "Save city" msgstr "" -#: application/helpers/common_helper.php:3301 +#: application/helpers/common_helper.php:3432 msgid "Store the state?" msgstr "" -#: application/helpers/common_helper.php:3302 +#: application/helpers/common_helper.php:3433 msgid "Save state" msgstr "" -#: application/helpers/common_helper.php:3312 +#: application/helpers/common_helper.php:3443 msgid "Store the postal code?" msgstr "" -#: application/helpers/common_helper.php:3313 +#: application/helpers/common_helper.php:3444 msgid "Save postal code" msgstr "" -#: application/helpers/common_helper.php:3323 +#: application/helpers/common_helper.php:3454 msgid "Store the country?" msgstr "" -#: application/helpers/common_helper.php:3324 +#: application/helpers/common_helper.php:3455 msgid "Save country" msgstr "" -#: application/helpers/common_helper.php:3328 -#: application/helpers/common_helper.php:3339 -#: application/helpers/common_helper.php:3350 +#: application/helpers/common_helper.php:3459 +#: application/helpers/common_helper.php:3470 +#: application/helpers/common_helper.php:3481 #: application/models/Survey_permissions.php:68 #: application/views/admin/export/statistics_view.php:1301 msgid "Statistics" msgstr "" -#: application/helpers/common_helper.php:3332 +#: application/helpers/common_helper.php:3463 msgid "Show a map in the statistics?" msgstr "" -#: application/helpers/common_helper.php:3333 +#: application/helpers/common_helper.php:3464 msgid "Display map" msgstr "" -#: application/helpers/common_helper.php:3343 +#: application/helpers/common_helper.php:3474 msgid "Display a chart in the statistics?" msgstr "" -#: application/helpers/common_helper.php:3344 +#: application/helpers/common_helper.php:3475 msgid "Display chart" msgstr "" -#: application/helpers/common_helper.php:3353 +#: application/helpers/common_helper.php:3484 msgid "Bar chart" msgstr "" -#: application/helpers/common_helper.php:3353 +#: application/helpers/common_helper.php:3484 msgid "Pie chart" msgstr "" -#: application/helpers/common_helper.php:3354 +#: application/helpers/common_helper.php:3485 msgid "Select the type of chart to be displayed" msgstr "" -#: application/helpers/common_helper.php:3355 +#: application/helpers/common_helper.php:3486 msgid "Chart type" msgstr "" -#: application/helpers/common_helper.php:3364 -#: application/helpers/common_helper.php:3598 -#: application/helpers/common_helper.php:3700 +#: application/helpers/common_helper.php:3495 +#: application/helpers/common_helper.php:3729 +#: application/helpers/common_helper.php:3831 #: application/views/admin/globalSettings_view.php:228 #: application/views/admin/globalSettings_view.php:240 #: application/views/admin/globalSettings_view.php:261 @@ -5447,420 +5447,420 @@ msgstr "" msgid "Off" msgstr "" -#: application/helpers/common_helper.php:3365 +#: application/helpers/common_helper.php:3496 msgid "Google Maps" msgstr "" -#: application/helpers/common_helper.php:3367 +#: application/helpers/common_helper.php:3498 msgid "Activate this to show a map above the input field where the user can select a location" msgstr "" -#: application/helpers/common_helper.php:3368 +#: application/helpers/common_helper.php:3499 msgid "Use mapping service" msgstr "" -#: application/helpers/common_helper.php:3376 +#: application/helpers/common_helper.php:3507 msgid "Width of the map in pixel" msgstr "" -#: application/helpers/common_helper.php:3377 +#: application/helpers/common_helper.php:3508 msgid "Map width" msgstr "" -#: application/helpers/common_helper.php:3385 +#: application/helpers/common_helper.php:3516 msgid "Height of the map in pixel" msgstr "" -#: application/helpers/common_helper.php:3386 +#: application/helpers/common_helper.php:3517 msgid "Map height" msgstr "" -#: application/helpers/common_helper.php:3396 +#: application/helpers/common_helper.php:3527 msgid "Get the default location using the user's IP address?" msgstr "" -#: application/helpers/common_helper.php:3397 +#: application/helpers/common_helper.php:3528 msgid "IP as default location" msgstr "" -#: application/helpers/common_helper.php:3404 +#: application/helpers/common_helper.php:3535 msgid "Default coordinates of the map when the page first loads. Format: latitude [space] longtitude" msgstr "" -#: application/helpers/common_helper.php:3405 +#: application/helpers/common_helper.php:3536 msgid "Default position" msgstr "" -#: application/helpers/common_helper.php:3413 +#: application/helpers/common_helper.php:3544 msgid "Map zoom level" msgstr "" -#: application/helpers/common_helper.php:3414 +#: application/helpers/common_helper.php:3545 msgid "Zoom level" msgstr "" -#: application/helpers/common_helper.php:3426 +#: application/helpers/common_helper.php:3557 msgid "Hide the tip that is normally shown with a question" msgstr "" -#: application/helpers/common_helper.php:3427 +#: application/helpers/common_helper.php:3558 msgid "Hide tip" msgstr "" -#: application/helpers/common_helper.php:3437 +#: application/helpers/common_helper.php:3568 msgid "Hide this question at any time. This is useful for including data using answer prefilling." msgstr "" -#: application/helpers/common_helper.php:3438 +#: application/helpers/common_helper.php:3569 msgid "Always hide this question" msgstr "" -#: application/helpers/common_helper.php:3445 +#: application/helpers/common_helper.php:3576 msgid "Limit the number of possible answers" msgstr "" -#: application/helpers/common_helper.php:3446 +#: application/helpers/common_helper.php:3577 msgid "Maximum answers" msgstr "" -#: application/helpers/common_helper.php:3453 +#: application/helpers/common_helper.php:3584 msgid "Maximum sum value of multiple numeric input" msgstr "" -#: application/helpers/common_helper.php:3454 +#: application/helpers/common_helper.php:3585 msgid "Maximum sum value" msgstr "" -#: application/helpers/common_helper.php:3461 +#: application/helpers/common_helper.php:3592 msgid "Maximum value of the numeric input" msgstr "" -#: application/helpers/common_helper.php:3462 -#: application/helpers/common_helper.php:3518 +#: application/helpers/common_helper.php:3593 +#: application/helpers/common_helper.php:3649 msgid "Maximum value" msgstr "" -#: application/helpers/common_helper.php:3477 +#: application/helpers/common_helper.php:3608 msgid "Maximum characters allowed" msgstr "" -#: application/helpers/common_helper.php:3478 +#: application/helpers/common_helper.php:3609 msgid "Maximum characters" msgstr "" -#: application/helpers/common_helper.php:3485 +#: application/helpers/common_helper.php:3616 msgid "Ensure a minimum number of possible answers (0=No limit)" msgstr "" -#: application/helpers/common_helper.php:3486 +#: application/helpers/common_helper.php:3617 msgid "Minimum answers" msgstr "" -#: application/helpers/common_helper.php:3493 +#: application/helpers/common_helper.php:3624 msgid "The sum of the multiple numeric inputs must be greater than this value" msgstr "" -#: application/helpers/common_helper.php:3494 +#: application/helpers/common_helper.php:3625 msgid "Minimum sum value" msgstr "" -#: application/helpers/common_helper.php:3501 +#: application/helpers/common_helper.php:3632 msgid "Minimum value of the numeric input" msgstr "" -#: application/helpers/common_helper.php:3502 -#: application/helpers/common_helper.php:3526 +#: application/helpers/common_helper.php:3633 +#: application/helpers/common_helper.php:3657 msgid "Minimum value" msgstr "" -#: application/helpers/common_helper.php:3517 +#: application/helpers/common_helper.php:3648 msgid "Maximum value for array(mult-flexible) question type" msgstr "" -#: application/helpers/common_helper.php:3525 +#: application/helpers/common_helper.php:3656 msgid "Minimum value for array(multi-flexible) question type" msgstr "" -#: application/helpers/common_helper.php:3533 -#: application/helpers/common_helper.php:3534 +#: application/helpers/common_helper.php:3664 +#: application/helpers/common_helper.php:3665 msgid "Step value" msgstr "" -#: application/helpers/common_helper.php:3544 +#: application/helpers/common_helper.php:3675 msgid "Use checkbox layout" msgstr "" -#: application/helpers/common_helper.php:3545 +#: application/helpers/common_helper.php:3676 msgid "Checkbox layout" msgstr "" -#: application/helpers/common_helper.php:3555 +#: application/helpers/common_helper.php:3686 msgid "Present answer options in reverse order" msgstr "" -#: application/helpers/common_helper.php:3556 +#: application/helpers/common_helper.php:3687 msgid "Reverse answer order" msgstr "" -#: application/helpers/common_helper.php:3575 +#: application/helpers/common_helper.php:3706 msgid "Restrict input to integer values" msgstr "" -#: application/helpers/common_helper.php:3576 +#: application/helpers/common_helper.php:3707 msgid "Integer only" msgstr "" -#: application/helpers/common_helper.php:3588 +#: application/helpers/common_helper.php:3719 msgid "Allow only numerical input" msgstr "" -#: application/helpers/common_helper.php:3589 +#: application/helpers/common_helper.php:3720 msgid "Numbers only" msgstr "" -#: application/helpers/common_helper.php:3599 +#: application/helpers/common_helper.php:3730 msgid "Rows" msgstr "" -#: application/helpers/common_helper.php:3600 +#: application/helpers/common_helper.php:3731 msgid "Columns" msgstr "" -#: application/helpers/common_helper.php:3601 +#: application/helpers/common_helper.php:3732 msgid "Both rows and columns" msgstr "" -#: application/helpers/common_helper.php:3604 +#: application/helpers/common_helper.php:3735 msgid "Show totals for either rows, columns or both rows and columns" msgstr "" -#: application/helpers/common_helper.php:3605 +#: application/helpers/common_helper.php:3736 msgid "Show totals for" msgstr "" -#: application/helpers/common_helper.php:3618 +#: application/helpers/common_helper.php:3749 msgid "Show grand total for either columns or rows" msgstr "" -#: application/helpers/common_helper.php:3619 +#: application/helpers/common_helper.php:3750 msgid "Show grand total" msgstr "" -#: application/helpers/common_helper.php:3630 +#: application/helpers/common_helper.php:3761 msgid "Present as text input boxes instead of dropdown lists" msgstr "" -#: application/helpers/common_helper.php:3631 +#: application/helpers/common_helper.php:3762 msgid "Text inputs" msgstr "" -#: application/helpers/common_helper.php:3641 +#: application/helpers/common_helper.php:3772 msgid "Make the 'Other:' comment field mandatory when the 'Other:' option is active" msgstr "" -#: application/helpers/common_helper.php:3642 +#: application/helpers/common_helper.php:3773 msgid "'Other:' comment mandatory" msgstr "" -#: application/helpers/common_helper.php:3652 +#: application/helpers/common_helper.php:3783 msgid "Allow only numerical input for 'Other' text" msgstr "" -#: application/helpers/common_helper.php:3653 +#: application/helpers/common_helper.php:3784 msgid "Numbers only for 'Other'" msgstr "" -#: application/helpers/common_helper.php:3661 +#: application/helpers/common_helper.php:3792 msgid "Replaces the label of the 'Other:' answer option with a custom text" msgstr "" -#: application/helpers/common_helper.php:3662 +#: application/helpers/common_helper.php:3793 msgid "Label for 'Other:' option" msgstr "" -#: application/helpers/common_helper.php:3672 +#: application/helpers/common_helper.php:3803 msgid "Insert a page break before this question in printable view by setting this to Yes." msgstr "" -#: application/helpers/common_helper.php:3673 +#: application/helpers/common_helper.php:3804 msgid "Insert page break in printable view" msgstr "" -#: application/helpers/common_helper.php:3681 +#: application/helpers/common_helper.php:3812 msgid "Add a prefix to the answer field" msgstr "" -#: application/helpers/common_helper.php:3682 +#: application/helpers/common_helper.php:3813 msgid "Answer prefix" msgstr "" -#: application/helpers/common_helper.php:3692 +#: application/helpers/common_helper.php:3823 msgid "Show statistics of this question in the public statistics page" msgstr "" -#: application/helpers/common_helper.php:3693 +#: application/helpers/common_helper.php:3824 msgid "Show in public statistics" msgstr "" -#: application/helpers/common_helper.php:3701 +#: application/helpers/common_helper.php:3832 msgid "Randomize on each page load" msgstr "" -#: application/helpers/common_helper.php:3705 +#: application/helpers/common_helper.php:3836 msgid "Present answers in random order" msgstr "" -#: application/helpers/common_helper.php:3706 +#: application/helpers/common_helper.php:3837 msgid "Random answer order" msgstr "" -#: application/helpers/common_helper.php:3729 +#: application/helpers/common_helper.php:3860 msgid "Show javascript alert" msgstr "" -#: application/helpers/common_helper.php:3730 +#: application/helpers/common_helper.php:3861 msgid "Show an alert if answers exceeds the number of max answers" msgstr "" -#: application/helpers/common_helper.php:3739 +#: application/helpers/common_helper.php:3870 msgid "Same height for all choice" msgstr "" -#: application/helpers/common_helper.php:3740 +#: application/helpers/common_helper.php:3871 msgid "Force each choice to have the same height" msgstr "" -#: application/helpers/common_helper.php:3749 +#: application/helpers/common_helper.php:3880 msgid "Same height for lists" msgstr "" -#: application/helpers/common_helper.php:3750 +#: application/helpers/common_helper.php:3881 msgid "Force the choice list and the rank list to have the same height" msgstr "" -#: application/helpers/common_helper.php:3757 +#: application/helpers/common_helper.php:3888 msgid "Get order from previous question" msgstr "" -#: application/helpers/common_helper.php:3758 +#: application/helpers/common_helper.php:3889 msgid "Enter question ID to get subquestion order from a previous question" msgstr "" -#: application/helpers/common_helper.php:3762 -#: application/helpers/common_helper.php:3773 -#: application/helpers/common_helper.php:3781 -#: application/helpers/common_helper.php:3789 -#: application/helpers/common_helper.php:3797 -#: application/helpers/common_helper.php:3805 -#: application/helpers/common_helper.php:3831 -#: application/helpers/common_helper.php:3842 +#: application/helpers/common_helper.php:3893 +#: application/helpers/common_helper.php:3904 +#: application/helpers/common_helper.php:3912 +#: application/helpers/common_helper.php:3920 +#: application/helpers/common_helper.php:3928 +#: application/helpers/common_helper.php:3936 +#: application/helpers/common_helper.php:3962 +#: application/helpers/common_helper.php:3973 msgid "Slider" msgstr "" -#: application/helpers/common_helper.php:3768 -#: application/helpers/common_helper.php:3769 -#: application/helpers/common_helper.php:3825 -#: application/helpers/common_helper.php:3826 +#: application/helpers/common_helper.php:3899 +#: application/helpers/common_helper.php:3900 +#: application/helpers/common_helper.php:3956 +#: application/helpers/common_helper.php:3957 msgid "Use slider layout" msgstr "" -#: application/helpers/common_helper.php:3776 -#: application/helpers/common_helper.php:3777 +#: application/helpers/common_helper.php:3907 +#: application/helpers/common_helper.php:3908 msgid "Slider minimum value" msgstr "" -#: application/helpers/common_helper.php:3784 -#: application/helpers/common_helper.php:3785 +#: application/helpers/common_helper.php:3915 +#: application/helpers/common_helper.php:3916 msgid "Slider maximum value" msgstr "" -#: application/helpers/common_helper.php:3792 -#: application/helpers/common_helper.php:3793 +#: application/helpers/common_helper.php:3923 +#: application/helpers/common_helper.php:3924 msgid "Slider accuracy" msgstr "" -#: application/helpers/common_helper.php:3800 -#: application/helpers/common_helper.php:3801 +#: application/helpers/common_helper.php:3931 +#: application/helpers/common_helper.php:3932 msgid "Slider initial value" msgstr "" -#: application/helpers/common_helper.php:3811 +#: application/helpers/common_helper.php:3942 msgid "The handle is displayed at the middle of the slider (this will not set the initial value)" msgstr "" -#: application/helpers/common_helper.php:3812 +#: application/helpers/common_helper.php:3943 msgid "Slider starts at the middle position" msgstr "" -#: application/helpers/common_helper.php:3821 +#: application/helpers/common_helper.php:3952 msgid "Yes - stars" msgstr "" -#: application/helpers/common_helper.php:3822 +#: application/helpers/common_helper.php:3953 msgid "Yes - slider with emoticon" msgstr "" -#: application/helpers/common_helper.php:3837 +#: application/helpers/common_helper.php:3968 msgid "Display min and max value under the slider" msgstr "" -#: application/helpers/common_helper.php:3838 +#: application/helpers/common_helper.php:3969 msgid "Display slider min and max value" msgstr "" -#: application/helpers/common_helper.php:3845 +#: application/helpers/common_helper.php:3976 msgid "Answer|Left-slider-text|Right-slider-text separator character" msgstr "" -#: application/helpers/common_helper.php:3846 +#: application/helpers/common_helper.php:3977 msgid "Slider left/right text separator" msgstr "" -#: application/helpers/common_helper.php:3854 +#: application/helpers/common_helper.php:3985 msgid "Add a suffix to the answer field" msgstr "" -#: application/helpers/common_helper.php:3855 +#: application/helpers/common_helper.php:3986 msgid "Answer suffix" msgstr "" -#: application/helpers/common_helper.php:3862 +#: application/helpers/common_helper.php:3993 msgid "Width of text input box" msgstr "" -#: application/helpers/common_helper.php:3863 +#: application/helpers/common_helper.php:3994 msgid "Input box width" msgstr "" -#: application/helpers/common_helper.php:3873 +#: application/helpers/common_helper.php:4004 msgid "Present dropdown control(s) instead of list of radio buttons" msgstr "" -#: application/helpers/common_helper.php:3874 +#: application/helpers/common_helper.php:4005 msgid "Use dropdown presentation" msgstr "" -#: application/helpers/common_helper.php:3883 +#: application/helpers/common_helper.php:4014 msgid "For list dropdown boxes, show up to this many rows" msgstr "" -#: application/helpers/common_helper.php:3884 +#: application/helpers/common_helper.php:4015 msgid "Height of dropdown" msgstr "" -#: application/helpers/common_helper.php:3892 +#: application/helpers/common_helper.php:4023 msgid "Order - like 3)" msgstr "" -#: application/helpers/common_helper.php:3895 +#: application/helpers/common_helper.php:4026 msgid "Accelerator keys for list items" msgstr "" -#: application/helpers/common_helper.php:3896 +#: application/helpers/common_helper.php:4027 msgid "Prefix for list items" msgstr "" -#: application/helpers/common_helper.php:3903 +#: application/helpers/common_helper.php:4034 #: application/views/admin/authentication/login.php:12 #: application/views/admin/user/personalsettings.php:29 #: application/views/admin/user/personalsettings.php:41 @@ -5868,324 +5868,324 @@ msgstr "" msgid "Default" msgstr "" -#: application/helpers/common_helper.php:3904 +#: application/helpers/common_helper.php:4035 msgid "Nominal" msgstr "" -#: application/helpers/common_helper.php:3905 +#: application/helpers/common_helper.php:4036 msgid "Ordinal" msgstr "" -#: application/helpers/common_helper.php:3906 +#: application/helpers/common_helper.php:4037 msgid "Scale" msgstr "" -#: application/helpers/common_helper.php:3908 +#: application/helpers/common_helper.php:4039 msgid "Set a specific SPSS export scale type for this question" msgstr "" -#: application/helpers/common_helper.php:3909 +#: application/helpers/common_helper.php:4040 msgid "SPSS export scale type" msgstr "" -#: application/helpers/common_helper.php:3918 +#: application/helpers/common_helper.php:4049 msgid "Replace choice header (default: \"%s\")" msgstr "" -#: application/helpers/common_helper.php:3919 +#: application/helpers/common_helper.php:4050 msgid "Choice header" msgstr "" -#: application/helpers/common_helper.php:3928 +#: application/helpers/common_helper.php:4059 msgid "Replace rank header (default: \"%s\")" msgstr "" -#: application/helpers/common_helper.php:3929 +#: application/helpers/common_helper.php:4060 msgid "Rank header" msgstr "" -#: application/helpers/common_helper.php:3934 -#: application/helpers/common_helper.php:3942 -#: application/helpers/common_helper.php:3954 -#: application/helpers/common_helper.php:3965 -#: application/helpers/common_helper.php:3976 -#: application/helpers/common_helper.php:3985 -#: application/helpers/common_helper.php:3993 -#: application/helpers/common_helper.php:4001 -#: application/helpers/common_helper.php:4010 -#: application/helpers/common_helper.php:4018 -#: application/helpers/common_helper.php:4026 -#: application/helpers/common_helper.php:4034 -#: application/helpers/common_helper.php:4043 -#: application/helpers/common_helper.php:4051 -#: application/helpers/common_helper.php:4059 -#: application/helpers/common_helper.php:4067 -#: application/helpers/common_helper.php:4076 +#: application/helpers/common_helper.php:4065 +#: application/helpers/common_helper.php:4073 +#: application/helpers/common_helper.php:4085 +#: application/helpers/common_helper.php:4096 +#: application/helpers/common_helper.php:4107 +#: application/helpers/common_helper.php:4116 +#: application/helpers/common_helper.php:4124 +#: application/helpers/common_helper.php:4132 +#: application/helpers/common_helper.php:4141 +#: application/helpers/common_helper.php:4149 +#: application/helpers/common_helper.php:4157 +#: application/helpers/common_helper.php:4165 +#: application/helpers/common_helper.php:4174 +#: application/helpers/common_helper.php:4182 +#: application/helpers/common_helper.php:4190 +#: application/helpers/common_helper.php:4198 +#: application/helpers/common_helper.php:4207 msgid "Timer" msgstr "" -#: application/helpers/common_helper.php:3937 +#: application/helpers/common_helper.php:4068 msgid "Limit time to answer question (in seconds)" msgstr "" -#: application/helpers/common_helper.php:3938 +#: application/helpers/common_helper.php:4069 msgid "Time limit" msgstr "" -#: application/helpers/common_helper.php:3945 +#: application/helpers/common_helper.php:4076 msgid "Warn and move on" msgstr "" -#: application/helpers/common_helper.php:3946 +#: application/helpers/common_helper.php:4077 msgid "Move on without warning" msgstr "" -#: application/helpers/common_helper.php:3947 +#: application/helpers/common_helper.php:4078 msgid "Disable only" msgstr "" -#: application/helpers/common_helper.php:3949 +#: application/helpers/common_helper.php:4080 msgid "Action to perform when time limit is up" msgstr "" -#: application/helpers/common_helper.php:3950 +#: application/helpers/common_helper.php:4081 msgid "Time limit action" msgstr "" -#: application/helpers/common_helper.php:3960 +#: application/helpers/common_helper.php:4091 msgid "Disable the next button until time limit expires" msgstr "" -#: application/helpers/common_helper.php:3961 +#: application/helpers/common_helper.php:4092 msgid "Time limit disable next" msgstr "" -#: application/helpers/common_helper.php:3971 +#: application/helpers/common_helper.php:4102 msgid "Disable the prev button until the time limit expires" msgstr "" -#: application/helpers/common_helper.php:3972 +#: application/helpers/common_helper.php:4103 msgid "Time limit disable prev" msgstr "" -#: application/helpers/common_helper.php:3980 +#: application/helpers/common_helper.php:4111 msgid "The text message that displays in the countdown timer during the countdown" msgstr "" -#: application/helpers/common_helper.php:3981 +#: application/helpers/common_helper.php:4112 msgid "Time limit countdown message" msgstr "" -#: application/helpers/common_helper.php:3988 +#: application/helpers/common_helper.php:4119 msgid "CSS Style for the message that displays in the countdown timer during the countdown" msgstr "" -#: application/helpers/common_helper.php:3989 +#: application/helpers/common_helper.php:4120 msgid "Time limit timer CSS style" msgstr "" -#: application/helpers/common_helper.php:3996 +#: application/helpers/common_helper.php:4127 msgid "Display the 'time limit expiry message' for this many seconds before performing the 'time limit action' (defaults to 1 second if left blank)" msgstr "" -#: application/helpers/common_helper.php:3997 +#: application/helpers/common_helper.php:4128 msgid "Time limit expiry message display time" msgstr "" -#: application/helpers/common_helper.php:4005 +#: application/helpers/common_helper.php:4136 msgid "The message to display when the time limit has expired (a default message will display if this setting is left blank)" msgstr "" -#: application/helpers/common_helper.php:4006 +#: application/helpers/common_helper.php:4137 msgid "Time limit expiry message" msgstr "" -#: application/helpers/common_helper.php:4013 +#: application/helpers/common_helper.php:4144 msgid "CSS style for the 'time limit expiry message'" msgstr "" -#: application/helpers/common_helper.php:4014 +#: application/helpers/common_helper.php:4145 msgid "Time limit message CSS style" msgstr "" -#: application/helpers/common_helper.php:4021 +#: application/helpers/common_helper.php:4152 msgid "Display a 'time limit warning' when there are this many seconds remaining in the countdown (warning will not display if left blank)" msgstr "" -#: application/helpers/common_helper.php:4022 +#: application/helpers/common_helper.php:4153 msgid "1st time limit warning message timer" msgstr "" -#: application/helpers/common_helper.php:4029 +#: application/helpers/common_helper.php:4160 msgid "The 'time limit warning' will stay visible for this many seconds (will not turn off if this setting is left blank)" msgstr "" -#: application/helpers/common_helper.php:4030 +#: application/helpers/common_helper.php:4161 msgid "1st time limit warning message display time" msgstr "" -#: application/helpers/common_helper.php:4038 +#: application/helpers/common_helper.php:4169 msgid "The message to display as a 'time limit warning' (a default warning will display if this is left blank)" msgstr "" -#: application/helpers/common_helper.php:4039 +#: application/helpers/common_helper.php:4170 msgid "1st time limit warning message" msgstr "" -#: application/helpers/common_helper.php:4046 +#: application/helpers/common_helper.php:4177 msgid "CSS style used when the 'time limit warning' message is displayed" msgstr "" -#: application/helpers/common_helper.php:4047 +#: application/helpers/common_helper.php:4178 msgid "1st time limit warning CSS style" msgstr "" -#: application/helpers/common_helper.php:4054 +#: application/helpers/common_helper.php:4185 msgid "Display the 2nd 'time limit warning' when there are this many seconds remaining in the countdown (warning will not display if left blank)" msgstr "" -#: application/helpers/common_helper.php:4055 +#: application/helpers/common_helper.php:4186 msgid "2nd time limit warning message timer" msgstr "" -#: application/helpers/common_helper.php:4062 +#: application/helpers/common_helper.php:4193 msgid "The 2nd 'time limit warning' will stay visible for this many seconds (will not turn off if this setting is left blank)" msgstr "" -#: application/helpers/common_helper.php:4063 +#: application/helpers/common_helper.php:4194 msgid "2nd time limit warning message display time" msgstr "" -#: application/helpers/common_helper.php:4071 +#: application/helpers/common_helper.php:4202 msgid "The 2nd message to display as a 'time limit warning' (a default warning will display if this is left blank)" msgstr "" -#: application/helpers/common_helper.php:4072 +#: application/helpers/common_helper.php:4203 msgid "2nd time limit warning message" msgstr "" -#: application/helpers/common_helper.php:4079 +#: application/helpers/common_helper.php:4210 msgid "CSS style used when the 2nd 'time limit warning' message is displayed" msgstr "" -#: application/helpers/common_helper.php:4080 +#: application/helpers/common_helper.php:4211 msgid "2nd time limit warning CSS style" msgstr "" -#: application/helpers/common_helper.php:4087 +#: application/helpers/common_helper.php:4218 msgid "Specify a custom date/time format (the d/dd m/mm yy/yyyy H/HH M/MM formats and \"-./: \" characters are allowed for day/month/year/hour/minutes without or with leading zero respectively. Defaults to survey's date format" msgstr "" -#: application/helpers/common_helper.php:4088 +#: application/helpers/common_helper.php:4219 msgid "Date/Time format" msgstr "" -#: application/helpers/common_helper.php:4095 +#: application/helpers/common_helper.php:4226 msgid "Minute step interval when using select boxes" msgstr "" -#: application/helpers/common_helper.php:4096 +#: application/helpers/common_helper.php:4227 msgid "Minute step interval" msgstr "" -#: application/helpers/common_helper.php:4103 +#: application/helpers/common_helper.php:4234 msgid "Short names" msgstr "" -#: application/helpers/common_helper.php:4104 +#: application/helpers/common_helper.php:4235 msgid "Full names" msgstr "" -#: application/helpers/common_helper.php:4105 +#: application/helpers/common_helper.php:4236 msgid "Numbers" msgstr "" -#: application/helpers/common_helper.php:4107 +#: application/helpers/common_helper.php:4238 msgid "Change the display style of the month when using select boxes" msgstr "" -#: application/helpers/common_helper.php:4108 +#: application/helpers/common_helper.php:4239 msgid "Month display style" msgstr "" -#: application/helpers/common_helper.php:4112 -#: application/helpers/common_helper.php:4123 +#: application/helpers/common_helper.php:4243 +#: application/helpers/common_helper.php:4254 msgid "File metadata" msgstr "" -#: application/helpers/common_helper.php:4118 +#: application/helpers/common_helper.php:4249 msgid "Is the participant required to give a title to the uploaded file?" msgstr "" -#: application/helpers/common_helper.php:4119 +#: application/helpers/common_helper.php:4250 msgid "Show title" msgstr "" -#: application/helpers/common_helper.php:4129 +#: application/helpers/common_helper.php:4260 msgid "Is the participant required to give a comment to the uploaded file?" msgstr "" -#: application/helpers/common_helper.php:4130 +#: application/helpers/common_helper.php:4261 msgid "Show comment" msgstr "" -#: application/helpers/common_helper.php:4139 +#: application/helpers/common_helper.php:4270 msgid "The participant cannot upload a single file larger than this size" msgstr "" -#: application/helpers/common_helper.php:4140 +#: application/helpers/common_helper.php:4271 msgid "Maximum file size allowed (in KB)" msgstr "" -#: application/helpers/common_helper.php:4148 +#: application/helpers/common_helper.php:4279 msgid "Maximum number of files that the participant can upload for this question" msgstr "" -#: application/helpers/common_helper.php:4149 +#: application/helpers/common_helper.php:4280 msgid "Max number of files" msgstr "" -#: application/helpers/common_helper.php:4157 +#: application/helpers/common_helper.php:4288 msgid "Minimum number of files that the participant must upload for this question" msgstr "" -#: application/helpers/common_helper.php:4158 +#: application/helpers/common_helper.php:4289 msgid "Min number of files" msgstr "" -#: application/helpers/common_helper.php:4166 +#: application/helpers/common_helper.php:4297 msgid "Allowed file types in comma separated format. e.g. pdf,doc,odt" msgstr "" -#: application/helpers/common_helper.php:4167 +#: application/helpers/common_helper.php:4298 msgid "Allowed file types" msgstr "" -#: application/helpers/common_helper.php:4174 +#: application/helpers/common_helper.php:4305 msgid "Place questions into a specified randomization group, all questions included in the specified group will appear in a random order" msgstr "" -#: application/helpers/common_helper.php:4175 +#: application/helpers/common_helper.php:4306 msgid "Randomization group name" msgstr "" -#: application/helpers/common_helper.php:4189 +#: application/helpers/common_helper.php:4320 msgid "Is no answer (missing) allowed when either 'Equals sum value' or 'Minimum sum value' are set?" msgstr "" -#: application/helpers/common_helper.php:4190 +#: application/helpers/common_helper.php:4321 msgid "Value range allows missing" msgstr "" -#: application/helpers/common_helper.php:4324 +#: application/helpers/common_helper.php:4455 msgid "Email was not sent because demo-mode is activated." msgstr "" -#: application/helpers/common_helper.php:4445 +#: application/helpers/common_helper.php:4576 msgid "SMTP debug output:" msgstr "" -#: application/helpers/common_helper.php:5317 +#: application/helpers/common_helper.php:5448 #: application/helpers/replacements_helper.php:642 #: application/views/admin/export/exportresults_view.php:121 #: application/views/admin/saved/savedlist_view.php:10 @@ -6194,132 +6194,132 @@ msgstr "" msgid "Email address" msgstr "" -#: application/helpers/common_helper.php:5318 +#: application/helpers/common_helper.php:5449 msgid "Token code" msgstr "" -#: application/helpers/common_helper.php:5319 +#: application/helpers/common_helper.php:5450 msgid "Language code" msgstr "" -#: application/helpers/common_helper.php:5320 +#: application/helpers/common_helper.php:5451 msgid "Invitation sent date" msgstr "" -#: application/helpers/common_helper.php:5321 +#: application/helpers/common_helper.php:5452 msgid "Last Reminder sent date" msgstr "" -#: application/helpers/common_helper.php:5322 +#: application/helpers/common_helper.php:5453 msgid "Total numbers of sent reminders" msgstr "" -#: application/helpers/common_helper.php:5323 +#: application/helpers/common_helper.php:5454 #: application/views/admin/token/browse.php:75 #: application/views/admin/token/browse.php:141 msgid "Uses left" msgstr "" -#: application/helpers/common_helper.php:5342 +#: application/helpers/common_helper.php:5473 msgid "Attribute %s" msgstr "" -#: application/helpers/common_helper.php:6223 +#: application/helpers/common_helper.php:6354 msgid "Access denied!" msgstr "" -#: application/helpers/common_helper.php:6228 +#: application/helpers/common_helper.php:6359 msgid "You are not allowed dump the database!" msgstr "" -#: application/helpers/common_helper.php:6233 +#: application/helpers/common_helper.php:6364 msgid "You are not allowed export a label set!" msgstr "" -#: application/helpers/common_helper.php:6238 +#: application/helpers/common_helper.php:6369 msgid "You are not allowed to change user data!" msgstr "" -#: application/helpers/common_helper.php:6243 +#: application/helpers/common_helper.php:6374 msgid "You are not allowed to create new surveys!" msgstr "" -#: application/helpers/common_helper.php:6248 +#: application/helpers/common_helper.php:6379 msgid "You are not allowed to delete this survey!" msgstr "" -#: application/helpers/common_helper.php:6253 +#: application/helpers/common_helper.php:6384 msgid "You are not allowed to add new questions for this survey!" msgstr "" -#: application/helpers/common_helper.php:6258 +#: application/helpers/common_helper.php:6389 msgid "You are not allowed to activate this survey!" msgstr "" -#: application/helpers/common_helper.php:6263 +#: application/helpers/common_helper.php:6394 msgid "You are not allowed to stop this survey!" msgstr "" -#: application/helpers/common_helper.php:6268 +#: application/helpers/common_helper.php:6399 msgid "You are not allowed to add a group to this survey!" msgstr "" -#: application/helpers/common_helper.php:6274 +#: application/helpers/common_helper.php:6405 msgid "You are not allowed to order groups in this survey!" msgstr "" -#: application/helpers/common_helper.php:6280 +#: application/helpers/common_helper.php:6411 msgid "You are not allowed to edit this survey!" msgstr "" -#: application/helpers/common_helper.php:6285 +#: application/helpers/common_helper.php:6416 msgid "You are not allowed to edit groups in this survey!" msgstr "" -#: application/helpers/common_helper.php:6290 +#: application/helpers/common_helper.php:6421 msgid "You are not allowed to browse responses!" msgstr "" -#: application/helpers/common_helper.php:6295 +#: application/helpers/common_helper.php:6426 msgid "You are not allowed to set assessment rules!" msgstr "" -#: application/helpers/common_helper.php:6300 +#: application/helpers/common_helper.php:6431 msgid "You are not allowed to delete this group!" msgstr "" -#: application/helpers/common_helper.php:6305 +#: application/helpers/common_helper.php:6436 msgid "You are not allowed to import a survey!" msgstr "" -#: application/helpers/common_helper.php:6311 +#: application/helpers/common_helper.php:6442 msgid "You are not allowed to import a group!" msgstr "" -#: application/helpers/common_helper.php:6316 +#: application/helpers/common_helper.php:6447 msgid "You are not allowed to to import a question!" msgstr "" -#: application/helpers/common_helper.php:6325 -#: application/helpers/common_helper.php:6330 +#: application/helpers/common_helper.php:6456 +#: application/helpers/common_helper.php:6461 msgid "Security alert" msgstr "" -#: application/helpers/common_helper.php:6325 -#: application/helpers/common_helper.php:6330 +#: application/helpers/common_helper.php:6456 +#: application/helpers/common_helper.php:6461 msgid "Someone may be trying to use your LimeSurvey session (CSRF attack suspected). If you just clicked on a malicious link, please report this to your system administrator." msgstr "" -#: application/helpers/common_helper.php:6325 -#: application/helpers/common_helper.php:6330 +#: application/helpers/common_helper.php:6456 +#: application/helpers/common_helper.php:6461 msgid "Also this problem can occur when you are working/editing in LimeSurvey in several browser windows/tabs at the same time." msgstr "" -#: application/helpers/common_helper.php:6335 +#: application/helpers/common_helper.php:6466 msgid "You are not allowed to perform this operation!" msgstr "" -#: application/helpers/common_helper.php:7082 +#: application/helpers/common_helper.php:7213 msgid "SQL command failed: %s" msgstr "" From 3cf9583b4ad2d31be93a0bf383ee55141f5a0bed Mon Sep 17 00:00:00 2001 From: jcleeland Date: Fri, 3 Aug 2012 11:39:03 +1000 Subject: [PATCH 39/75] Fixed issue #06419 - Failed to reproduce statistic with large survey in Yii Branch (missing semi-colon) --- application/helpers/admin/statistics_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/helpers/admin/statistics_helper.php b/application/helpers/admin/statistics_helper.php index 108e6753cb6..7c175b978ea 100644 --- a/application/helpers/admin/statistics_helper.php +++ b/application/helpers/admin/statistics_helper.php @@ -3255,7 +3255,7 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, Yii::import('application.libraries.admin.pear.Spreadsheet.Excel.Xlswriter', true); if($pdfOutput=='F') { - $sFileName = $tempdir.'/statistic-survey'.$surveyid.'.xls' + $sFileName = $tempdir.'/statistic-survey'.$surveyid.'.xls'; $workbook = new Xlswriter($sFileName); } else From 597bee193ecaabde09ac44d6891b74a5449184f1 Mon Sep 17 00:00:00 2001 From: Aaron Schmitz Date: Thu, 2 Aug 2012 21:05:36 -0500 Subject: [PATCH 40/75] Fix PHP Strict Error in qanda_helper.php. Only variables should be passed by reference --- application/helpers/qanda_helper.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application/helpers/qanda_helper.php b/application/helpers/qanda_helper.php index 057e319c330..d79247d99de 100644 --- a/application/helpers/qanda_helper.php +++ b/application/helpers/qanda_helper.php @@ -5285,7 +5285,8 @@ function do_array_multitext($ia) $cellwidth=sprintf('%02d', $cellwidth); $ansquery = "SELECT count(question) FROM {{questions}} WHERE parent_qid={$ia[0]} and scale_id=0 AND question like '%|%'"; - $ansresult = reset(dbExecuteAssoc($ansquery)->read()); + $ansresult = dbExecuteAssoc($ansquery)->read(); + $ansresult = reset($ansresult); if ($ansresult>0) { $right_exists=true; @@ -5992,7 +5993,8 @@ function do_array_dual($ia) $labelans1=array(); $labelans=array(); $qquery = "SELECT other FROM {{questions}} WHERE qid=".$ia[0]." AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."'"; - $other = reset(dbExecuteAssoc($qquery)->read()); //Checked + $other = dbExecuteAssoc($qquery)->read(); + $other = reset($other); //Checked $lquery = "SELECT * FROM {{answers}} WHERE scale_id=0 AND qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY sortorder, code"; $lquery1 = "SELECT * FROM {{answers}} WHERE scale_id=1 AND qid={$ia[0]} AND language='".$_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['s_lang']."' ORDER BY sortorder, code"; $aQuestionAttributes = getQuestionAttributeValues($ia[0], $ia[4]); From b39088c2da1793f247412e6585929b0fa6f418fc Mon Sep 17 00:00:00 2001 From: Aaron Schmitz Date: Fri, 3 Aug 2012 05:21:39 -0500 Subject: [PATCH 41/75] Add missing n to make \n --- application/helpers/qanda_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/helpers/qanda_helper.php b/application/helpers/qanda_helper.php index d79247d99de..4ce24a61fc0 100644 --- a/application/helpers/qanda_helper.php +++ b/application/helpers/qanda_helper.php @@ -4592,7 +4592,7 @@ function do_array_yesnouncertain($ia) $fn++; } } - $answer .= $answer_t_content . "\t\\n\n"; + $answer .= $answer_t_content . "\t\n\n\n"; return array($answer, $inputnames); } From 5d6a388263dab33461aaddbb96f33562fe1a0790 Mon Sep 17 00:00:00 2001 From: Rahmat Awaludin Date: Fri, 3 Aug 2012 17:27:54 +0700 Subject: [PATCH 42/75] fix error PHP Script error in PrintanswersController.php --- application/controllers/PrintanswersController.php | 2 +- application/libraries/admin/pdf.php | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/application/controllers/PrintanswersController.php b/application/controllers/PrintanswersController.php index 2f92deac580..e122aafa4ee 100644 --- a/application/controllers/PrintanswersController.php +++ b/application/controllers/PrintanswersController.php @@ -133,7 +133,7 @@ function actionView($surveyid,$printableexport=FALSE) require (Yii::app()->getConfig('rootdir').'/application/config/tcpdf.php'); Yii::import('application.libraries.admin.pdf', true); $pdf = new pdf(); - $pdf->_config = $tcpdf; + $pdf->setConfig($tcpdf); //$pdf->SetFont($pdfdefaultfont,'',$pdffontsize); $pdf->AddPage(); //$pdf->titleintopdf($clang->gT("Survey name (ID)",'unescaped').": {$surveyname} ({$surveyid})"); diff --git a/application/libraries/admin/pdf.php b/application/libraries/admin/pdf.php index 01473be69db..628383b3432 100644 --- a/application/libraries/admin/pdf.php +++ b/application/libraries/admin/pdf.php @@ -193,6 +193,16 @@ class pdf extends MyPDF { * @access private */ private $_config = array(); + + /** + * Set _config for pdf + * @access public + * @param mixed $tcpdf + * @return + */ + public function setConfig($tcpdf) { + $this->_config=$tcpdf; + } /** From ff25e5b4dd0d80cac756fc39e46b65f030063eb0 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Fri, 3 Aug 2012 13:35:42 +0200 Subject: [PATCH 43/75] Release 2.00 Release Candidate 8 --- application/config/version.php | 2 +- docs/release_notes.txt | 110 +++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 7 deletions(-) diff --git a/application/config/version.php b/application/config/version.php index 2e2118fd64c..56fcc5cbe08 100644 --- a/application/config/version.php +++ b/application/config/version.php @@ -12,7 +12,7 @@ * */ -$config['versionnumber'] = "2.0RC7"; +$config['versionnumber'] = "2.0RC8"; $config['dbversionnumber'] = 161; $config['buildnumber'] = ''; $config['updatable'] = false; diff --git a/docs/release_notes.txt b/docs/release_notes.txt index 49575c7bded..16d6f5afe32 100644 --- a/docs/release_notes.txt +++ b/docs/release_notes.txt @@ -1,5 +1,4 @@ -Welcome to LimeSurvey v2.00 Release Candidate 7! - +Welcome to LimeSurvey v2.00 Release Candidate 8! Warranty: This program is provided "as is" without warranties of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular @@ -21,7 +20,7 @@ Check out detailed requirements at http://docs.limesurvey.org/tiki-index.php?pag HOW TO INSTALL --------------- If you are doing a complete new installation please refer to the manual at -http://docs.limesurvey.org +http://docs.limesurvey.org/Installation+Version+2.0+or+later Please also have a look at the "Installation security hints" section of the online manual in order to secure your installation. @@ -46,9 +45,7 @@ HOW TO UPGRADE from LimeSurvey 1.45 or later (<=1.70) 2. Backup your config.php. 3. Delete all old files 4. Upload the new version to the same place. -5. Adjust the settings in config.php to the setting from the backup config.php. - --Do NOT just copy over the old config.php over the new one.-- -6. Run the installer in /admin/install/index.php to update the database. +6. Run the installer 7. Done. Special note for UPGRADING from 1.53 to 1.72(+) @@ -79,6 +76,107 @@ HOW TO UPGRADE from a LimeSurvey 1.70(+) version to the latest 1.9x Thank you to everyone who helped with this new release! + +Changes from 2.0RC6 to 2.0RC7 (build 120803) Aug 3, 2012 +-New feature: Added link from deactivation page to export page and corrected language (jcleeland) +-New Feature: Added remotecontrol function get_site_settings (Spiros Trougakos) +-New feature: CSS styles for EM's "Show Logic File" feature (Marcel Minke) +-New feature: Dropdown inline search options for jqGrid survey list (useful for active/expired/inactive) (jcleeland) +-New feature: Question save/save and close options - instead of just updating and closing, now choice is to save and keep editing, or to save and return to question view. My wife made me do it. (jcleeland) +-New feature: Remotecontrol functions for manipulation of groups (Spiros Trougakos) +-New feature: Remotecontrol functions for manipulation of questions (Spiros Trougakos) +-New feature: Remotecontrol functions for manipulation of surveys (Spiros Trougakos) +-New feature: Remotecontrol functions for manipulation of tokens (Spiros Trougakos) +-New feature: Sorting for inline text listing in statistics display, also initial sorting for text display of numerical responses. Todo: fix some of the sorting problems for numerical responses (jcleeland) +-New feature: Statistics browse, etc - view file and generic sort icons (jcleeland) +-New feature: Statistics output screen cleaned up, placed inside collapsible divs (jcleeland) +-Updated feature: Remote control functions new naming schema (Spiros Trougakos) +#Updated translation: Czech by slansky +#Updated translation: Turkish by kayazeren +-Fixed issue #6401: Question type list and aample popups fall off the screen (Sam Mousa) +-Fixed issue #5795: No save message at attribute management (jcleeland) +-Fixed issue #6066: File upload fails if single oder double quotes are used (Carsten Schmitz) +-Fixed issue #6067: jqGrid behaviours for editing attributes has errors (jcleeland) +-Fixed issue #6113: Import participants from CSV does not work. Adjusted system settings to cope with mac file endings (jcleeland) +-Fixed issue #6259: PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ls2.lime_surveys' doesn't exist (Carsten Schmitz) +-Fixed issue #6287: Unable to export QueXML with Postgresql 9.1 Fixed issue #6297: QueXML Export broken Dev Removed condition checking for queXML export (Adam Zammit) +-Fixed issue #6340: Error "String offset cast occured" when adding user and using PHP 5.4 or later (Carsten Schmitz) +-Fixed issue #6341: Installation fails if ./tmp/runtime is not writable (Carsten Schmitz) +-Fixed issue #6344: Printable survey shows wrong content for Array (Numbers) (Carsten Schmitz) +-Fixed issue #6346: Statistic page filter not remembering statistics language (Carsten Schmitz) +-Fixed issue #6347: display of question text different in 1.92+ and 2.0 when view question in admin mode (Carsten Schmitz) +-Fixed issue #6348: Bar chart not translated in statistics when changing statistics language (Carsten Schmitz) +-Fixed issue #6349: Condition does not work while using slider with stars (Thomas White) +-Fixed issue #6350: Error html_entity_decode(): charset `ANSI_X3.4-1968' not supported, assuming iso-8859-1 on survey save when sending confirmation email (Carsten Schmitz) +-Fixed issue #6351: Error when deleting a user (Carsten Schmitz) +-Fixed issue #6354: Typo in sPostgres installation script (jcleeland) +-Fixed issue #6355: Change graph type in statistics view not working (jcleeland) +-Fixed issue #6359: Installations with postgres as database fail because of syntax error (jcleeland) +-Fixed issue #6360: No Server time displayed in global settings (Carsten Schmitz) +-Fixed issue #6363: Statistics repsonse filters don't display speaker icon, show question text twice (jcleeland) +-Fixed issue #6363: Updated blobblueish style for earlier fix (jcleeland) +-Fixed issue #6367: Participants database not importing from CSV even though CSV file in correct format (jcleeland) +-Fixed issue #6368: Missing variable after creating function (jcleeland) +-Fixed issue #6371: Statistics not checking selected checkboxes in response filter section after displaying stats (jcleeland) +-Fixed issue #6372: Browse text responses doesn't work. Also reworked much of the stats function a lot of which is still spaghetti code. (jcleeland) +-Fixed issue #6374: Cannot delete survey response (Carsten Schmitz) +-Fixed issue #6377: Large integer values corrupted in survey responses (Carsten Schmitz) +-Fixed issue #6378: Fatal error when editing conditions and using Text (Array) question (Carsten Schmitz) +-Fixed issue #6379: Cannot define default answer for question (Carsten Schmitz) +-Fixed issue #6381: Central participant database, admin language should not determine the list of available surveys (jcleeland) +-Fixed issue #6383: All languages are presented when editing label set even restricted ones (Carsten Schmitz) +-Fixed issue #6385: Graphs produces "Undefined offset: 8" error when there are more than 7 items to display. Problem was the directory location of the pchart color palette. Also some code tidying, changing db calls to use standard Yii models rather than raw SQL. Also fixed bug caused when the 'statistics_graphtype' question attribute did not exist. (jcleeland) +-Fixed issue #6386: Importing CSV labels sets from LS website throws SQL exception (Carsten Schmitz) +-Fixed issue #6387: Broken Add vs Replace Buttons on Quick Add for Labels (tpartner) +-Fixed issue #6388: Graph cannot be changed from bar-graph to pie-graph javascript error occurs. Also added text explanations to the icons for mouseovers. (jcleeland) +-Fixed issue #6389: Changing bar graph to pie graph for text based question fails (jcleeland) +-Fixed issue #6389: Show text responses inline option no longer available. Fixed methodology to improve script efficiency. (jcleeland) +-Fixed issue #6390: Show text responses inline option no longer available in general filter of statistics page (jcleeland) +-Fixed issue #6391: Quartile calculations seem to be wrong. They really were. The limit/offset functions weren't working properly, and the method was calculating quartiles based on sum values, which is just wrong. Corrected methodology and database call, although the database call should probably be improved later. (jcleeland) +-Fixed issue #6392: Language switch question type broken (Carsten Schmitz) +-Fixed issue #6393: Multilingual attributes are lost when copying or importing survey (Carsten Schmitz) +-Fixed issue #6395: QuickAdd permits longer codes than 5 characters (Carsten Schmitz) +-Fixed issue #6397: Non-Superadmin user is unable to create a survey (Carsten Schmitz) +-Fixed issue #6398: New user unable to access CPD (jcleeland) +-Fixed issue #6402: adding participants to survey without selecting individual ones copies participants you don't own (jcleeland) +-Fixed issue #6403: Link from participants grid to surveys bypasses survey permissions (jcleeland) +-Fixed issue #6410: No options for some location atributes (Carsten Schmitz) +-Fixed issue #6419: Failed to reproduce statistic with large survey in Yii Branch (missing semi-colon) (jcleeland) +-Fixed issue: 5 point star rating breaked in Yii (Denis Chenu) +-Fixed issue: Add offset and limit to list_participant (Spiros Trougakos) +-Fixed issue: Change get and set functions(Survey,Group,Question,Tokens) invalid properties check (Spiros Trougakos) +-Fixed issue: Clean up remotecontrol of dublicate functions (Spiros Trougakos) +-Fixed issue: Discriminate get_survey_locale_settings from get_survey_settings function (Spiros Trougakos) +-Fixed issue: Empty settings array returns status message in get-modify survey,group,token (Spiros Trougakos) +-Fixed issue: escaping in statistics browse text responses view, also added title/hover info for browse view (jcleeland) +-Fixed issue: Fixed error messages and functionality in list_surveys (Spiros Trougakos) +-Fixed issue: Fix get_question_properties, set_question_properties, list_questions to take into account multilingual questions (Spiros Trougakos) +-Fixed issue: Fix naming according to hungarian rule (Spiros Trougakos) +-Fixed issue: Fix PHP notice that breaks participants display - strict standards creating default object from empty value (extended version of Aaron's fix) (jcleeland) +-Fixed Issue: Fix wrong function descriptions (Spiros Trougakos) +-Fixed issue: Incorporated token_return functionality into get_token_list (Spiros Trougakos) +-Fixed issue: Link for next/previous breaked (Denis Chenu) +-Fixed issue: more statistics_help script fixes (jcleeland) +-Fixed issue: Move hasSurveyPermission higher to avoid not needed calls (Spiros Trougakos) +-Fixed issue: Move insertParticipant from remotecontrol to model (Spiros Trougakos) +-Fixed issue: Move remotecontrol validation in model (Spiros Trougakos) +-Fixed issue: multiple short text and multiple numerical results in statistics were endlessly looping, continued cleaning up code (jcleeland) +-Fixed issue: numerical calculations in statistics were not working (jcleeland) +-Fixed issue: Printable survey not properly using the configured template (Carsten Schmitz) +-Fixed issue: questions with advanced-settting set to default to bar-graph weren't working in statistics page (jcleeland) +-Fixed issue: Remotecontrol function add_participants (Spiros Trougakos) +-Fixed issue: Removed obsolete features from add_survey (Spiros Trougakos) +-Fixed issue: Remove obsolete RevertUpgradeConditionsToRelevance in delete_group (Spiros Trougakos) +-Fixed issue: Resume later button not showing (Carsten Schmitz) +-Fixed issue: Simplify in export_statistics (Spiros Trougakos) +-Fixed issue: statistics pdf header was referring to old /image directory - updated to default to admin style image directory (jcleeland) +-Fixed issue: statistics script not able to build query selector for array(column) question type (jcleeland) +-Fixed issue: Subquestions and attributes were not properly copied when copying question (Carsten Schmitz) +-Fixed issue: Survey breaking if configured template does not exist (Carsten Schmitz) +-Fixed issue: the background color of the jqGrid loading modal is too dark. This may not be the best colour, but it's better :-) (jcleeland) +-Fixed issue: tokens table not displaying more than 25 entries. Also added sort capabilities. (jcleeland) +-Fixed issue: Path error for certain CSS files. (Aaron Schmitz) + Changes from 2.0RC6 to 2.0RC7 (build 120721) June 20, 2012 -Fixed issue #6192 - PHP notice "undefined variable" when using end URL (jcleeland) -Fixed issue #6277 - case insensitive search now enabled (default search changed ton "cn" (contains) in earlier update) (jcleeland) From 55897201338e7b43af9ceaeb0c83fe2563fd4144 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 4 Aug 2012 00:05:46 +0200 Subject: [PATCH 44/75] Dev Automatic translation update --- locale/_template/limesurvey.pot | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index cd4980c70a9..0ca945c55d0 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-08-02 22:05:44+00:00\n" +"POT-Creation-Date: 2012-08-03 22:05:44+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -1287,12 +1287,12 @@ msgstr "" #: application/helpers/qanda_helper.php:4850 #: application/helpers/qanda_helper.php:4933 #: application/helpers/qanda_helper.php:5065 -#: application/helpers/qanda_helper.php:5856 #: application/helpers/qanda_helper.php:5857 -#: application/helpers/qanda_helper.php:6149 -#: application/helpers/qanda_helper.php:6310 -#: application/helpers/qanda_helper.php:6511 -#: application/helpers/qanda_helper.php:6565 +#: application/helpers/qanda_helper.php:5858 +#: application/helpers/qanda_helper.php:6151 +#: application/helpers/qanda_helper.php:6312 +#: application/helpers/qanda_helper.php:6513 +#: application/helpers/qanda_helper.php:6567 #: application/views/admin/dataentry/content_view.php:29 msgid "No answer" msgstr "" @@ -3663,8 +3663,8 @@ msgstr "" #: application/helpers/qanda_helper.php:1293 #: application/helpers/qanda_helper.php:1474 #: application/helpers/qanda_helper.php:2085 -#: application/helpers/qanda_helper.php:6491 -#: application/helpers/qanda_helper.php:6545 +#: application/helpers/qanda_helper.php:6493 +#: application/helpers/qanda_helper.php:6547 #: application/views/admin/dataentry/content_view.php:84 #: application/views/admin/dataentry/content_view.php:94 #: application/views/admin/labels/labelsetsbar_view.php:22 @@ -7272,7 +7272,7 @@ msgstr "" #: application/helpers/qanda_helper.php:2967 #: application/helpers/qanda_helper.php:3286 #: application/helpers/qanda_helper.php:4517 -#: application/helpers/qanda_helper.php:6362 +#: application/helpers/qanda_helper.php:6364 msgid "Error: This question has no answers." msgstr "" @@ -7300,18 +7300,18 @@ msgid "Drag and drop the pin to the desired location. You may also right click o msgstr "" #: application/helpers/qanda_helper.php:5089 -#: application/helpers/qanda_helper.php:5467 -#: application/helpers/qanda_helper.php:5823 -#: application/helpers/qanda_helper.php:5971 -#: application/helpers/qanda_helper.php:6591 +#: application/helpers/qanda_helper.php:5468 +#: application/helpers/qanda_helper.php:5824 +#: application/helpers/qanda_helper.php:5972 +#: application/helpers/qanda_helper.php:6593 msgid "Error: There are no answer options for this question and/or they don't exist in this language." msgstr "" -#: application/helpers/qanda_helper.php:5740 +#: application/helpers/qanda_helper.php:5741 msgid "..." msgstr "" -#: application/helpers/qanda_helper.php:5965 +#: application/helpers/qanda_helper.php:5966 msgid "Error: There are no answers defined for this question." msgstr "" From 75384ebaec7d2fd5afec217014d21721ebdb6f46 Mon Sep 17 00:00:00 2001 From: Rahmat Awaludin Date: Sat, 4 Aug 2012 15:14:51 +0700 Subject: [PATCH 45/75] Fixed issue PHP Error in statistic_view.php Dev this fix error undefined variable showtextinline Dev when user trying to get statistic from response --- application/controllers/admin/statistics.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/application/controllers/admin/statistics.php b/application/controllers/admin/statistics.php index 545dcccfd21..6e94d566ff0 100644 --- a/application/controllers/admin/statistics.php +++ b/application/controllers/admin/statistics.php @@ -451,13 +451,14 @@ public function run($surveyid, $subaction = null) // ----------------------------------- END FILTER FORM --------------------------------------- Yii::app()->loadHelper('admin/statistics'); + $showtextinline=isset($_POST['showtextinline']) ? 1 : 0; + $aData['showtextinline'] = $showtextinline; + //Show Summary results if (isset($summary) && $summary) { $usegraph=isset($_POST['usegraph']) ? 1 : 0; $aData['usegraph'] = $usegraph; - $showtextinline=isset($_POST['showtextinline']) ? 1 : 0; - $aData['showtextinline'] = $showtextinline; $outputType = $_POST['outputtype']; $selects=buildSelects($summary, $surveyid, $statlang); From 0bc9ad11e27ed8d2a15cd250b9ec4ccaf8effd0c Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Sun, 5 Aug 2012 16:19:32 +0200 Subject: [PATCH 46/75] Fixed issue #6404: No bounce check button Fixed issue: Tokens not listed if related responses record is missing --- application/controllers/admin/tokens.php | 19 +++- application/views/admin/token/browse.php | 3 + scripts/admin/tokens.js | 124 +++++++++++++---------- styles/gringegreen/images/bounce_12.png | Bin 0 -> 456 bytes 4 files changed, 86 insertions(+), 60 deletions(-) create mode 100644 styles/gringegreen/images/bounce_12.png diff --git a/application/controllers/admin/tokens.php b/application/controllers/admin/tokens.php index 47ce7828e6f..14cd44eb77b 100644 --- a/application/controllers/admin/tokens.php +++ b/application/controllers/admin/tokens.php @@ -85,8 +85,12 @@ function bounceprocessing($iSurveyId) $clang = $this->getController()->lang; $thissurvey = getSurveyInfo($iSurveyId); - if (($thissurvey['bounceprocessing'] != 'N' || ($thissurvey['bounceprocessing'] == 'G' && getGlobalSetting('bounceaccounttype') == 'off')) - && hasSurveyPermission($iSurveyId, 'tokens', 'update')) + if (!hasSurveyPermission($iSurveyId, 'tokens', 'update')) + { + $clang->eT("We are sorry but you don't have permissions to do this."); + return; + } + if ($thissurvey['bounceprocessing'] != 'N' || ($thissurvey['bounceprocessing'] == 'G' && getGlobalSetting('bounceaccounttype') != 'off')) { $bouncetotal = 0; $checktotal = 0; @@ -233,9 +237,11 @@ function bounceprocessing($iSurveyId) } else { - $clang->eT("We are sorry but you don't have permissions to do this."); + $clang->eT("Bounce processing is deactivated either application-wide or for this survey in particular."); + return; } + exit; // if bounceprocessing : javascript : no more todo } @@ -401,7 +407,12 @@ function getTokens_json($iSurveyId) } elseif ($token['completed'] != "N" && $token['completed'] != "" && $prow['anonymized'] == "N" ) { //Get the survey response id of the matching entry $id=Survey_dynamic::model($iSurveyId)->findAllByAttributes(array('token'=>$token['token'])); - $action .= 'getController()->createUrl("admin/responses/view/surveyid/{$iSurveyId}/id/{$id[0]['id']}").'", "_top")\'>'; + if (count($id)>0) + { + $action .= 'getController()->createUrl("admin/responses/view/surveyid/{$iSurveyId}/id/{$id[0]['id']}").'", "_top")\'>'; + } else { + $action .= '
    '; + } } else { $action .= '
    '; } diff --git a/application/views/admin/token/browse.php b/application/views/admin/token/browse.php index 3eec8db4289..d15453b526d 100644 --- a/application/views/admin/token/browse.php +++ b/application/views/admin/token/browse.php @@ -70,6 +70,8 @@ var remindmsg = "eT("Send reminder email to the selected entries (if they have already received the invitation email)"); ?>" var inviteurl = "getController()->createUrl("admin/tokens/email/surveyid/{$surveyid}/tids/|"); ?>"; var viewParticipantsLink = "eT("View participants of this survey in the central participant database panel") ?>"; + var sBounceProcessing = "eT("Start bounce processing") ?>"; + var sBounceProcessingURL = "getController()->createUrl('admin/tokens/bounceprocessing/surveyid/' . $surveyid); ?>"; var participantlinkUrl="getController()->createUrl("admin/participants/displayParticipants/searchurl/survey||equal||".$surveyid); ?>"; var searchtypes = ["eT("Equals") ?>","eT("Contains") ?>","eT("Not equal") ?>","eT("Not contains") ?>","eT("Greater than") ?>","eT("Less than") ?>"] var colNames = ["ID","eT("Action") ?>","eT("First name") ?>","eT("Last name") ?>","eT("Email address") ?>","eT("Email status") ?>","eT("Token") ?>","eT("Language") ?>","eT("Invitation sent?") ?>","eT("Reminder sent?") ?>","eT("Reminder count") ?>","eT("Completed?") ?>","eT("Uses left") ?>","eT("Valid from") ?>","eT("Valid until") ?>",]; @@ -204,3 +206,4 @@ function sendPost(myaction,checkcode,arrayparam,arrayval)
    +
    \ No newline at end of file diff --git a/scripts/admin/tokens.js b/scripts/admin/tokens.js index 3902e21595d..a6f923588cf 100644 --- a/scripts/admin/tokens.js +++ b/scripts/admin/tokens.js @@ -1,5 +1,12 @@ // $Id: tokens.js 8633 2010-04-25 12:57:33Z c_schmitz var idexternal=parseInt(3); + +function checkbounces() { + $("#dialog-modal").dialog('open'); + $('#dialog-modal').html('

    '); + $('#dialog-modal').load(sBounceProcessingURL); +} + function addcondition() { id=2; @@ -20,20 +27,8 @@ function addcondition() } $(document).ready(function() { - $("#bounceprocessing").change(turnoff); turnoff(); - $('img#bounceprocessing').bind('click',function(){ - $("#dialog-modal").dialog({ - title: "Summary", - modal: true, - autoOpen: false, - height: 200, - width: 400, - show: 'blind', - hide: 'blind' - }); - checkbounces(surveyid); - }); + $("#filterduplicatetoken").change(function(){ if ($("#filterduplicatetoken").attr('checked')==true) { $("#lifilterduplicatefields").slideDown(); @@ -57,20 +52,20 @@ $(document).ready(function() { // Code for AJAX download jQuery.download = function(url, data, method){ - //url and data options required - if( url && data ){ - //data can be string of parameters or array/object - data = typeof data == 'string' ? data : jQuery.param(data); - //split params into form inputs - var inputs = ''; - jQuery.each(data.split('&'), function(){ - var pair = this.split('='); - inputs+=''; - }); - //send request - jQuery('
    '+inputs+'
    ') - .appendTo('body').submit().remove(); - }; + //url and data options required + if( url && data ){ + //data can be string of parameters or array/object + data = typeof data == 'string' ? data : jQuery.param(data); + //split params into form inputs + var inputs = ''; + jQuery.each(data.split('&'), function(){ + var pair = this.split('='); + inputs+=''; + }); + //send request + jQuery('
    '+inputs+'
    ') + .appendTo('body').submit().remove(); + }; }; // Code for AJAX download var id=1; @@ -131,8 +126,8 @@ $(document).ready(function() { loadComplete: function() { /* Sneaky way of adding custom icons to jqGrid pager buttons */ - $("#pager").find(".ui-participant-link") - .css({"background-image":"url("+imageurl+"cpdb_12.png)", "background-position":"0", "color":"black"}); + $("#pager").find(".ui-participant-link").css({"background-image":"url("+imageurl+"cpdb_12.png)", "background-position":"0", "color":"black"}); + $("#pager").find(".ui-bounceprocessing").css({"background-image":"url("+imageurl+"bounce_12.png)", "background-position":"0", "color":"black"}); window.editing = false; jQuery(".token_edit").unbind('click').bind('click', function(e) { @@ -164,15 +159,15 @@ $(document).ready(function() { }); jQuery('') - .appendTo(jQuery(this).parent()) - .click(func); + .appendTo(jQuery(this).parent()) + .click(func); jQuery('') - .appendTo(jQuery(this).parent()) - .click(function() - { - jQuery('#displaytokens').saveRow(row.attr('id')); - func(); - }); + .appendTo(jQuery(this).parent()) + .click(function() + { + jQuery('#displaytokens').saveRow(row.attr('id')); + func(); + }); }); }, ondblClickRow: function(id) @@ -205,10 +200,10 @@ $(document).ready(function() { }, beforeSubmit : function(postdata, formid) { $.post(delUrl, { - tid : postdata - }, - function(data) {} - ); + tid : postdata + }, + function(data) {} + ); success = "dummy"; message = "dummy"; return[success,message]; @@ -235,24 +230,24 @@ $(document).ready(function() { var dialog_buttons={}; if($('#field_1').val() == '') { dialog_buttons[okBtn]=function(){ - $( this ).dialog( "close" ); + $( this ).dialog( "close" ); }; /* End of building array for button functions */ $('#fieldnotselected').dialog({ - modal: true, + modal: true, title: error, - buttons: dialog_buttons + buttons: dialog_buttons }); } else if($('#condition_1').val()=="") { dialog_buttons[okBtn]=function(){ - $( this ).dialog( "close" ); + $( this ).dialog( "close" ); }; /* End of building array for button functions */ $('#conditionnotselected').dialog({ - modal: true, + modal: true, title: error, - buttons: dialog_buttons + buttons: dialog_buttons }); } else { if(id == 1) { @@ -275,7 +270,7 @@ $(document).ready(function() { var dialog_buttons={}; dialog_buttons[okBtn]=function(){ $( this ).dialog( "close" ); - }; + }; $("

    "+noSearchResultsTxt+"

    ").dialog({ modal: true, buttons: dialog_buttons, @@ -287,9 +282,9 @@ $(document).ready(function() { $(this).dialog("close"); } }; - dialog_buttons[cancelBtn]=function(){ + dialog_buttons[cancelBtn]=function(){ $(this).dialog("close"); - }; + }; dialog_buttons[resetBtn]=function(){ jQuery("#displaytokens").jqGrid('setGridParam',{ url:jsonUrl, @@ -309,14 +304,14 @@ $(document).ready(function() { }); $("#displaytokens").jqGrid('setGridParam', { search: false, postData: { "filters": ""} }).trigger("reloadGrid"); }; - /* End of building array for button functions */ - $("#search").dialog({ + /* End of building array for button functions */ + $("#search").dialog({ height: 300, - width: 750, - modal: true, + width: 750, + modal: true, title : 'Full Search', - buttons: dialog_buttons - }); + buttons: dialog_buttons + }); } }); $("#displaytokens").navButtonAdd('#pager',{ @@ -343,6 +338,23 @@ $(document).ready(function() { window.open(participantlinkUrl, "_top"); } }); + $("#displaytokens").navButtonAdd('#pager', { + caption:"", + title:sBounceProcessing, + buttonicon:'ui-bounceprocessing', + onClickButton:function(){ + $("#dialog-modal").dialog({ + title: "Summary", + modal: true, + autoOpen: false, + height: 200, + width: 400, + show: 'blind', + hide: 'blind' + }); + checkbounces(); + } + }); $.extend(jQuery.jgrid.edit,{ closeAfterAdd: true, reloadAfterSubmit: true, diff --git a/styles/gringegreen/images/bounce_12.png b/styles/gringegreen/images/bounce_12.png new file mode 100644 index 0000000000000000000000000000000000000000..cd828c27f2991aefbf1bffe341f1fd37cefe1fff GIT binary patch literal 456 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&kmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l;AAzh%5%0eGP;eC*)Vo z0SZc$xJHx&=ckpFCl;kL1SDqWmFW4ohA5O7>zV2q8W?;jTFAh_DBJ|Ba?|H*_COGn?rXcK@LJ1qGMM+qT!RZuD5;xIv=j+q4@;)Dj(>T&!O>DY5DA zt$S{@eP?g=#ax4HFDz|N+idv0TKMdQZ> zD{acS;}Y+&FdH!5PMDg#;T5Y-$>V)*P1Zb`xJ!FsS*%6d+@{Eg&wlqKZog#uc2sHN z#+o&LE7!^XS^8+D+G(BWb=k9)*jhA{zg}{H^`6;Z20`z5!T&z@SC%Z2e|>>lt Date: Sun, 5 Aug 2012 18:01:11 +0200 Subject: [PATCH 47/75] Fixed issue #6380: Error while exporting survey results to Excel --- application/controllers/admin/export.php | 1 + application/helpers/admin/statistics_helper.php | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/application/controllers/admin/export.php b/application/controllers/admin/export.php index 1589ced64f1..c6b87016082 100644 --- a/application/controllers/admin/export.php +++ b/application/controllers/admin/export.php @@ -1322,6 +1322,7 @@ private function _exportexcel($surveyid) // actually generate an Excel workbook $workbook = new xlswriter; $workbook->setVersion(8); + $workbook->setTempDir(Yii::app()->getConfig("tempdir")); $workbook->send($fn); $sheet =& $workbook->addWorksheet(); // do not translate/change this - the library does not support any special chars in sheet name diff --git a/application/helpers/admin/statistics_helper.php b/application/helpers/admin/statistics_helper.php index 7c175b978ea..a636f762e7e 100644 --- a/application/helpers/admin/statistics_helper.php +++ b/application/helpers/admin/statistics_helper.php @@ -3262,6 +3262,10 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, $workbook = new Xlswriter(); $workbook->setVersion(8); + // Inform the module that our data will arrive as UTF-8. + // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) + $workbook->setTempDir($tempdir); + // Inform the module that our data will arrive as UTF-8. // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) if (!empty($tempdir)) { From 9351790fc8717109f832cb8d967f5d5fa39384dc Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Sun, 5 Aug 2012 18:36:38 +0200 Subject: [PATCH 48/75] Fixed issue #6412: "SAVE" button visible when importing --- application/views/admin/responses/browseindex_view.php | 4 ++-- application/views/admin/survey/newSurvey_view.php | 2 +- application/views/admin/survey/subview/tab_view.php | 9 +++++++++ scripts/admin/surveysettings.js | 6 ++++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/application/views/admin/responses/browseindex_view.php b/application/views/admin/responses/browseindex_view.php index 205ffc65131..14ef5d9cb2d 100644 --- a/application/views/admin/responses/browseindex_view.php +++ b/application/views/admin/responses/browseindex_view.php @@ -1,5 +1,5 @@ -
    eT("Response summary"); ?>
    + @@ -8,7 +8,7 @@
    eT("Response summary"); ?>
    eT("Total responses:"); ?>
    eT("Full responses:"); ?>
    - + diff --git a/application/views/admin/survey/newSurvey_view.php b/application/views/admin/survey/newSurvey_view.php index 59e561c9a4e..84dc4d8bf78 100644 --- a/application/views/admin/survey/newSurvey_view.php +++ b/application/views/admin/survey/newSurvey_view.php @@ -25,7 +25,7 @@ ?> -

    diff --git a/application/views/admin/survey/subview/tab_view.php b/application/views/admin/survey/subview/tab_view.php index 59eabffbd94..5ce82cebab4 100644 --- a/application/views/admin/survey/subview/tab_view.php +++ b/application/views/admin/survey/subview/tab_view.php @@ -1,3 +1,12 @@ +
    • eT("General"); ?>
    • diff --git a/scripts/admin/surveysettings.js b/scripts/admin/surveysettings.js index f3bc7af7bc1..a09ab544c3f 100644 --- a/scripts/admin/surveysettings.js +++ b/scripts/admin/surveysettings.js @@ -52,6 +52,12 @@ $(document).ready(function(){ $('#btnSave').click(saveParameter); $('#addnewsurvey').submit(PostParameterGrid); + $( "#tabs" ).bind( "tabsselect", function(event, ui) { + if (ui.index>4) + {$('#btnSave').hide();} + else + {$('#btnSave').show();} +}); }); From 2db1ffeb5b07b828c93904500b86ab8db26b38f1 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 6 Aug 2012 00:05:48 +0200 Subject: [PATCH 49/75] Dev Automatic translation update --- locale/_template/limesurvey.pot | 398 ++++++++++++++++---------------- 1 file changed, 203 insertions(+), 195 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index 0ca945c55d0..f012303fd84 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-08-03 22:05:44+00:00\n" +"POT-Creation-Date: 2012-08-05 22:05:45+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -82,9 +82,9 @@ msgstr "" #: application/views/admin/survey/importSurvey_view.php:14 #: application/views/admin/templates/importuploaded_view.php:25 #: application/views/admin/token/browse.php:45 -#: application/views/admin/token/browse.php:190 -#: application/views/admin/token/browse.php:195 -#: application/views/admin/token/browse.php:200 +#: application/views/admin/token/browse.php:192 +#: application/views/admin/token/browse.php:197 +#: application/views/admin/token/browse.php:202 #: application/views/admin/token/ldapform.php:2 msgid "Error" msgstr "" @@ -101,7 +101,7 @@ msgstr "" #: application/controllers/AdminController.php:86 #: application/controllers/admin/surveyadmin.php:419 -#: application/controllers/admin/tokens.php:2184 +#: application/controllers/admin/tokens.php:2195 #: application/helpers/admin/import_helper.php:2612 #: application/views/admin/authentication/forgotpassword.php:15 #: application/views/admin/dataentry/active_html_view.php:95 @@ -758,8 +758,8 @@ msgstr "" #: application/controllers/admin/conditionsaction.php:86 #: application/views/admin/participants/displayParticipants_view.php:76 #: application/views/admin/participants/displayParticipants_view.php:189 -#: application/views/admin/token/browse.php:74 -#: application/views/admin/token/browse.php:150 +#: application/views/admin/token/browse.php:76 +#: application/views/admin/token/browse.php:152 msgid "Less than" msgstr "" @@ -787,8 +787,8 @@ msgstr "" #: application/controllers/admin/conditionsaction.php:91 #: application/views/admin/participants/displayParticipants_view.php:75 #: application/views/admin/participants/displayParticipants_view.php:188 -#: application/views/admin/token/browse.php:74 -#: application/views/admin/token/browse.php:149 +#: application/views/admin/token/browse.php:76 +#: application/views/admin/token/browse.php:151 msgid "Greater than" msgstr "" @@ -844,7 +844,7 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:517 #: application/controllers/admin/surveyadmin.php:607 -#: application/controllers/admin/tokens.php:2101 +#: application/controllers/admin/tokens.php:2112 #: application/core/Survey_Common_Action.php:827 #: application/helpers/admin/statistics_helper.php:1456 #: application/helpers/admin/statistics_helper.php:1589 @@ -948,7 +948,7 @@ msgid "Yes" msgstr "" #: application/controllers/admin/conditionsaction.php:181 -#: application/controllers/admin/tokens.php:2164 +#: application/controllers/admin/tokens.php:2175 #: application/views/admin/assessments_view.php:122 #: application/views/admin/conditions/includes/conditions_scenario.php:13 #: application/views/admin/labels/labelview_view.php:161 @@ -978,7 +978,7 @@ msgid "We recommend that before you proceed, you export the entire survey from t msgstr "" #: application/controllers/admin/conditionsaction.php:190 -#: application/controllers/admin/tokens.php:1458 +#: application/controllers/admin/tokens.php:1469 #: application/controllers/admin/useraction.php:157 #: application/views/admin/dataentry/import.php:31 #: application/views/admin/survey/Question/questionbar_view.php:193 @@ -1006,8 +1006,8 @@ msgstr "" #: application/controllers/admin/surveypermission.php:329 #: application/controllers/admin/surveypermission.php:502 #: application/controllers/admin/surveypermission.php:595 -#: application/controllers/admin/tokens.php:2303 -#: application/controllers/admin/tokens.php:2338 +#: application/controllers/admin/tokens.php:2314 +#: application/controllers/admin/tokens.php:2349 #: application/controllers/admin/useraction.php:720 #: application/helpers/common_helper.php:6360 #: application/helpers/common_helper.php:6365 @@ -1096,7 +1096,7 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:518 #: application/controllers/admin/surveyadmin.php:611 -#: application/controllers/admin/tokens.php:2103 +#: application/controllers/admin/tokens.php:2114 #: application/core/Survey_Common_Action.php:823 #: application/helpers/admin/statistics_helper.php:1457 #: application/helpers/admin/statistics_helper.php:1590 @@ -1787,8 +1787,8 @@ msgid "Save" msgstr "" #: application/controllers/admin/dataentry.php:1587 -#: application/controllers/admin/tokens.php:854 -#: application/controllers/admin/tokens.php:1025 +#: application/controllers/admin/tokens.php:865 +#: application/controllers/admin/tokens.php:1036 #: application/controllers/admin/useraction.php:149 #: application/views/admin/dataentry/insert.php:73 #: application/views/admin/dataentry/iteratesurvey.php:5 @@ -1932,223 +1932,223 @@ msgid "The answer(s) must meet these array_filter criteria:" msgstr "" #: application/controllers/admin/dataentry.php:2495 -#: application/controllers/admin/tokens.php:1793 +#: application/controllers/admin/tokens.php:1804 #: application/views/admin/participants/importCSV_view.php:17 msgid "ARMSCII-8 Armenian" msgstr "" #: application/controllers/admin/dataentry.php:2496 -#: application/controllers/admin/tokens.php:1794 +#: application/controllers/admin/tokens.php:1805 #: application/views/admin/participants/importCSV_view.php:18 msgid "US ASCII" msgstr "" #: application/controllers/admin/dataentry.php:2497 -#: application/controllers/admin/tokens.php:1795 +#: application/controllers/admin/tokens.php:1806 #: application/views/admin/participants/importCSV_view.php:19 msgid "Automatic" msgstr "" #: application/controllers/admin/dataentry.php:2498 -#: application/controllers/admin/tokens.php:1796 +#: application/controllers/admin/tokens.php:1807 #: application/views/admin/participants/importCSV_view.php:20 msgid "Big5 Traditional Chinese" msgstr "" #: application/controllers/admin/dataentry.php:2499 -#: application/controllers/admin/tokens.php:1797 +#: application/controllers/admin/tokens.php:1808 #: application/views/admin/participants/importCSV_view.php:21 msgid "Binary pseudo charset" msgstr "" #: application/controllers/admin/dataentry.php:2500 -#: application/controllers/admin/tokens.php:1798 +#: application/controllers/admin/tokens.php:1809 #: application/views/admin/participants/importCSV_view.php:22 msgid "Windows Central European" msgstr "" #: application/controllers/admin/dataentry.php:2501 -#: application/controllers/admin/tokens.php:1799 +#: application/controllers/admin/tokens.php:1810 #: application/views/admin/participants/importCSV_view.php:23 msgid "Windows Cyrillic" msgstr "" #: application/controllers/admin/dataentry.php:2502 -#: application/controllers/admin/tokens.php:1800 +#: application/controllers/admin/tokens.php:1811 #: application/views/admin/participants/importCSV_view.php:24 msgid "Windows Arabic" msgstr "" #: application/controllers/admin/dataentry.php:2503 -#: application/controllers/admin/tokens.php:1801 +#: application/controllers/admin/tokens.php:1812 #: application/views/admin/participants/importCSV_view.php:25 msgid "Windows Baltic" msgstr "" #: application/controllers/admin/dataentry.php:2504 -#: application/controllers/admin/tokens.php:1802 +#: application/controllers/admin/tokens.php:1813 #: application/views/admin/participants/importCSV_view.php:26 msgid "DOS West European" msgstr "" #: application/controllers/admin/dataentry.php:2505 -#: application/controllers/admin/tokens.php:1803 +#: application/controllers/admin/tokens.php:1814 #: application/views/admin/participants/importCSV_view.php:27 msgid "DOS Central European" msgstr "" #: application/controllers/admin/dataentry.php:2506 -#: application/controllers/admin/tokens.php:1804 +#: application/controllers/admin/tokens.php:1815 #: application/views/admin/participants/importCSV_view.php:28 msgid "DOS Russian" msgstr "" #: application/controllers/admin/dataentry.php:2507 -#: application/controllers/admin/tokens.php:1805 +#: application/controllers/admin/tokens.php:1816 #: application/views/admin/participants/importCSV_view.php:29 msgid "SJIS for Windows Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2508 -#: application/controllers/admin/tokens.php:1806 +#: application/controllers/admin/tokens.php:1817 #: application/views/admin/participants/importCSV_view.php:30 msgid "DEC West European" msgstr "" #: application/controllers/admin/dataentry.php:2509 -#: application/controllers/admin/tokens.php:1807 +#: application/controllers/admin/tokens.php:1818 #: application/views/admin/participants/importCSV_view.php:31 msgid "UJIS for Windows Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2510 -#: application/controllers/admin/tokens.php:1808 +#: application/controllers/admin/tokens.php:1819 #: application/views/admin/participants/importCSV_view.php:32 msgid "EUC-KR Korean" msgstr "" #: application/controllers/admin/dataentry.php:2511 -#: application/controllers/admin/tokens.php:1809 +#: application/controllers/admin/tokens.php:1820 #: application/views/admin/participants/importCSV_view.php:33 msgid "GB2312 Simplified Chinese" msgstr "" #: application/controllers/admin/dataentry.php:2512 -#: application/controllers/admin/tokens.php:1810 +#: application/controllers/admin/tokens.php:1821 #: application/views/admin/participants/importCSV_view.php:34 msgid "GBK Simplified Chinese" msgstr "" #: application/controllers/admin/dataentry.php:2513 -#: application/controllers/admin/tokens.php:1811 +#: application/controllers/admin/tokens.php:1822 #: application/views/admin/participants/importCSV_view.php:35 msgid "GEOSTD8 Georgian" msgstr "" #: application/controllers/admin/dataentry.php:2514 -#: application/controllers/admin/tokens.php:1812 +#: application/controllers/admin/tokens.php:1823 #: application/views/admin/participants/importCSV_view.php:36 msgid "ISO 8859-7 Greek" msgstr "" #: application/controllers/admin/dataentry.php:2515 -#: application/controllers/admin/tokens.php:1813 +#: application/controllers/admin/tokens.php:1824 #: application/views/admin/participants/importCSV_view.php:37 msgid "ISO 8859-8 Hebrew" msgstr "" #: application/controllers/admin/dataentry.php:2516 -#: application/controllers/admin/tokens.php:1814 +#: application/controllers/admin/tokens.php:1825 #: application/views/admin/participants/importCSV_view.php:38 msgid "HP West European" msgstr "" #: application/controllers/admin/dataentry.php:2517 -#: application/controllers/admin/tokens.php:1815 +#: application/controllers/admin/tokens.php:1826 #: application/views/admin/participants/importCSV_view.php:39 msgid "DOS Kamenicky Czech-Slovak" msgstr "" #: application/controllers/admin/dataentry.php:2518 -#: application/controllers/admin/tokens.php:1816 +#: application/controllers/admin/tokens.php:1827 #: application/views/admin/participants/importCSV_view.php:40 msgid "KOI8-R Relcom Russian" msgstr "" #: application/controllers/admin/dataentry.php:2519 -#: application/controllers/admin/tokens.php:1817 +#: application/controllers/admin/tokens.php:1828 #: application/views/admin/participants/importCSV_view.php:41 msgid "KOI8-U Ukrainian" msgstr "" #: application/controllers/admin/dataentry.php:2520 -#: application/controllers/admin/tokens.php:1818 +#: application/controllers/admin/tokens.php:1829 #: application/views/admin/participants/importCSV_view.php:42 msgid "cp1252 West European" msgstr "" #: application/controllers/admin/dataentry.php:2521 -#: application/controllers/admin/tokens.php:1819 +#: application/controllers/admin/tokens.php:1830 #: application/views/admin/participants/importCSV_view.php:43 msgid "ISO 8859-2 Central European" msgstr "" #: application/controllers/admin/dataentry.php:2522 -#: application/controllers/admin/tokens.php:1820 +#: application/controllers/admin/tokens.php:1831 #: application/views/admin/participants/importCSV_view.php:44 msgid "ISO 8859-9 Turkish" msgstr "" #: application/controllers/admin/dataentry.php:2523 -#: application/controllers/admin/tokens.php:1821 +#: application/controllers/admin/tokens.php:1832 #: application/views/admin/participants/importCSV_view.php:45 msgid "ISO 8859-13 Baltic" msgstr "" #: application/controllers/admin/dataentry.php:2524 -#: application/controllers/admin/tokens.php:1822 +#: application/controllers/admin/tokens.php:1833 #: application/views/admin/participants/importCSV_view.php:46 msgid "Mac Central European" msgstr "" #: application/controllers/admin/dataentry.php:2525 -#: application/controllers/admin/tokens.php:1823 +#: application/controllers/admin/tokens.php:1834 #: application/views/admin/participants/importCSV_view.php:47 msgid "Mac West European" msgstr "" #: application/controllers/admin/dataentry.php:2526 -#: application/controllers/admin/tokens.php:1824 +#: application/controllers/admin/tokens.php:1835 #: application/views/admin/participants/importCSV_view.php:48 msgid "Shift-JIS Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2527 -#: application/controllers/admin/tokens.php:1825 +#: application/controllers/admin/tokens.php:1836 #: application/views/admin/participants/importCSV_view.php:49 msgid "7bit Swedish" msgstr "" #: application/controllers/admin/dataentry.php:2528 -#: application/controllers/admin/tokens.php:1826 +#: application/controllers/admin/tokens.php:1837 #: application/views/admin/participants/importCSV_view.php:50 msgid "TIS620 Thai" msgstr "" #: application/controllers/admin/dataentry.php:2529 -#: application/controllers/admin/tokens.php:1827 +#: application/controllers/admin/tokens.php:1838 #: application/views/admin/participants/importCSV_view.php:51 msgid "UCS-2 Unicode" msgstr "" #: application/controllers/admin/dataentry.php:2530 -#: application/controllers/admin/tokens.php:1828 +#: application/controllers/admin/tokens.php:1839 #: application/views/admin/participants/importCSV_view.php:52 msgid "EUC-JP Japanese" msgstr "" #: application/controllers/admin/dataentry.php:2531 -#: application/controllers/admin/tokens.php:1829 +#: application/controllers/admin/tokens.php:1840 #: application/views/admin/participants/importCSV_view.php:53 msgid "UTF-8 Unicode" msgstr "" @@ -2695,8 +2695,8 @@ msgstr "" #: application/views/admin/participants/displayParticipants_view.php:154 #: application/views/admin/participants/displayParticipants_view.php:173 #: application/views/admin/participants/sharePanel_view.php:7 -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:131 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:133 #: application/views/admin/token/dummytokenform.php:13 #: application/views/admin/token/tokenform.php:30 msgid "First name" @@ -2711,8 +2711,8 @@ msgstr "" #: application/views/admin/participants/displayParticipants_view.php:154 #: application/views/admin/participants/displayParticipants_view.php:174 #: application/views/admin/participants/sharePanel_view.php:8 -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:132 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:134 #: application/views/admin/token/dummytokenform.php:15 #: application/views/admin/token/tokenform.php:35 msgid "Last name" @@ -2962,7 +2962,7 @@ msgstr "" #: application/views/admin/quotas/viewquotas_view.php:19 #: application/views/admin/survey/Question/subQuestion_view.php:80 #: application/views/admin/survey/subview/tabPanelIntegration_view.php:8 -#: application/views/admin/token/browse.php:75 +#: application/views/admin/token/browse.php:77 #: application/views/admin/user/editusers.php:5 #: application/views/admin/usergroup/viewUserGroup_view.php:33 msgid "Action" @@ -3006,8 +3006,8 @@ msgid "Delete" msgstr "" #: application/controllers/admin/surveypermission.php:109 -#: application/controllers/admin/tokens.php:408 -#: application/controllers/admin/tokens.php:485 +#: application/controllers/admin/tokens.php:419 +#: application/controllers/admin/tokens.php:496 #: application/views/admin/assessments_view.php:32 #: application/views/admin/responses/browseidheader_view.php:14 #: application/views/admin/saved/savedlist_view.php:29 @@ -3113,7 +3113,7 @@ msgstr "" #: application/controllers/admin/surveypermission.php:403 #: application/views/admin/dataentry/vvimport.php:35 -#: application/views/admin/survey/subview/tab_view.php:9 +#: application/views/admin/survey/subview/tab_view.php:18 msgid "Import" msgstr "" @@ -3361,255 +3361,259 @@ msgstr "" msgid "The survey you selected does not exist" msgstr "" -#: application/controllers/admin/tokens.php:222 -msgid "%s messages were scanned out of which %s were marked as bounce by the system." +#: application/controllers/admin/tokens.php:90 +#: application/controllers/survey/index.php:83 +#: application/controllers/survey/index.php:96 +msgid "We are sorry but you don't have permissions to do this." msgstr "" #: application/controllers/admin/tokens.php:226 +msgid "%s messages were scanned out of which %s were marked as bounce by the system." +msgstr "" + +#: application/controllers/admin/tokens.php:230 msgid "%s messages were scanned, none were marked as bounce by the system." msgstr "" -#: application/controllers/admin/tokens.php:231 +#: application/controllers/admin/tokens.php:235 msgid "Please check your settings" msgstr "" -#: application/controllers/admin/tokens.php:236 -#: application/controllers/survey/index.php:83 -#: application/controllers/survey/index.php:96 -msgid "We are sorry but you don't have permissions to do this." +#: application/controllers/admin/tokens.php:240 +msgid "Bounce processing is deactivated either application-wide or for this survey in particular." msgstr "" -#: application/controllers/admin/tokens.php:400 -#: application/controllers/admin/tokens.php:476 +#: application/controllers/admin/tokens.php:406 +#: application/controllers/admin/tokens.php:487 msgid "Do survey" msgstr "" -#: application/controllers/admin/tokens.php:404 -#: application/controllers/admin/tokens.php:480 +#: application/controllers/admin/tokens.php:412 +#: application/controllers/admin/tokens.php:491 #: application/views/admin/responses/browseallrow_view.php:4 #: application/views/admin/responses/browsetimerow_view.php:4 msgid "View response details" msgstr "" -#: application/controllers/admin/tokens.php:408 -#: application/controllers/admin/tokens.php:485 +#: application/controllers/admin/tokens.php:419 +#: application/controllers/admin/tokens.php:496 msgid "Delete token entry" msgstr "" -#: application/controllers/admin/tokens.php:414 -#: application/controllers/admin/tokens.php:491 +#: application/controllers/admin/tokens.php:425 +#: application/controllers/admin/tokens.php:502 msgid "Send invitation email to this person (if they have not yet been sent an invitation email)" msgstr "" -#: application/controllers/admin/tokens.php:416 -#: application/controllers/admin/tokens.php:493 +#: application/controllers/admin/tokens.php:427 +#: application/controllers/admin/tokens.php:504 msgid "Send reminder email to this person (if they have already received the invitation email)" msgstr "" -#: application/controllers/admin/tokens.php:423 -#: application/controllers/admin/tokens.php:498 +#: application/controllers/admin/tokens.php:434 +#: application/controllers/admin/tokens.php:509 #: application/views/admin/token/tokenform.php:5 msgid "Edit token entry" msgstr "" -#: application/controllers/admin/tokens.php:425 -#: application/controllers/admin/tokens.php:500 +#: application/controllers/admin/tokens.php:436 +#: application/controllers/admin/tokens.php:511 msgid "View this person in the central participants database" msgstr "" -#: application/controllers/admin/tokens.php:602 -#: application/controllers/admin/tokens.php:633 -#: application/controllers/admin/tokens.php:739 -#: application/controllers/admin/tokens.php:844 -#: application/controllers/admin/tokens.php:972 +#: application/controllers/admin/tokens.php:613 +#: application/controllers/admin/tokens.php:644 +#: application/controllers/admin/tokens.php:750 +#: application/controllers/admin/tokens.php:855 +#: application/controllers/admin/tokens.php:983 msgid "%s cannot be empty" msgstr "" -#: application/controllers/admin/tokens.php:855 +#: application/controllers/admin/tokens.php:866 msgid "The token entry was successfully updated." msgstr "" -#: application/controllers/admin/tokens.php:856 -#: application/controllers/admin/tokens.php:1027 +#: application/controllers/admin/tokens.php:867 #: application/controllers/admin/tokens.php:1038 +#: application/controllers/admin/tokens.php:1049 #: application/views/admin/token/addtokenpost.php:7 #: application/views/admin/token/addtokenpost.php:14 #: application/views/admin/token/tokenbar.php:12 msgid "Display tokens" msgstr "" -#: application/controllers/admin/tokens.php:862 -#: application/controllers/admin/tokens.php:1034 +#: application/controllers/admin/tokens.php:873 +#: application/controllers/admin/tokens.php:1045 #: application/views/admin/token/addtokenpost.php:12 #: application/views/admin/token/ldappost.php:5 msgid "Failed" msgstr "" -#: application/controllers/admin/tokens.php:863 +#: application/controllers/admin/tokens.php:874 #: application/views/admin/token/addtokenpost.php:13 msgid "There is already an entry with that exact token in the table. The same token cannot be used in multiple entries." msgstr "" -#: application/controllers/admin/tokens.php:864 +#: application/controllers/admin/tokens.php:875 msgid "Show this token entry" msgstr "" -#: application/controllers/admin/tokens.php:1026 +#: application/controllers/admin/tokens.php:1037 msgid "New dummy tokens were added." msgstr "" -#: application/controllers/admin/tokens.php:1035 +#: application/controllers/admin/tokens.php:1046 msgid "Only %s new dummy tokens were added after %s trials." msgstr "" -#: application/controllers/admin/tokens.php:1036 +#: application/controllers/admin/tokens.php:1047 msgid "Try with a bigger token length." msgstr "" -#: application/controllers/admin/tokens.php:1141 +#: application/controllers/admin/tokens.php:1152 msgid "%s field(s) were successfully added." msgstr "" -#: application/controllers/admin/tokens.php:1142 -#: application/controllers/admin/tokens.php:1193 +#: application/controllers/admin/tokens.php:1153 +#: application/controllers/admin/tokens.php:1204 msgid "Back to attribute field management." msgstr "" -#: application/controllers/admin/tokens.php:1192 +#: application/controllers/admin/tokens.php:1203 msgid "Token attribute descriptions were successfully updated." msgstr "" -#: application/controllers/admin/tokens.php:1390 +#: application/controllers/admin/tokens.php:1401 msgid "Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) delayed: Token is not yet valid." msgstr "" -#: application/controllers/admin/tokens.php:1394 +#: application/controllers/admin/tokens.php:1405 msgid "Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) skipped: Token is not valid anymore." msgstr "" -#: application/controllers/admin/tokens.php:1404 +#: application/controllers/admin/tokens.php:1415 msgid "Invitation sent to:" msgstr "" -#: application/controllers/admin/tokens.php:1409 +#: application/controllers/admin/tokens.php:1420 msgid "Reminder sent to:" msgstr "" -#: application/controllers/admin/tokens.php:1427 +#: application/controllers/admin/tokens.php:1438 msgid "Email to {FIRSTNAME} {LASTNAME} ({EMAIL}) failed. Error Message:" msgstr "" -#: application/controllers/admin/tokens.php:1459 +#: application/controllers/admin/tokens.php:1470 msgid "There were no eligible emails to send. This will be because none satisfied the criteria of:" msgstr "" -#: application/controllers/admin/tokens.php:1460 +#: application/controllers/admin/tokens.php:1471 msgid "having a valid email address" msgstr "" -#: application/controllers/admin/tokens.php:1461 +#: application/controllers/admin/tokens.php:1472 msgid "not having been sent an invitation already" msgstr "" -#: application/controllers/admin/tokens.php:1462 +#: application/controllers/admin/tokens.php:1473 msgid "having already completed the survey" msgstr "" -#: application/controllers/admin/tokens.php:1463 +#: application/controllers/admin/tokens.php:1474 msgid "having a token" msgstr "" -#: application/controllers/admin/tokens.php:1545 +#: application/controllers/admin/tokens.php:1556 msgid "Uploading LDAP Query" msgstr "" -#: application/controllers/admin/tokens.php:1758 +#: application/controllers/admin/tokens.php:1769 msgid "Can't bind to the LDAP directory" msgstr "" -#: application/controllers/admin/tokens.php:1765 +#: application/controllers/admin/tokens.php:1776 msgid "Can't connect to the LDAP directory" msgstr "" -#: application/controllers/admin/tokens.php:2098 -#: application/controllers/admin/tokens.php:2125 +#: application/controllers/admin/tokens.php:2109 +#: application/controllers/admin/tokens.php:2136 msgid "Create tokens" msgstr "" -#: application/controllers/admin/tokens.php:2099 +#: application/controllers/admin/tokens.php:2110 msgid "Clicking 'Yes' will generate tokens for all those in this token list that have not been issued one. Continue?" msgstr "" -#: application/controllers/admin/tokens.php:2116 +#: application/controllers/admin/tokens.php:2127 msgid "Only %s token has been created." msgid_plural "Only %s tokens have been created." msgstr[0] "" msgstr[1] "" -#: application/controllers/admin/tokens.php:2117 +#: application/controllers/admin/tokens.php:2128 msgid "Need %s token." msgid_plural "Need %s tokens." msgstr[0] "" msgstr[1] "" -#: application/controllers/admin/tokens.php:2122 +#: application/controllers/admin/tokens.php:2133 msgid "%s token has been created." msgid_plural "%s tokens have been created." msgstr[0] "" msgstr[1] "" -#: application/controllers/admin/tokens.php:2158 -#: application/controllers/admin/tokens.php:2180 +#: application/controllers/admin/tokens.php:2169 +#: application/controllers/admin/tokens.php:2191 msgid "Delete Tokens Table" msgstr "" -#: application/controllers/admin/tokens.php:2159 +#: application/controllers/admin/tokens.php:2170 msgid "If you delete this table tokens will no longer be required to access this survey." msgstr "" -#: application/controllers/admin/tokens.php:2159 +#: application/controllers/admin/tokens.php:2170 msgid "A backup of this table will be made if you proceed. Your system administrator will be able to access this table." msgstr "" -#: application/controllers/admin/tokens.php:2162 +#: application/controllers/admin/tokens.php:2173 msgid "Delete Tokens" msgstr "" -#: application/controllers/admin/tokens.php:2181 +#: application/controllers/admin/tokens.php:2192 msgid "The tokens table has now been removed and tokens are no longer required to access this survey." msgstr "" -#: application/controllers/admin/tokens.php:2181 +#: application/controllers/admin/tokens.php:2192 msgid "A backup of this table has been made and can be accessed by your system administrator." msgstr "" -#: application/controllers/admin/tokens.php:2226 +#: application/controllers/admin/tokens.php:2237 #: application/views/admin/globalSettings_view.php:10 #: application/views/admin/token/bounce.php:1 #: application/views/admin/token/tokenbar.php:78 msgid "Bounce settings" msgstr "" -#: application/controllers/admin/tokens.php:2227 +#: application/controllers/admin/tokens.php:2238 msgid "Bounce settings have been saved." msgstr "" -#: application/controllers/admin/tokens.php:2300 +#: application/controllers/admin/tokens.php:2311 #: application/views/admin/export/exportresults_view.php:115 #: application/views/admin/token/tokenbar.php:3 #: application/views/admin/token/tokenwarning.php:3 msgid "Token control" msgstr "" -#: application/controllers/admin/tokens.php:2301 +#: application/controllers/admin/tokens.php:2312 msgid "A token table has been created for this survey." msgstr "" -#: application/controllers/admin/tokens.php:2335 +#: application/controllers/admin/tokens.php:2346 msgid "Import old tokens" msgstr "" -#: application/controllers/admin/tokens.php:2336 +#: application/controllers/admin/tokens.php:2347 msgid "A token table has been created for this survey and the old tokens were imported." msgstr "" @@ -4549,7 +4553,7 @@ msgstr "" #: application/helpers/admin/statistics_helper.php:1284 #: application/helpers/admin/statistics_helper.php:1956 #: application/helpers/admin/statistics_helper.php:1977 -#: application/helpers/admin/statistics_helper.php:3403 +#: application/helpers/admin/statistics_helper.php:3407 msgid "Browse" msgstr "" @@ -4648,37 +4652,37 @@ msgid "Page" msgstr "" #: application/helpers/admin/statistics_helper.php:3230 -#: application/helpers/admin/statistics_helper.php:3355 -#: application/helpers/admin/statistics_helper.php:3472 -#: application/helpers/admin/statistics_helper.php:3473 +#: application/helpers/admin/statistics_helper.php:3359 #: application/helpers/admin/statistics_helper.php:3476 +#: application/helpers/admin/statistics_helper.php:3477 +#: application/helpers/admin/statistics_helper.php:3480 #: application/views/admin/participants/displayParticipants_view.php:281 #: application/views/admin/survey/listSurveys_view.php:11 #: application/views/admin/survey/surveybar_view.php:3 msgid "Survey" msgstr "" -#: application/helpers/admin/statistics_helper.php:3327 -#: application/helpers/admin/statistics_helper.php:3346 -#: application/helpers/admin/statistics_helper.php:3365 +#: application/helpers/admin/statistics_helper.php:3331 +#: application/helpers/admin/statistics_helper.php:3350 +#: application/helpers/admin/statistics_helper.php:3369 msgid "Number of records in this query:" msgstr "" -#: application/helpers/admin/statistics_helper.php:3330 -#: application/helpers/admin/statistics_helper.php:3347 -#: application/helpers/admin/statistics_helper.php:3367 +#: application/helpers/admin/statistics_helper.php:3334 +#: application/helpers/admin/statistics_helper.php:3351 +#: application/helpers/admin/statistics_helper.php:3371 msgid "Total records in survey:" msgstr "" -#: application/helpers/admin/statistics_helper.php:3336 -#: application/helpers/admin/statistics_helper.php:3350 -#: application/helpers/admin/statistics_helper.php:3374 +#: application/helpers/admin/statistics_helper.php:3340 +#: application/helpers/admin/statistics_helper.php:3354 +#: application/helpers/admin/statistics_helper.php:3378 msgid "Percentage of total:" msgstr "" -#: application/helpers/admin/statistics_helper.php:3354 -#: application/helpers/admin/statistics_helper.php:3355 -#: application/helpers/admin/statistics_helper.php:3364 +#: application/helpers/admin/statistics_helper.php:3358 +#: application/helpers/admin/statistics_helper.php:3359 +#: application/helpers/admin/statistics_helper.php:3368 msgid "Results" msgstr "" @@ -5021,8 +5025,8 @@ msgstr "" #: application/views/admin/dataentry/caption_view.php:29 #: application/views/admin/export/exportresults_view.php:122 #: application/views/admin/participants/attributeMap_view.php:95 -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:135 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:137 #: application/views/admin/token/tokenform.php:56 #: application/views/entertoken_view.php:15 msgid "Token" @@ -6189,8 +6193,8 @@ msgstr "" #: application/helpers/replacements_helper.php:642 #: application/views/admin/export/exportresults_view.php:121 #: application/views/admin/saved/savedlist_view.php:10 -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:133 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:135 msgid "Email address" msgstr "" @@ -6215,8 +6219,8 @@ msgid "Total numbers of sent reminders" msgstr "" #: application/helpers/common_helper.php:5454 -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:141 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:143 msgid "Uses left" msgstr "" @@ -7927,7 +7931,7 @@ msgid "Permission to view/update the survey settings including token table creat msgstr "" #: application/models/Survey_permissions.php:75 -#: application/views/admin/survey/subview/tab_view.php:7 +#: application/views/admin/survey/subview/tab_view.php:16 msgid "Tokens" msgstr "" @@ -8032,8 +8036,8 @@ msgstr "" #: application/views/admin/participants/displayParticipants_view.php:68 #: application/views/admin/participants/displayParticipants_view.php:154 #: application/views/admin/participants/displayParticipants_view.php:179 -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:136 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:138 #: application/views/admin/token/dummytokenform.php:19 #: application/views/admin/token/tokenform.php:66 msgid "Language" @@ -8656,7 +8660,7 @@ msgstr "" #: application/views/admin/export/exportresults_view.php:8 #: application/views/admin/globalSettings_view.php:8 -#: application/views/admin/survey/subview/tab_view.php:3 +#: application/views/admin/survey/subview/tab_view.php:12 msgid "General" msgstr "" @@ -10131,22 +10135,22 @@ msgstr "" #: application/views/admin/participants/displayParticipants_view.php:71 #: application/views/admin/participants/displayParticipants_view.php:183 -#: application/views/admin/token/browse.php:74 -#: application/views/admin/token/browse.php:145 +#: application/views/admin/token/browse.php:76 +#: application/views/admin/token/browse.php:147 msgid "Equals" msgstr "" #: application/views/admin/participants/displayParticipants_view.php:72 #: application/views/admin/participants/displayParticipants_view.php:184 -#: application/views/admin/token/browse.php:74 -#: application/views/admin/token/browse.php:146 +#: application/views/admin/token/browse.php:76 +#: application/views/admin/token/browse.php:148 msgid "Contains" msgstr "" #: application/views/admin/participants/displayParticipants_view.php:73 #: application/views/admin/participants/displayParticipants_view.php:186 -#: application/views/admin/token/browse.php:74 -#: application/views/admin/token/browse.php:147 +#: application/views/admin/token/browse.php:76 +#: application/views/admin/token/browse.php:149 msgid "Not equal" msgstr "" @@ -10858,7 +10862,7 @@ msgstr "" msgid "Show next..." msgstr "" -#: application/views/admin/responses/browseindex_view.php:1 +#: application/views/admin/responses/browseindex_view.php:2 msgid "Response summary" msgstr "" @@ -12518,27 +12522,27 @@ msgstr "" msgid "Set token length to:" msgstr "" -#: application/views/admin/survey/subview/tab_view.php:4 +#: application/views/admin/survey/subview/tab_view.php:13 msgid "Presentation & navigation" msgstr "" -#: application/views/admin/survey/subview/tab_view.php:5 +#: application/views/admin/survey/subview/tab_view.php:14 msgid "Publication & access control" msgstr "" -#: application/views/admin/survey/subview/tab_view.php:6 +#: application/views/admin/survey/subview/tab_view.php:15 msgid "Notification & data management" msgstr "" -#: application/views/admin/survey/subview/tab_view.php:10 +#: application/views/admin/survey/subview/tab_view.php:19 msgid "Copy" msgstr "" -#: application/views/admin/survey/subview/tab_view.php:13 +#: application/views/admin/survey/subview/tab_view.php:22 msgid "Panel integration" msgstr "" -#: application/views/admin/survey/subview/tab_view.php:14 +#: application/views/admin/survey/subview/tab_view.php:23 msgid "Resources" msgstr "" @@ -12995,72 +12999,76 @@ msgstr "" msgid "View participants of this survey in the central participant database panel" msgstr "" -#: application/views/admin/token/browse.php:74 -#: application/views/admin/token/browse.php:148 +#: application/views/admin/token/browse.php:73 +msgid "Start bounce processing" +msgstr "" + +#: application/views/admin/token/browse.php:76 +#: application/views/admin/token/browse.php:150 msgid "Not contains" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:134 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:136 msgid "Email status" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:137 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:139 #: application/views/admin/token/tokenform.php:79 msgid "Invitation sent?" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:138 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:140 #: application/views/admin/token/tokenform.php:91 msgid "Reminder sent?" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:139 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:141 msgid "Reminder count" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:140 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:142 #: application/views/admin/token/tokenform.php:109 msgid "Completed?" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:142 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:144 #: application/views/admin/token/dummytokenform.php:24 #: application/views/admin/token/tokenform.php:133 msgid "Valid from" msgstr "" -#: application/views/admin/token/browse.php:75 -#: application/views/admin/token/browse.php:143 +#: application/views/admin/token/browse.php:77 +#: application/views/admin/token/browse.php:145 msgid "Valid until" msgstr "" -#: application/views/admin/token/browse.php:157 +#: application/views/admin/token/browse.php:159 msgid "Add another search criteria" msgstr "" -#: application/views/admin/token/browse.php:168 +#: application/views/admin/token/browse.php:170 msgid "Add participants to central database" msgstr "" -#: application/views/admin/token/browse.php:170 +#: application/views/admin/token/browse.php:172 msgid "Please select the attributes that are to be added to the central database" msgstr "" -#: application/views/admin/token/browse.php:192 +#: application/views/admin/token/browse.php:194 msgid "Please select a field." msgstr "" -#: application/views/admin/token/browse.php:197 +#: application/views/admin/token/browse.php:199 msgid "Please select a condition." msgstr "" -#: application/views/admin/token/browse.php:202 +#: application/views/admin/token/browse.php:204 msgid "Please select at least one participant." msgstr "" From c5097eaf3206da7acbe5d40cec38fbe9e9fbacec Mon Sep 17 00:00:00 2001 From: jcleeland Date: Mon, 6 Aug 2012 09:49:13 +1000 Subject: [PATCH 50/75] Fixed issue #6430 - Central Participant Database: List of participants does not scale well with the number of attributes --- .../views/admin/participants/displayParticipants_view.php | 4 ++++ scripts/admin/displayParticipant.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/application/views/admin/participants/displayParticipants_view.php b/application/views/admin/participants/displayParticipants_view.php index 7dcc0eea7b9..388662f9d1f 100644 --- a/application/views/admin/participants/displayParticipants_view.php +++ b/application/views/admin/participants/displayParticipants_view.php @@ -40,6 +40,7 @@ $langNames[] = $lang . $langnames; /* Build the columnNames for the extra attributes */ /* and, build the columnModel */ +$autowidth='true'; if (isset($attributes) && count($attributes) > 0) { foreach ($attributes as $row) @@ -48,6 +49,7 @@ $uidNames[] = '{ "name": "' . $row['attribute_name'] . '", "index":"' . $row['attribute_id'] . '", "sorttype":"string", "sortable": true, "align":"center"}'; } $columnNames = ',' . implode(",", $attnames) . ''; //Add to the end of the standard list of columnNames + if(count($attributes) > 5) $autowidth='false'; } else { @@ -88,6 +90,7 @@ var dateInvitedColTxt="eT("Last invited") ?>"; var dateCompletedColTxt="eT("Submitted") ?>"; var surveylinkUrl = "getController()->createUrl("admin/participants/getSurveyInfo_json/pid/"); ?>"; + /* Colnames and heading for attributes subgrid */ var attributesHeadingTxt="eT("Participant's attribute information") ?>"; var actionsColTxt="eT("Actions") ?>"; @@ -132,6 +135,7 @@ var jsonUrl = "getController()->createUrl("admin/participants/".$urlsearch); ?>"; var jsonSearchUrl = "getController()->createUrl("admin/participants/getParticipantsResults_json/search/"); ?>"; var editUrl = "getController()->createUrl("admin/participants/editParticipant"); ?>"; + var autowidth = ""; var getSearchIDs = "getController()->createUrl("admin/participants/getSearchIDs"); ?>"; var getaddtosurveymsg = "getController()->createUrl("admin/participants/getaddtosurveymsg"); ?>"; var minusbutton = "getConfig('adminimageurl') . "deleteanswer.png" ?>"; diff --git a/scripts/admin/displayParticipant.js b/scripts/admin/displayParticipant.js index 399591370f8..c37e78e81e2 100644 --- a/scripts/admin/displayParticipant.js +++ b/scripts/admin/displayParticipant.js @@ -121,7 +121,7 @@ $(document).ready(function() { rowNum: 25, editable:true, scrollOffset:0, - autowidth: true, + autowidth: autowidth, sortable : true, sortname: 'firstname', sortorder: 'asc', From 4df6f5f2d103fab7bf800170c79230fdbc81678c Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Mon, 6 Aug 2012 11:10:43 +0200 Subject: [PATCH 51/75] Fixed issue #6347: display of question text different in 1.92+ and 2.0 when view question in admin mode --- .../views/admin/survey/Question/questionbar_view.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/application/views/admin/survey/Question/questionbar_view.php b/application/views/admin/survey/Question/questionbar_view.php index 5fcef8d6f3f..80b98820482 100644 --- a/application/views/admin/survey/Question/questionbar_view.php +++ b/application/views/admin/survey/Question/questionbar_view.php @@ -1,4 +1,6 @@ - +
      eT("Please select a language:"); ?>
        @@ -165,14 +167,14 @@
    From 769b5f30fd47fd90121be4919aed39a3c26e120d Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Mon, 6 Aug 2012 11:30:46 +0200 Subject: [PATCH 52/75] Fixed issue #6427: 'Select tokens IDs' line showing up even when no tokens were selected for sending reminders --- application/views/admin/token/remind.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/application/views/admin/token/remind.php b/application/views/admin/token/remind.php index 20f7484bd2a..a6c1fedb143 100644 --- a/application/views/admin/token/remind.php +++ b/application/views/admin/token/remind.php @@ -63,7 +63,8 @@ ?> From b4e5041f937900577a32575766e7feda70e60ce1 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 7 Aug 2012 12:20:44 +0200 Subject: [PATCH 56/75] Fixed issue #6428: Unable to set time in dropdown mode for date question type --- application/helpers/common_helper.php | 5 +- application/helpers/qanda_helper.php | 75 +++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 12 deletions(-) diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 9eb67cf3b3e..01d5e205d83 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -2184,7 +2184,7 @@ function createCompleteSGQA($iSurveyID,$aFilters,$sLanguage) { $aAdditionalLanguages = array_filter(explode(" ", $oSurvey->additional_languages)); if (is_null($sLanguage)|| !in_array($sLanguage,$aAdditionalLanguages)) $sLanguage = $oSurvey->language; - + switch ($flt['type']) { case "K": // Multiple Numerical @@ -2287,7 +2287,7 @@ function createCompleteSGQA($iSurveyID,$aFilters,$sLanguage) { } //end switch } - + return $allfields; } @@ -4223,6 +4223,7 @@ function questionAttributes($returnByName=false) 'category'=>$clang->gT('Input'), 'sortorder'=>100, "inputtype"=>"integer", + 'default'=>1, "help"=>$clang->gT("Minute step interval when using select boxes"), "caption"=>$clang->gT("Minute step interval")); diff --git a/application/helpers/qanda_helper.php b/application/helpers/qanda_helper.php index 4ce24a61fc0..dc5f7fadddb 100644 --- a/application/helpers/qanda_helper.php +++ b/application/helpers/qanda_helper.php @@ -1077,10 +1077,10 @@ function do_date($ia) $checkconditionFunction = "checkconditions"; - $dateformatdetails = getDateFormatData($thissurvey['surveyls_dateformat']); + $dateformatdetails = getDateFormatDataForQID($aQuestionAttributes,$thissurvey); $numberformatdatat = getRadixPointData($thissurvey['surveyls_numberformat']); - if (trim($aQuestionAttributes['dropdown_dates'])!=0) { + if (trim($aQuestionAttributes['dropdown_dates'])==1) { if (!empty($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])) { $datetimeobj = getdate(DateTime::createFromFormat("Y-m-d H:i:s", $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])->getTimeStamp()); @@ -1093,9 +1093,11 @@ function do_date($ia) $currentdate=''; $currentmonth=''; $currentyear=''; + $currenthour = ''; + $currentminute = ''; } - $dateorder = preg_split('/[-\.\/ ]/', $dateformatdetails['phpdate']); + $dateorder = preg_split('/([-\.\/ :])/', $dateformatdetails['phpdate'],-1,PREG_SPLIT_DELIM_CAPTURE ); $answer='
  • + + eT("Regenerate question codes");?> +
  • From 805441e687a3093e974f22f42aeb879a2e31b57a Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 7 Aug 2012 15:37:25 +0200 Subject: [PATCH 59/75] Fixed issue #6433: Wrong date/time is showing in survey summary Dev This should also fix most other date conversion related issues --- application/controllers/admin/surveyadmin.php | 2 +- application/libraries/Date_Time_Converter.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application/controllers/admin/surveyadmin.php b/application/controllers/admin/surveyadmin.php index 32da7d93be7..cd8fc5a07f7 100644 --- a/application/controllers/admin/surveyadmin.php +++ b/application/controllers/admin/surveyadmin.php @@ -1491,7 +1491,7 @@ function insert($iSurveyID=null) { Yii::import('application.libraries.Date_Time_Converter'); $converter = new Date_Time_Converter($sStartDate, $aDateFormatData['phpdate'] . ' H:i:s'); - $sExpiryDate = $converter->convert("Y-m-d H:i:s"); + $sStartDate = $converter->convert("Y-m-d H:i:s"); } // If expiry date supplied convert it to the right format diff --git a/application/libraries/Date_Time_Converter.php b/application/libraries/Date_Time_Converter.php index bd59bdc8c36..570df1afddb 100644 --- a/application/libraries/Date_Time_Converter.php +++ b/application/libraries/Date_Time_Converter.php @@ -58,15 +58,15 @@ class Date_Time_Converter * without leading zeros (n,j,g,G) as long as they aren't bunched together. * ie: ("1152008", "njY") wont work; ("1/15/2008", "n/j/2008") will work. * Example: $obj = new Date_Time_Calc('12/30/2008 17:40:00', 'm/d/Y H:i:s'); */ - public function __construct($data) { + public function __construct($sDate, $sFormat) { require_once(APPPATH . '/helpers/adodb/adodb-time.inc_helper.php'); $this->_default_date_time_units(); //set date&time units to default values - $this->date_time = $data[0]; - $this->date_time_mask = $data[1]; + $this->date_time = $sDate; + $this->date_time_mask = $sFormat; //convert date to timestamp - $this->date_time_stamp = $this->_date_to_timestamp($data[0], $data[1]); + $this->date_time_stamp = $this->_date_to_timestamp($sDate, $sFormat); } From 2401db5a047c37d788935c728ae49d6b905e14be Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 7 Aug 2012 20:47:01 +0200 Subject: [PATCH 60/75] Fixed issue #6424: Lastpage field not being added in MSSQL when upgrading from 1.85 or older --- application/helpers/database_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/helpers/database_helper.php b/application/helpers/database_helper.php index ee05820f160..9b288fab818 100644 --- a/application/helpers/database_helper.php +++ b/application/helpers/database_helper.php @@ -190,7 +190,7 @@ function dbSelectTablesLike($table) return "SHOW TABLES LIKE '$table'"; case 'mssql' : case 'sqlsrv' : - return "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE' and TABLE_NAME LIKE '$table'"; + return "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE' and TABLE_NAME LIKE '$table' ESCAPE '\'"; case 'pgsql' : $table=str_replace('\\','\\\\',$table); return "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' and table_name like '$table'"; From 0a601a943dab4b32c06126cee574d6cad4335001 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 7 Aug 2012 21:25:36 +0200 Subject: [PATCH 61/75] Fixed issue #6434: Regenerate question codes doesn't work --- application/controllers/admin/surveyadmin.php | 7 +++---- application/views/admin/survey/surveybar_view.php | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/application/controllers/admin/surveyadmin.php b/application/controllers/admin/surveyadmin.php index cd8fc5a07f7..c636e70379a 100644 --- a/application/controllers/admin/surveyadmin.php +++ b/application/controllers/admin/surveyadmin.php @@ -69,7 +69,7 @@ public function index() $this->_renderWrappedTemplate('survey', 'listSurveys_view', $aData); } - public function regenquestioncodes($iSurveyID, $sStyle ='straight') + public function regenquestioncodes($iSurveyID, $sSubAction ) { if (hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) { @@ -91,15 +91,14 @@ public function regenquestioncodes($iSurveyID, $sStyle ='straight') foreach($grows as $grow) { //Go through all the questions - if ($sStyle == 'bygroup' && (!isset($group_number) || $group_number != $grow['gid'])) + if ($sSubAction == 'bygroup' && (!isset($group_number) || $group_number != $grow['gid'])) { //If we're doing this by group, restart the numbering when the group number changes $question_number=1; $group_number = $grow['gid']; $gseq++; } $usql="UPDATE {{questions}} " - ."SET title='" - .(($sStyle == 'bygroup') ? ('G' . $gseq . '_') : '')."Q".str_pad($question_number, 4, "0", STR_PAD_LEFT)."'\n" + ."SET title='".(($sSubAction == 'bygroup') ? ('G' . $gseq . '_') : '')."Q".str_pad($question_number, 4, "0", STR_PAD_LEFT)."'\n" ."WHERE qid=".$grow['qid']; //$databaseoutput .= "[$sql]"; $uresult=dbExecuteAssoc($usql) or safe_die("Error: ".$connect->ErrorMsg()); // Checked diff --git a/application/views/admin/survey/surveybar_view.php b/application/views/admin/survey/surveybar_view.php index 56cdba5188a..1c2dae9161d 100644 --- a/application/views/admin/survey/surveybar_view.php +++ b/application/views/admin/survey/surveybar_view.php @@ -123,10 +123,10 @@ eT("Regenerate question codes");?> From 5146de566c85ddc819db0c6d62f5118f246cb865 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Tue, 7 Aug 2012 21:53:07 +0200 Subject: [PATCH 62/75] Fixed issue #6433: Wrong date/time is showing in survey summary Dev This should also fix most other date conversion related issues --- application/controllers/admin/surveyadmin.php | 9 +++------ application/controllers/admin/tokens.php | 12 ++++++------ application/helpers/common_helper.php | 2 +- application/helpers/replacements_helper.php | 3 +-- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/application/controllers/admin/surveyadmin.php b/application/controllers/admin/surveyadmin.php index c636e70379a..82ea386e2c5 100644 --- a/application/controllers/admin/surveyadmin.php +++ b/application/controllers/admin/surveyadmin.php @@ -628,7 +628,7 @@ public function getSurveys_json() //Set Date Yii::import('application.libraries.Date_Time_Converter', true); - $datetimeobj = new Date_Time_Converter(array($rows['datecreated'], "Y-m-d H:i:s")); + $datetimeobj = new Date_Time_Converter($rows['datecreated'], "Y-m-d H:i:s"); $aSurveyEntry[] = '' . $datetimeobj->convert($dateformatdetails['phpdate']); //Set Owner @@ -1228,19 +1228,16 @@ private function _tabPublicationAccess($esrow) $startdate = ''; if ($esrow['startdate']) { - $items = array($esrow["startdate"], "Y-m-d H:i:s"); // $dateformatdetails['phpdate'] Yii::app()->loadLibrary('Date_Time_Converter'); - $datetimeobj = new date_time_converter($items); //new Date_Time_Converter($esrow['startdate'] , "Y-m-d H:i:s"); + $datetimeobj = new date_time_converter($esrow["startdate"],"Y-m-d H:i:s"); //new Date_Time_Converter($esrow['startdate'] , "Y-m-d H:i:s"); $startdate = $datetimeobj->convert("d.m.Y H:i"); //$datetimeobj->convert($dateformatdetails['phpdate'].' H:i'); } $expires = ''; if ($esrow['expires']) { - $items = array($esrow['expires'], "Y-m-d H:i:s"); - Yii::app()->loadLibrary('Date_Time_Converter'); - $datetimeobj = new date_time_converter($items); //new Date_Time_Converter($esrow['expires'] , "Y-m-d H:i:s"); + $datetimeobj = new date_time_converter($esrow['expires'], "Y-m-d H:i:s"); //new Date_Time_Converter($esrow['expires'] , "Y-m-d H:i:s"); $expires = $datetimeobj->convert("d.m.Y H:i"); } $aData['clang'] = $clang; diff --git a/application/controllers/admin/tokens.php b/application/controllers/admin/tokens.php index 14cd44eb77b..94ebd76230c 100644 --- a/application/controllers/admin/tokens.php +++ b/application/controllers/admin/tokens.php @@ -690,7 +690,7 @@ function addnew($iSurveyId) } else { - $datetimeobj = new Date_Time_Converter(array(trim(Yii::app()->request->getPost('validfrom')), $dateformatdetails['phpdate'] . ' H:i')); + $datetimeobj = new Date_Time_Converter(trim(Yii::app()->request->getPost('validfrom')), $dateformatdetails['phpdate'] . ' H:i'); $validfrom = $datetimeobj->convert('Y-m-d H:i:s'); } if (trim(Yii::app()->request->getPost('validuntil')) == '') @@ -699,7 +699,7 @@ function addnew($iSurveyId) } else { - $datetimeobj = new Date_Time_Converter(array(trim(Yii::app()->request->getPost('validuntil')), $dateformatdetails['phpdate'] . ' H:i')); + $datetimeobj = new Date_Time_Converter(trim(Yii::app()->request->getPost('validuntil')), $dateformatdetails['phpdate'] . ' H:i'); $validuntil = $datetimeobj->convert('Y-m-d H:i:s'); } @@ -810,7 +810,7 @@ function edit($iSurveyId, $iTokenId) } else { - $datetimeobj = new Date_Time_Converter(array(trim(Yii::app()->request->getPost('validfrom')), $dateformatdetails['phpdate'] . ' H:i')); + $datetimeobj = new Date_Time_Converter(trim(Yii::app()->request->getPost('validfrom')), $dateformatdetails['phpdate'] . ' H:i'); $_POST['validfrom'] = $datetimeobj->convert('Y-m-d H:i:s'); } if (trim(Yii::app()->request->getPost('validuntil')) == '') @@ -819,7 +819,7 @@ function edit($iSurveyId, $iTokenId) } else { - $datetimeobj = new Date_Time_Converter(array(trim(Yii::app()->request->getPost('validuntil')), $dateformatdetails['phpdate'] . ' H:i')); + $datetimeobj = new Date_Time_Converter(trim(Yii::app()->request->getPost('validuntil')), $dateformatdetails['phpdate'] . ' H:i'); $_POST['validuntil'] = $datetimeobj->convert('Y-m-d H:i:s'); } @@ -946,7 +946,7 @@ function addDummies($iSurveyId, $subaction = '') } else { - $datetimeobj = new Date_Time_Converter(array(trim(Yii::app()->request->getPost('validfrom')), $dateformatdetails['phpdate'] . ' H:i')); + $datetimeobj = new Date_Time_Converter(trim(Yii::app()->request->getPost('validfrom')), $dateformatdetails['phpdate'] . ' H:i'); $_POST['validfrom'] = $datetimeobj->convert('Y-m-d H:i:s'); } if (trim(Yii::app()->request->getPost('validuntil')) == '') @@ -955,7 +955,7 @@ function addDummies($iSurveyId, $subaction = '') } else { - $datetimeobj = new Date_Time_Converter(array(trim(Yii::app()->request->getPost('validuntil')), $dateformatdetails['phpdate'] . ' H:i')); + $datetimeobj = new Date_Time_Converter(trim(Yii::app()->request->getPost('validuntil')), $dateformatdetails['phpdate'] . ' H:i'); $_POST['validuntil'] = $datetimeobj->convert('Y-m-d H:i:s'); } diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 01d5e205d83..aa2dfcf8bd0 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -5571,7 +5571,7 @@ function useFirebug() function convertDateTimeFormat($value, $fromdateformat, $todateformat) { Yii::import('application.libraries.Date_Time_Converter', true); - $date = new Date_Time_Converter(array($value, $fromdateformat)); + $date = new Date_Time_Converter($value, $fromdateformat); return $date->convert($todateformat); } diff --git a/application/helpers/replacements_helper.php b/application/helpers/replacements_helper.php index 2ad12f8a482..0c70ce53874 100644 --- a/application/helpers/replacements_helper.php +++ b/application/helpers/replacements_helper.php @@ -371,9 +371,8 @@ function templatereplace($line, $replacements = array(), &$redata = array(), $de if (isset($thissurvey['expiry'])) { $dateformatdetails=getDateFormatData($thissurvey['surveyls_dateformat']); - $items = array($thissurvey['expiry'],"Y-m-d"); Yii::import('application.libraries.Date_Time_Converter', true); - $datetimeobj = new Date_Time_Converter($items) ; + $datetimeobj = new Date_Time_Converter($thissurvey['expiry'],"Y-m-d") ; $_dateoutput=$datetimeobj->convert($dateformatdetails['phpdate']); } else From 40bc43013a1f38e5b59b0f728bc72279917d0ff2 Mon Sep 17 00:00:00 2001 From: finn Date: Wed, 8 Aug 2012 00:04:24 +0200 Subject: [PATCH 63/75] Signed-off-by: finn --- application/helpers/admin/label_helper.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/application/helpers/admin/label_helper.php b/application/helpers/admin/label_helper.php index 3d47ea1a314..3e89e539fbc 100644 --- a/application/helpers/admin/label_helper.php +++ b/application/helpers/admin/label_helper.php @@ -47,9 +47,15 @@ function updateset($lid) foreach ($oldcodesarray as $oldcode => $olddata) $sqlvalues[]= array('lid' => $lid, 'code' => $oldcode, 'sortorder' => $olddata['sortorder'], 'language' => $addedlangid, 'assessment_value' => $olddata['assessment_value']); - if (isset($sqlvalues)) - foreach ($sqlvalues as $sqlvalue) - Label::model()->insert($sqlvalue); + if (isset($sqlvalues)) { + foreach ($sqlvalues as $sqlvalue) { + $label = new Label(); + foreach ($sqlvalue as $name => $value) { + $label->setAttribute($name, $value); + } + $label->save(); + } + } // If languages are removed, delete labels for these languages $criteria = new CDbCriteria; From 08f46362134e811f6a1837b6cfd6dc1a505ba28b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 8 Aug 2012 00:05:46 +0200 Subject: [PATCH 64/75] Dev Automatic translation update --- locale/_template/limesurvey.pot | 808 ++++++++++++++++---------------- 1 file changed, 408 insertions(+), 400 deletions(-) diff --git a/locale/_template/limesurvey.pot b/locale/_template/limesurvey.pot index c4d6aa0a86e..22f49e5a242 100644 --- a/locale/_template/limesurvey.pot +++ b/locale/_template/limesurvey.pot @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: LimeSurvey language file\n" "Report-Msgid-Bugs-To: http://translate.limesurvey.org/\n" -"POT-Creation-Date: 2012-08-06 22:05:48+00:00\n" +"POT-Creation-Date: 2012-08-07 22:05:44+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -100,7 +100,7 @@ msgid "Back" msgstr "" #: application/controllers/AdminController.php:86 -#: application/controllers/admin/surveyadmin.php:419 +#: application/controllers/admin/surveyadmin.php:462 #: application/controllers/admin/tokens.php:2195 #: application/helpers/admin/import_helper.php:2612 #: application/views/admin/authentication/forgotpassword.php:15 @@ -468,7 +468,7 @@ msgid "Unknown error" msgstr "" #: application/controllers/UploaderController.php:263 -#: application/helpers/qanda_helper.php:2789 +#: application/helpers/qanda_helper.php:2847 #: application/views/admin/assessments_view.php:13 #: application/views/admin/labels/labelview_view.php:40 #: application/views/admin/survey/QuestionGroups/editGroup_view.php:16 @@ -481,7 +481,7 @@ msgstr "" #: application/controllers/UploaderController.php:264 #: application/helpers/common_helper.php:2578 #: application/helpers/common_helper.php:2791 -#: application/helpers/qanda_helper.php:2790 +#: application/helpers/qanda_helper.php:2848 #: application/views/admin/dataentry/content_view.php:139 msgid "Comment" msgstr "" @@ -576,7 +576,7 @@ msgid "Assessment mode for this survey is not activated. You can activate it in msgstr "" #: application/controllers/admin/assessments.php:136 -#: application/controllers/admin/surveyadmin.php:592 +#: application/controllers/admin/surveyadmin.php:635 #: application/views/admin/assessments_view.php:24 #: application/views/admin/quotas/viewquotasrow_view.php:28 msgid "Edit" @@ -843,9 +843,9 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1183 #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:517 -#: application/controllers/admin/surveyadmin.php:607 +#: application/controllers/admin/surveyadmin.php:650 #: application/controllers/admin/tokens.php:2112 -#: application/core/Survey_Common_Action.php:827 +#: application/core/Survey_Common_Action.php:816 #: application/helpers/admin/statistics_helper.php:1456 #: application/helpers/admin/statistics_helper.php:1589 #: application/helpers/common_helper.php:1819 @@ -882,9 +882,9 @@ msgstr "" #: application/helpers/common_helper.php:4002 #: application/helpers/common_helper.php:4090 #: application/helpers/common_helper.php:4100 -#: application/helpers/common_helper.php:4247 -#: application/helpers/common_helper.php:4258 -#: application/helpers/common_helper.php:4318 +#: application/helpers/common_helper.php:4248 +#: application/helpers/common_helper.php:4259 +#: application/helpers/common_helper.php:4319 #: application/helpers/export_helper.php:241 #: application/helpers/export_helper.php:245 #: application/helpers/export_helper.php:253 @@ -893,9 +893,9 @@ msgstr "" #: application/helpers/export_helper.php:1296 #: application/helpers/expressions/em_manager_helper.php:2837 #: application/helpers/expressions/em_manager_helper.php:2841 -#: application/helpers/qanda_helper.php:4078 -#: application/helpers/qanda_helper.php:4505 -#: application/helpers/qanda_helper.php:4543 +#: application/helpers/qanda_helper.php:4136 +#: application/helpers/qanda_helper.php:4563 +#: application/helpers/qanda_helper.php:4601 #: application/views/admin/dataentry/content_view.php:527 #: application/views/admin/dataentry/content_view.php:580 #: application/views/admin/dataentry/import.php:23 @@ -1009,33 +1009,33 @@ msgstr "" #: application/controllers/admin/tokens.php:2314 #: application/controllers/admin/tokens.php:2349 #: application/controllers/admin/useraction.php:720 -#: application/helpers/common_helper.php:6360 -#: application/helpers/common_helper.php:6365 -#: application/helpers/common_helper.php:6370 -#: application/helpers/common_helper.php:6375 -#: application/helpers/common_helper.php:6380 -#: application/helpers/common_helper.php:6385 -#: application/helpers/common_helper.php:6390 -#: application/helpers/common_helper.php:6395 -#: application/helpers/common_helper.php:6400 -#: application/helpers/common_helper.php:6406 -#: application/helpers/common_helper.php:6412 -#: application/helpers/common_helper.php:6417 -#: application/helpers/common_helper.php:6422 -#: application/helpers/common_helper.php:6427 -#: application/helpers/common_helper.php:6432 -#: application/helpers/common_helper.php:6437 -#: application/helpers/common_helper.php:6443 -#: application/helpers/common_helper.php:6448 -#: application/helpers/common_helper.php:6457 -#: application/helpers/common_helper.php:6462 -#: application/helpers/common_helper.php:6469 -#: application/helpers/common_helper.php:6473 -#: application/helpers/common_helper.php:6477 +#: application/helpers/common_helper.php:6361 +#: application/helpers/common_helper.php:6366 +#: application/helpers/common_helper.php:6371 +#: application/helpers/common_helper.php:6376 +#: application/helpers/common_helper.php:6381 +#: application/helpers/common_helper.php:6386 +#: application/helpers/common_helper.php:6391 +#: application/helpers/common_helper.php:6396 +#: application/helpers/common_helper.php:6401 +#: application/helpers/common_helper.php:6407 +#: application/helpers/common_helper.php:6413 +#: application/helpers/common_helper.php:6418 +#: application/helpers/common_helper.php:6423 +#: application/helpers/common_helper.php:6428 +#: application/helpers/common_helper.php:6433 +#: application/helpers/common_helper.php:6438 +#: application/helpers/common_helper.php:6444 +#: application/helpers/common_helper.php:6449 +#: application/helpers/common_helper.php:6458 +#: application/helpers/common_helper.php:6463 +#: application/helpers/common_helper.php:6470 +#: application/helpers/common_helper.php:6474 +#: application/helpers/common_helper.php:6478 #: application/helpers/frontend_helper.php:1448 #: application/helpers/frontend_helper.php:1525 #: application/helpers/frontend_helper.php:1697 -#: application/helpers/replacements_helper.php:664 +#: application/helpers/replacements_helper.php:663 #: application/views/admin/authentication/message.php:3 #: application/views/admin/participants/attributeMapCSV_view.php:76 #: application/views/admin/participants/attributeMap_view.php:106 @@ -1077,8 +1077,8 @@ msgstr "" #: application/helpers/export_helper.php:259 #: application/helpers/export_helper.php:1296 #: application/helpers/expressions/em_manager_helper.php:2843 -#: application/helpers/qanda_helper.php:4506 -#: application/helpers/qanda_helper.php:4551 +#: application/helpers/qanda_helper.php:4564 +#: application/helpers/qanda_helper.php:4609 #: application/views/admin/dataentry/content_view.php:581 #: application/views/admin/export/statistics_view.php:719 msgid "Uncertain" @@ -1095,9 +1095,9 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:1185 #: application/controllers/admin/printablesurvey.php:1188 #: application/controllers/admin/quotas.php:518 -#: application/controllers/admin/surveyadmin.php:611 +#: application/controllers/admin/surveyadmin.php:654 #: application/controllers/admin/tokens.php:2114 -#: application/core/Survey_Common_Action.php:823 +#: application/core/Survey_Common_Action.php:812 #: application/helpers/admin/statistics_helper.php:1457 #: application/helpers/admin/statistics_helper.php:1590 #: application/helpers/common_helper.php:1826 @@ -1134,18 +1134,18 @@ msgstr "" #: application/helpers/common_helper.php:4001 #: application/helpers/common_helper.php:4089 #: application/helpers/common_helper.php:4099 -#: application/helpers/common_helper.php:4246 -#: application/helpers/common_helper.php:4257 -#: application/helpers/common_helper.php:4317 +#: application/helpers/common_helper.php:4247 +#: application/helpers/common_helper.php:4258 +#: application/helpers/common_helper.php:4318 #: application/helpers/export_helper.php:254 #: application/helpers/export_helper.php:258 #: application/helpers/export_helper.php:1277 #: application/helpers/export_helper.php:1296 #: application/helpers/expressions/em_manager_helper.php:2838 #: application/helpers/expressions/em_manager_helper.php:2842 -#: application/helpers/qanda_helper.php:4087 -#: application/helpers/qanda_helper.php:4507 -#: application/helpers/qanda_helper.php:4561 +#: application/helpers/qanda_helper.php:4145 +#: application/helpers/qanda_helper.php:4565 +#: application/helpers/qanda_helper.php:4619 #: application/views/admin/dataentry/content_view.php:528 #: application/views/admin/dataentry/content_view.php:582 #: application/views/admin/dataentry/import.php:24 @@ -1206,8 +1206,8 @@ msgstr "" #: application/helpers/export_helper.php:262 #: application/helpers/export_helper.php:1301 #: application/helpers/expressions/em_manager_helper.php:2846 -#: application/helpers/qanda_helper.php:4662 -#: application/helpers/qanda_helper.php:4704 +#: application/helpers/qanda_helper.php:4720 +#: application/helpers/qanda_helper.php:4762 #: application/views/admin/dataentry/content_view.php:598 #: application/views/admin/export/statistics_view.php:769 msgid "Increase" @@ -1222,8 +1222,8 @@ msgstr "" #: application/helpers/export_helper.php:263 #: application/helpers/export_helper.php:1301 #: application/helpers/expressions/em_manager_helper.php:2847 -#: application/helpers/qanda_helper.php:4663 -#: application/helpers/qanda_helper.php:4715 +#: application/helpers/qanda_helper.php:4721 +#: application/helpers/qanda_helper.php:4773 #: application/views/admin/dataentry/content_view.php:599 #: application/views/admin/export/statistics_view.php:774 msgid "Same" @@ -1238,8 +1238,8 @@ msgstr "" #: application/helpers/export_helper.php:264 #: application/helpers/export_helper.php:1301 #: application/helpers/expressions/em_manager_helper.php:2848 -#: application/helpers/qanda_helper.php:4664 -#: application/helpers/qanda_helper.php:4727 +#: application/helpers/qanda_helper.php:4722 +#: application/helpers/qanda_helper.php:4785 #: application/views/admin/dataentry/content_view.php:600 #: application/views/admin/export/statistics_view.php:779 msgid "Decrease" @@ -1270,29 +1270,29 @@ msgstr "" #: application/helpers/common_helper.php:1827 #: application/helpers/common_helper.php:1835 #: application/helpers/qanda_helper.php:966 -#: application/helpers/qanda_helper.php:1498 -#: application/helpers/qanda_helper.php:1805 -#: application/helpers/qanda_helper.php:1938 -#: application/helpers/qanda_helper.php:2001 -#: application/helpers/qanda_helper.php:4098 -#: application/helpers/qanda_helper.php:4142 -#: application/helpers/qanda_helper.php:4234 -#: application/helpers/qanda_helper.php:4296 -#: application/helpers/qanda_helper.php:4387 -#: application/helpers/qanda_helper.php:4432 -#: application/helpers/qanda_helper.php:4510 -#: application/helpers/qanda_helper.php:4581 -#: application/helpers/qanda_helper.php:4667 -#: application/helpers/qanda_helper.php:4745 -#: application/helpers/qanda_helper.php:4850 -#: application/helpers/qanda_helper.php:4933 -#: application/helpers/qanda_helper.php:5065 -#: application/helpers/qanda_helper.php:5857 -#: application/helpers/qanda_helper.php:5858 -#: application/helpers/qanda_helper.php:6151 -#: application/helpers/qanda_helper.php:6312 -#: application/helpers/qanda_helper.php:6513 -#: application/helpers/qanda_helper.php:6567 +#: application/helpers/qanda_helper.php:1556 +#: application/helpers/qanda_helper.php:1863 +#: application/helpers/qanda_helper.php:1996 +#: application/helpers/qanda_helper.php:2059 +#: application/helpers/qanda_helper.php:4156 +#: application/helpers/qanda_helper.php:4200 +#: application/helpers/qanda_helper.php:4292 +#: application/helpers/qanda_helper.php:4354 +#: application/helpers/qanda_helper.php:4445 +#: application/helpers/qanda_helper.php:4490 +#: application/helpers/qanda_helper.php:4568 +#: application/helpers/qanda_helper.php:4639 +#: application/helpers/qanda_helper.php:4725 +#: application/helpers/qanda_helper.php:4803 +#: application/helpers/qanda_helper.php:4908 +#: application/helpers/qanda_helper.php:4991 +#: application/helpers/qanda_helper.php:5123 +#: application/helpers/qanda_helper.php:5915 +#: application/helpers/qanda_helper.php:5916 +#: application/helpers/qanda_helper.php:6209 +#: application/helpers/qanda_helper.php:6370 +#: application/helpers/qanda_helper.php:6571 +#: application/helpers/qanda_helper.php:6625 #: application/views/admin/dataentry/content_view.php:29 msgid "No answer" msgstr "" @@ -1323,7 +1323,7 @@ msgstr "" #: application/helpers/export_helper.php:249 #: application/helpers/export_helper.php:1281 #: application/helpers/expressions/em_manager_helper.php:2834 -#: application/helpers/qanda_helper.php:4124 +#: application/helpers/qanda_helper.php:4182 #: application/views/admin/dataentry/content_view.php:54 #: application/views/admin/export/statistics_view.php:530 msgid "Female" @@ -1339,7 +1339,7 @@ msgstr "" #: application/helpers/export_helper.php:250 #: application/helpers/export_helper.php:1281 #: application/helpers/expressions/em_manager_helper.php:2833 -#: application/helpers/qanda_helper.php:4132 +#: application/helpers/qanda_helper.php:4190 #: application/views/admin/dataentry/content_view.php:55 #: application/views/admin/export/statistics_view.php:536 msgid "Male" @@ -1363,17 +1363,17 @@ msgstr "" #: application/helpers/common_helper.php:4031 #: application/helpers/common_helper.php:4044 #: application/helpers/common_helper.php:4054 -#: application/helpers/common_helper.php:4266 -#: application/helpers/common_helper.php:4275 -#: application/helpers/common_helper.php:4284 -#: application/helpers/common_helper.php:4293 +#: application/helpers/common_helper.php:4267 +#: application/helpers/common_helper.php:4276 +#: application/helpers/common_helper.php:4285 +#: application/helpers/common_helper.php:4294 #: application/helpers/export_helper.php:874 #: application/helpers/export_helper.php:883 #: application/helpers/export_helper.php:979 #: application/helpers/export_helper.php:994 -#: application/helpers/qanda_helper.php:1771 -#: application/helpers/qanda_helper.php:2349 -#: application/helpers/qanda_helper.php:2679 +#: application/helpers/qanda_helper.php:1829 +#: application/helpers/qanda_helper.php:2407 +#: application/helpers/qanda_helper.php:2737 #: application/views/admin/dataentry/content_view.php:103 #: application/views/admin/dataentry/content_view.php:108 #: application/views/admin/dataentry/content_view.php:123 @@ -1530,13 +1530,13 @@ msgstr "" #: application/helpers/admin/statistics_helper.php:2154 #: application/helpers/admin/statistics_helper.php:2162 #: application/helpers/admin/statistics_helper.php:2167 -#: application/helpers/qanda_helper.php:1218 -#: application/helpers/qanda_helper.php:3677 -#: application/helpers/qanda_helper.php:3778 -#: application/helpers/qanda_helper.php:3870 -#: application/helpers/qanda_helper.php:3971 -#: application/helpers/qanda_helper.php:3972 -#: application/helpers/qanda_helper.php:4046 +#: application/helpers/qanda_helper.php:1276 +#: application/helpers/qanda_helper.php:3735 +#: application/helpers/qanda_helper.php:3836 +#: application/helpers/qanda_helper.php:3928 +#: application/helpers/qanda_helper.php:4029 +#: application/helpers/qanda_helper.php:4030 +#: application/helpers/qanda_helper.php:4104 msgid "Answer" msgstr "" @@ -1683,11 +1683,11 @@ msgstr "" #: application/controllers/admin/dataentry.php:306 #: application/controllers/admin/labels.php:100 #: application/controllers/admin/labels.php:133 -#: application/controllers/admin/participantsaction.php:1387 +#: application/controllers/admin/participantsaction.php:1392 #: application/controllers/admin/question.php:55 #: application/controllers/admin/questiongroup.php:55 -#: application/controllers/admin/surveyadmin.php:203 -#: application/controllers/admin/surveyadmin.php:826 +#: application/controllers/admin/surveyadmin.php:246 +#: application/controllers/admin/surveyadmin.php:869 #: application/controllers/admin/templates.php:151 #: application/controllers/admin/templates.php:210 msgid "An error occurred uploading your file. This may be caused by incorrect permissions in your %s folder." @@ -1731,8 +1731,8 @@ msgstr "" #: application/controllers/admin/dataentry.php:844 #: application/controllers/admin/dataentry.php:1067 #: application/controllers/admin/dataentry.php:1184 -#: application/helpers/qanda_helper.php:1512 -#: application/helpers/qanda_helper.php:5045 +#: application/helpers/qanda_helper.php:1570 +#: application/helpers/qanda_helper.php:5103 #: application/views/admin/dataentry/content_view.php:53 #: application/views/admin/dataentry/content_view.php:118 #: application/views/admin/dataentry/content_view.php:136 @@ -1753,13 +1753,13 @@ msgstr "" #: application/controllers/admin/dataentry.php:1000 #: application/helpers/common_helper.php:4049 -#: application/helpers/qanda_helper.php:2124 +#: application/helpers/qanda_helper.php:2182 msgid "Your Choices" msgstr "" #: application/controllers/admin/dataentry.php:1005 #: application/helpers/common_helper.php:4059 -#: application/helpers/qanda_helper.php:2132 +#: application/helpers/qanda_helper.php:2190 msgid "Your Ranking" msgstr "" @@ -1891,7 +1891,7 @@ msgid "Thank you for saving your survey in progress. The following details can msgstr "" #: application/controllers/admin/dataentry.php:1948 -#: application/helpers/replacements_helper.php:552 +#: application/helpers/replacements_helper.php:551 #: application/libraries/Save.php:199 msgid "Name" msgstr "" @@ -1901,8 +1901,8 @@ msgstr "" #: application/controllers/admin/useraction.php:133 #: application/controllers/admin/useraction.php:362 #: application/controllers/admin/useraction.php:380 -#: application/helpers/replacements_helper.php:558 -#: application/helpers/replacements_helper.php:591 +#: application/helpers/replacements_helper.php:557 +#: application/helpers/replacements_helper.php:590 #: application/libraries/Save.php:200 #: application/views/admin/authentication/login.php:8 #: application/views/admin/user/modifyuser.php:7 @@ -2196,18 +2196,18 @@ msgid "Logged in" msgstr "" #: application/controllers/admin/labels.php:54 -#: application/controllers/admin/surveyadmin.php:157 +#: application/controllers/admin/surveyadmin.php:200 msgid "Demo mode only: Uploading files is disabled in this system." msgstr "" #: application/controllers/admin/labels.php:68 -#: application/controllers/admin/surveyadmin.php:171 +#: application/controllers/admin/surveyadmin.php:214 #: application/controllers/admin/templates.php:96 msgid "Incorrect permissions in your %s folder." msgstr "" #: application/controllers/admin/labels.php:97 -#: application/controllers/admin/surveyadmin.php:200 +#: application/controllers/admin/surveyadmin.php:243 msgid "This ZIP archive contains no valid Resources files. Import failed." msgstr "" @@ -2393,45 +2393,45 @@ msgstr "" msgid "Text box" msgstr "" -#: application/controllers/admin/participantsaction.php:345 +#: application/controllers/admin/participantsaction.php:350 msgid "Attribute display setting updated" msgstr "" -#: application/controllers/admin/participantsaction.php:540 -#: application/controllers/admin/participantsaction.php:560 +#: application/controllers/admin/participantsaction.php:545 +#: application/controllers/admin/participantsaction.php:565 msgid "Export %s participant(s) to CSV" msgstr "" -#: application/controllers/admin/participantsaction.php:661 -#: application/controllers/admin/participantsaction.php:675 +#: application/controllers/admin/participantsaction.php:666 +#: application/controllers/admin/participantsaction.php:680 msgid "%s participant(s) are to be copied " msgstr "" -#: application/controllers/admin/participantsaction.php:1753 +#: application/controllers/admin/participantsaction.php:1758 msgid "%s participants have been shared" msgstr "" -#: application/controllers/admin/participantsaction.php:1773 +#: application/controllers/admin/participantsaction.php:1778 msgid "%s participants have been copied to the central participants table" msgstr "" -#: application/controllers/admin/participantsaction.php:1776 -#: application/controllers/admin/participantsaction.php:1800 -#: application/controllers/admin/participantsaction.php:1830 +#: application/controllers/admin/participantsaction.php:1781 +#: application/controllers/admin/participantsaction.php:1805 +#: application/controllers/admin/participantsaction.php:1835 msgid "%s entries were not copied because they already existed" msgstr "" -#: application/controllers/admin/participantsaction.php:1780 +#: application/controllers/admin/participantsaction.php:1785 msgid "Attribute values for existing participants have been updated from the token records" msgstr "" -#: application/controllers/admin/participantsaction.php:1797 -#: application/controllers/admin/participantsaction.php:1827 +#: application/controllers/admin/participantsaction.php:1802 +#: application/controllers/admin/participantsaction.php:1832 msgid "%s participants have been copied to the survey token table" msgstr "" -#: application/controllers/admin/participantsaction.php:1804 -#: application/controllers/admin/participantsaction.php:1834 +#: application/controllers/admin/participantsaction.php:1809 +#: application/controllers/admin/participantsaction.php:1839 msgid "Attribute values for existing participants have been updated from the participants records" msgstr "" @@ -2507,10 +2507,10 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:827 #: application/controllers/admin/printablesurvey.php:829 -#: application/helpers/qanda_helper.php:2661 -#: application/helpers/qanda_helper.php:2662 -#: application/helpers/qanda_helper.php:2693 -#: application/helpers/qanda_helper.php:2696 +#: application/helpers/qanda_helper.php:2719 +#: application/helpers/qanda_helper.php:2720 +#: application/helpers/qanda_helper.php:2751 +#: application/helpers/qanda_helper.php:2754 msgid "Make a comment on your choice here:" msgstr "" @@ -2535,10 +2535,10 @@ msgstr "" #: application/controllers/admin/printablesurvey.php:934 #: application/helpers/expressions/em_manager_helper.php:2966 #: application/helpers/expressions/em_manager_helper.php:5511 -#: application/helpers/qanda_helper.php:1331 -#: application/helpers/qanda_helper.php:1657 -#: application/helpers/qanda_helper.php:2192 -#: application/helpers/qanda_helper.php:2553 +#: application/helpers/qanda_helper.php:1389 +#: application/helpers/qanda_helper.php:1715 +#: application/helpers/qanda_helper.php:2250 +#: application/helpers/qanda_helper.php:2611 msgid "Other:" msgstr "" @@ -2688,8 +2688,8 @@ msgstr "" #: application/controllers/admin/responses.php:130 #: application/controllers/admin/responses.php:465 -#: application/helpers/common_helper.php:5446 -#: application/helpers/replacements_helper.php:628 +#: application/helpers/common_helper.php:5447 +#: application/helpers/replacements_helper.php:627 #: application/views/admin/export/exportresults_view.php:119 #: application/views/admin/participants/displayParticipants_view.php:65 #: application/views/admin/participants/displayParticipants_view.php:158 @@ -2704,8 +2704,8 @@ msgstr "" #: application/controllers/admin/responses.php:131 #: application/controllers/admin/responses.php:466 -#: application/helpers/common_helper.php:5447 -#: application/helpers/replacements_helper.php:635 +#: application/helpers/common_helper.php:5448 +#: application/helpers/replacements_helper.php:634 #: application/views/admin/export/exportresults_view.php:120 #: application/views/admin/participants/displayParticipants_view.php:66 #: application/views/admin/participants/displayParticipants_view.php:158 @@ -2780,149 +2780,153 @@ msgstr "" msgid "You do not have the Freetype Library installed. Showing charts requires the Freetype library to function properly." msgstr "" -#: application/controllers/admin/surveyadmin.php:407 -#: application/controllers/admin/surveyadmin.php:424 +#: application/controllers/admin/surveyadmin.php:108 +msgid "Question codes were successfully regenerated." +msgstr "" + +#: application/controllers/admin/surveyadmin.php:450 +#: application/controllers/admin/surveyadmin.php:467 #: application/views/admin/survey/activateSurvey_view.php:5 #: application/views/admin/survey/activateSurvey_view.php:35 msgid "Activate Survey" msgstr "" -#: application/controllers/admin/surveyadmin.php:410 +#: application/controllers/admin/surveyadmin.php:453 msgid "Survey table could not be created." msgstr "" -#: application/controllers/admin/surveyadmin.php:414 +#: application/controllers/admin/surveyadmin.php:457 msgid "Timings table could not be created." msgstr "" -#: application/controllers/admin/surveyadmin.php:417 +#: application/controllers/admin/surveyadmin.php:460 msgid "Database error!!" msgstr "" -#: application/controllers/admin/surveyadmin.php:425 +#: application/controllers/admin/surveyadmin.php:468 msgid "Survey has been activated. Results table has been successfully created." msgstr "" -#: application/controllers/admin/surveyadmin.php:430 +#: application/controllers/admin/surveyadmin.php:473 msgid "The required directory for saving the uploaded files couldn't be created. Please check file premissions on the /upload/surveys directory." msgstr "" -#: application/controllers/admin/surveyadmin.php:436 +#: application/controllers/admin/surveyadmin.php:479 msgid "This survey allows public registration. A token table must also be created." msgstr "" -#: application/controllers/admin/surveyadmin.php:437 +#: application/controllers/admin/surveyadmin.php:480 #: application/views/admin/token/tokenwarning.php:23 msgid "Initialise tokens" msgstr "" -#: application/controllers/admin/surveyadmin.php:441 +#: application/controllers/admin/surveyadmin.php:484 msgid "This survey is now active, and responses can be recorded." msgstr "" -#: application/controllers/admin/surveyadmin.php:442 +#: application/controllers/admin/surveyadmin.php:485 msgid "Open-access mode" msgstr "" -#: application/controllers/admin/surveyadmin.php:442 +#: application/controllers/admin/surveyadmin.php:485 msgid "No invitation code is needed to complete the survey." msgstr "" -#: application/controllers/admin/surveyadmin.php:442 +#: application/controllers/admin/surveyadmin.php:485 msgid "You can switch to the closed-access mode by initialising a token table with the button below." msgstr "" -#: application/controllers/admin/surveyadmin.php:443 +#: application/controllers/admin/surveyadmin.php:486 msgid "Switch to closed-access mode" msgstr "" -#: application/controllers/admin/surveyadmin.php:444 +#: application/controllers/admin/surveyadmin.php:487 #: application/views/admin/token/tokenwarning.php:24 msgid "No, thanks." msgstr "" -#: application/controllers/admin/surveyadmin.php:547 +#: application/controllers/admin/surveyadmin.php:590 #: application/views/admin/survey/surveybar_view.php:19 msgid "This survey is active but expired." msgstr "" -#: application/controllers/admin/surveyadmin.php:551 +#: application/controllers/admin/surveyadmin.php:594 #: application/views/admin/survey/surveybar_view.php:21 msgid "This survey is active but has a start date." msgstr "" -#: application/controllers/admin/surveyadmin.php:557 +#: application/controllers/admin/surveyadmin.php:600 msgid "This survey is active - click here to stop this survey." msgstr "" -#: application/controllers/admin/surveyadmin.php:561 +#: application/controllers/admin/surveyadmin.php:604 #: application/views/admin/survey/QuestionGroups/questiongroupbar_view.php:105 #: application/views/admin/survey/surveybar_view.php:23 -#: application/views/admin/survey/surveybar_view.php:219 -#: application/views/admin/survey/surveybar_view.php:280 +#: application/views/admin/survey/surveybar_view.php:230 +#: application/views/admin/survey/surveybar_view.php:291 msgid "This survey is currently active." msgstr "" -#: application/controllers/admin/surveyadmin.php:571 +#: application/controllers/admin/surveyadmin.php:614 msgid "This survey is currently not active - click here to activate this survey." msgstr "" -#: application/controllers/admin/surveyadmin.php:575 +#: application/controllers/admin/surveyadmin.php:618 msgid "This survey is currently not active." msgstr "" -#: application/controllers/admin/surveyadmin.php:597 +#: application/controllers/admin/surveyadmin.php:640 #: application/views/admin/survey/listSurveys_view.php:36 msgid "Closed" msgstr "" -#: application/controllers/admin/surveyadmin.php:601 +#: application/controllers/admin/surveyadmin.php:644 #: application/views/admin/survey/listSurveys_view.php:35 msgid "Open" msgstr "" -#: application/controllers/admin/surveyadmin.php:672 +#: application/controllers/admin/surveyadmin.php:715 msgid "Survey deleted." msgstr "" -#: application/controllers/admin/surveyadmin.php:747 +#: application/controllers/admin/surveyadmin.php:790 #: application/views/admin/survey/Question/answerOptions_view.php:43 #: application/views/admin/survey/Question/subQuestion_view.php:41 #: application/views/admin/token/managetokenattributes.php:12 msgid "Base Language" msgstr "" -#: application/controllers/admin/surveyadmin.php:808 +#: application/controllers/admin/surveyadmin.php:851 msgid "Import survey data" msgstr "" -#: application/controllers/admin/surveyadmin.php:809 +#: application/controllers/admin/surveyadmin.php:852 msgid "Survey structure import summary" msgstr "" -#: application/controllers/admin/surveyadmin.php:814 +#: application/controllers/admin/surveyadmin.php:857 #: application/views/admin/survey/copySurvey_view.php:1 #: application/views/admin/survey/subview/tabCopy_view.php:21 msgid "Copy survey" msgstr "" -#: application/controllers/admin/surveyadmin.php:815 +#: application/controllers/admin/surveyadmin.php:858 msgid "Survey copy summary" msgstr "" -#: application/controllers/admin/surveyadmin.php:845 +#: application/controllers/admin/surveyadmin.php:888 msgid "Import failed. You specified an invalid file type." msgstr "" -#: application/controllers/admin/surveyadmin.php:882 +#: application/controllers/admin/surveyadmin.php:925 msgid "No survey ID has been provided. Cannot copy survey" msgstr "" -#: application/controllers/admin/surveyadmin.php:1017 +#: application/controllers/admin/surveyadmin.php:1060 msgid "The new question group/question order was successfully saved." msgstr "" -#: application/controllers/admin/surveyadmin.php:1285 +#: application/controllers/admin/surveyadmin.php:1325 #: application/views/admin/labels/labelview_view.php:136 #: application/views/admin/labels/labelview_view.php:148 #: application/views/admin/survey/Question/editQuestion_view.php:282 @@ -2934,21 +2938,21 @@ msgstr "" msgid "Please select a file to import!" msgstr "" -#: application/controllers/admin/surveyadmin.php:1288 +#: application/controllers/admin/surveyadmin.php:1328 #: application/views/admin/labels/labelview_view.php:148 #: application/views/admin/templates/importform_view.php:16 msgid "zip library not supported by PHP, Import ZIP Disabled" msgstr "" -#: application/controllers/admin/surveyadmin.php:1313 +#: application/controllers/admin/surveyadmin.php:1353 msgid "The survey was successfully expired by setting an expiration date in the survey settings." msgstr "" -#: application/controllers/admin/surveyadmin.php:1428 +#: application/controllers/admin/surveyadmin.php:1468 msgid "Survey could not be created because it did not have a title" msgstr "" -#: application/controllers/admin/surveyadmin.php:1560 +#: application/controllers/admin/surveyadmin.php:1600 msgid "Survey was successfully added." msgstr "" @@ -3125,7 +3129,7 @@ msgid "Export" msgstr "" #: application/controllers/admin/surveypermission.php:439 -#: application/helpers/replacements_helper.php:581 +#: application/helpers/replacements_helper.php:580 #: application/views/admin/user/setuserrights.php:119 msgid "Save Now" msgstr "" @@ -3168,12 +3172,12 @@ msgid "This file is not a valid ZIP file archive. Import failed." msgstr "" #: application/controllers/admin/templates.php:124 -#: application/core/Survey_Common_Action.php:962 +#: application/core/Survey_Common_Action.php:951 msgid "Copy failed" msgstr "" #: application/controllers/admin/templates.php:129 -#: application/core/Survey_Common_Action.php:969 +#: application/core/Survey_Common_Action.php:958 #: application/views/admin/participants/attributeMapCSV_view.php:18 #: application/views/admin/participants/displayParticipants_view.php:126 #: application/views/admin/participants/participantsPanel_view.php:5 @@ -3183,7 +3187,7 @@ msgid "OK" msgstr "" #: application/controllers/admin/templates.php:135 -#: application/core/Survey_Common_Action.php:978 +#: application/core/Survey_Common_Action.php:967 msgid "Forbidden Extension" msgstr "" @@ -3660,15 +3664,15 @@ msgstr "" #: application/helpers/common_helper.php:621 #: application/helpers/common_helper.php:1274 #: application/helpers/common_helper.php:1344 -#: application/helpers/common_helper.php:7102 -#: application/helpers/common_helper.php:7139 -#: application/helpers/common_helper.php:7535 -#: application/helpers/common_helper.php:7578 -#: application/helpers/qanda_helper.php:1293 -#: application/helpers/qanda_helper.php:1474 -#: application/helpers/qanda_helper.php:2085 -#: application/helpers/qanda_helper.php:6493 -#: application/helpers/qanda_helper.php:6547 +#: application/helpers/common_helper.php:7103 +#: application/helpers/common_helper.php:7140 +#: application/helpers/common_helper.php:7536 +#: application/helpers/common_helper.php:7579 +#: application/helpers/qanda_helper.php:1351 +#: application/helpers/qanda_helper.php:1532 +#: application/helpers/qanda_helper.php:2143 +#: application/helpers/qanda_helper.php:6551 +#: application/helpers/qanda_helper.php:6605 #: application/views/admin/dataentry/content_view.php:84 #: application/views/admin/dataentry/content_view.php:94 #: application/views/admin/labels/labelsetsbar_view.php:22 @@ -4014,8 +4018,8 @@ msgstr "" #: application/controllers/survey/index.php:431 #: application/controllers/survey/index.php:435 -#: application/helpers/replacements_helper.php:441 -#: application/helpers/replacements_helper.php:453 +#: application/helpers/replacements_helper.php:440 +#: application/helpers/replacements_helper.php:452 msgid "Load unfinished survey" msgstr "" @@ -4055,8 +4059,8 @@ msgstr "" #: application/helpers/common_helper.php:1275 #: application/helpers/common_helper.php:1345 #: application/helpers/common_helper.php:4022 -#: application/helpers/common_helper.php:7536 -#: application/helpers/common_helper.php:7579 +#: application/helpers/common_helper.php:7537 +#: application/helpers/common_helper.php:7580 #: application/views/admin/token/bounce.php:14 #: application/views/admin/token/bounce.php:57 msgid "None" @@ -4125,32 +4129,15 @@ msgstr "" msgid "Detailed email notification with response data is sent to:" msgstr "" -#: application/core/Survey_Common_Action.php:734 -msgid "Regenerate question codes:" -msgstr "" - -#: application/core/Survey_Common_Action.php:736 -#: application/core/Survey_Common_Action.php:739 -msgid "Are you sure you want regenerate the question codes?" -msgstr "" - -#: application/core/Survey_Common_Action.php:737 -msgid "Straight" -msgstr "" - -#: application/core/Survey_Common_Action.php:740 -msgid "By Group" -msgstr "" - -#: application/core/Survey_Common_Action.php:838 +#: application/core/Survey_Common_Action.php:827 msgid "Survey cannot be activated yet." msgstr "" -#: application/core/Survey_Common_Action.php:841 +#: application/core/Survey_Common_Action.php:830 msgid "You need to add question groups" msgstr "" -#: application/core/Survey_Common_Action.php:845 +#: application/core/Survey_Common_Action.php:834 msgid "You need to add questions" msgstr "" @@ -4176,7 +4163,7 @@ msgid "Clear Responses" msgstr "" #: application/helpers/SurveyRuntimeHelper.php:449 -#: application/helpers/replacements_helper.php:844 +#: application/helpers/replacements_helper.php:843 #: application/views/admin/templates/templateeditor_completed_view.php:2 msgid "Thank you!" msgstr "" @@ -4239,7 +4226,7 @@ msgstr "" #: application/helpers/SurveyRuntimeHelper.php:1122 #: application/helpers/frontend_helper.php:2234 -#: application/helpers/replacements_helper.php:384 +#: application/helpers/replacements_helper.php:383 #: application/views/admin/dataentry/active_html_view.php:67 #: application/views/admin/dataentry/includes/editdata/editdata.php:57 #: application/views/admin/dataentry/insert.php:41 @@ -5108,7 +5095,7 @@ msgstr "" #: application/helpers/common_helper.php:3998 #: application/helpers/common_helper.php:4010 #: application/helpers/common_helper.php:4019 -#: application/helpers/common_helper.php:4231 +#: application/helpers/common_helper.php:4232 msgid "Display" msgstr "" @@ -5151,7 +5138,7 @@ msgstr "" #: application/helpers/common_helper.php:3613 #: application/helpers/common_helper.php:3766 #: application/helpers/common_helper.php:3777 -#: application/helpers/common_helper.php:4302 +#: application/helpers/common_helper.php:4303 msgid "Logic" msgstr "" @@ -5177,7 +5164,7 @@ msgstr "" #: application/helpers/common_helper.php:3241 #: application/views/admin/survey/QuestionGroups/questiongroupbar_view.php:105 -#: application/views/admin/survey/surveybar_view.php:280 +#: application/views/admin/survey/surveybar_view.php:291 msgid "Disabled" msgstr "" @@ -5294,7 +5281,7 @@ msgstr "" #: application/helpers/common_helper.php:3699 #: application/helpers/common_helper.php:4215 #: application/helpers/common_helper.php:4223 -#: application/helpers/common_helper.php:4314 +#: application/helpers/common_helper.php:4315 msgid "Input" msgstr "" @@ -6084,113 +6071,113 @@ msgstr "" msgid "Date/Time format" msgstr "" -#: application/helpers/common_helper.php:4226 +#: application/helpers/common_helper.php:4227 msgid "Minute step interval when using select boxes" msgstr "" -#: application/helpers/common_helper.php:4227 +#: application/helpers/common_helper.php:4228 msgid "Minute step interval" msgstr "" -#: application/helpers/common_helper.php:4234 +#: application/helpers/common_helper.php:4235 msgid "Short names" msgstr "" -#: application/helpers/common_helper.php:4235 +#: application/helpers/common_helper.php:4236 msgid "Full names" msgstr "" -#: application/helpers/common_helper.php:4236 +#: application/helpers/common_helper.php:4237 msgid "Numbers" msgstr "" -#: application/helpers/common_helper.php:4238 +#: application/helpers/common_helper.php:4239 msgid "Change the display style of the month when using select boxes" msgstr "" -#: application/helpers/common_helper.php:4239 +#: application/helpers/common_helper.php:4240 msgid "Month display style" msgstr "" -#: application/helpers/common_helper.php:4243 -#: application/helpers/common_helper.php:4254 +#: application/helpers/common_helper.php:4244 +#: application/helpers/common_helper.php:4255 msgid "File metadata" msgstr "" -#: application/helpers/common_helper.php:4249 +#: application/helpers/common_helper.php:4250 msgid "Is the participant required to give a title to the uploaded file?" msgstr "" -#: application/helpers/common_helper.php:4250 +#: application/helpers/common_helper.php:4251 msgid "Show title" msgstr "" -#: application/helpers/common_helper.php:4260 +#: application/helpers/common_helper.php:4261 msgid "Is the participant required to give a comment to the uploaded file?" msgstr "" -#: application/helpers/common_helper.php:4261 +#: application/helpers/common_helper.php:4262 msgid "Show comment" msgstr "" -#: application/helpers/common_helper.php:4270 +#: application/helpers/common_helper.php:4271 msgid "The participant cannot upload a single file larger than this size" msgstr "" -#: application/helpers/common_helper.php:4271 +#: application/helpers/common_helper.php:4272 msgid "Maximum file size allowed (in KB)" msgstr "" -#: application/helpers/common_helper.php:4279 +#: application/helpers/common_helper.php:4280 msgid "Maximum number of files that the participant can upload for this question" msgstr "" -#: application/helpers/common_helper.php:4280 +#: application/helpers/common_helper.php:4281 msgid "Max number of files" msgstr "" -#: application/helpers/common_helper.php:4288 +#: application/helpers/common_helper.php:4289 msgid "Minimum number of files that the participant must upload for this question" msgstr "" -#: application/helpers/common_helper.php:4289 +#: application/helpers/common_helper.php:4290 msgid "Min number of files" msgstr "" -#: application/helpers/common_helper.php:4297 +#: application/helpers/common_helper.php:4298 msgid "Allowed file types in comma separated format. e.g. pdf,doc,odt" msgstr "" -#: application/helpers/common_helper.php:4298 +#: application/helpers/common_helper.php:4299 msgid "Allowed file types" msgstr "" -#: application/helpers/common_helper.php:4305 +#: application/helpers/common_helper.php:4306 msgid "Place questions into a specified randomization group, all questions included in the specified group will appear in a random order" msgstr "" -#: application/helpers/common_helper.php:4306 +#: application/helpers/common_helper.php:4307 msgid "Randomization group name" msgstr "" -#: application/helpers/common_helper.php:4320 +#: application/helpers/common_helper.php:4321 msgid "Is no answer (missing) allowed when either 'Equals sum value' or 'Minimum sum value' are set?" msgstr "" -#: application/helpers/common_helper.php:4321 +#: application/helpers/common_helper.php:4322 msgid "Value range allows missing" msgstr "" -#: application/helpers/common_helper.php:4455 +#: application/helpers/common_helper.php:4456 msgid "Email was not sent because demo-mode is activated." msgstr "" -#: application/helpers/common_helper.php:4576 +#: application/helpers/common_helper.php:4577 msgid "SMTP debug output:" msgstr "" -#: application/helpers/common_helper.php:5448 -#: application/helpers/replacements_helper.php:642 +#: application/helpers/common_helper.php:5449 +#: application/helpers/replacements_helper.php:641 #: application/views/admin/export/exportresults_view.php:121 #: application/views/admin/saved/savedlist_view.php:10 #: application/views/admin/token/browse.php:77 @@ -6198,132 +6185,132 @@ msgstr "" msgid "Email address" msgstr "" -#: application/helpers/common_helper.php:5449 +#: application/helpers/common_helper.php:5450 msgid "Token code" msgstr "" -#: application/helpers/common_helper.php:5450 +#: application/helpers/common_helper.php:5451 msgid "Language code" msgstr "" -#: application/helpers/common_helper.php:5451 +#: application/helpers/common_helper.php:5452 msgid "Invitation sent date" msgstr "" -#: application/helpers/common_helper.php:5452 +#: application/helpers/common_helper.php:5453 msgid "Last Reminder sent date" msgstr "" -#: application/helpers/common_helper.php:5453 +#: application/helpers/common_helper.php:5454 msgid "Total numbers of sent reminders" msgstr "" -#: application/helpers/common_helper.php:5454 +#: application/helpers/common_helper.php:5455 #: application/views/admin/token/browse.php:77 #: application/views/admin/token/browse.php:143 msgid "Uses left" msgstr "" -#: application/helpers/common_helper.php:5473 +#: application/helpers/common_helper.php:5474 msgid "Attribute %s" msgstr "" -#: application/helpers/common_helper.php:6354 +#: application/helpers/common_helper.php:6355 msgid "Access denied!" msgstr "" -#: application/helpers/common_helper.php:6359 +#: application/helpers/common_helper.php:6360 msgid "You are not allowed dump the database!" msgstr "" -#: application/helpers/common_helper.php:6364 +#: application/helpers/common_helper.php:6365 msgid "You are not allowed export a label set!" msgstr "" -#: application/helpers/common_helper.php:6369 +#: application/helpers/common_helper.php:6370 msgid "You are not allowed to change user data!" msgstr "" -#: application/helpers/common_helper.php:6374 +#: application/helpers/common_helper.php:6375 msgid "You are not allowed to create new surveys!" msgstr "" -#: application/helpers/common_helper.php:6379 +#: application/helpers/common_helper.php:6380 msgid "You are not allowed to delete this survey!" msgstr "" -#: application/helpers/common_helper.php:6384 +#: application/helpers/common_helper.php:6385 msgid "You are not allowed to add new questions for this survey!" msgstr "" -#: application/helpers/common_helper.php:6389 +#: application/helpers/common_helper.php:6390 msgid "You are not allowed to activate this survey!" msgstr "" -#: application/helpers/common_helper.php:6394 +#: application/helpers/common_helper.php:6395 msgid "You are not allowed to stop this survey!" msgstr "" -#: application/helpers/common_helper.php:6399 +#: application/helpers/common_helper.php:6400 msgid "You are not allowed to add a group to this survey!" msgstr "" -#: application/helpers/common_helper.php:6405 +#: application/helpers/common_helper.php:6406 msgid "You are not allowed to order groups in this survey!" msgstr "" -#: application/helpers/common_helper.php:6411 +#: application/helpers/common_helper.php:6412 msgid "You are not allowed to edit this survey!" msgstr "" -#: application/helpers/common_helper.php:6416 +#: application/helpers/common_helper.php:6417 msgid "You are not allowed to edit groups in this survey!" msgstr "" -#: application/helpers/common_helper.php:6421 +#: application/helpers/common_helper.php:6422 msgid "You are not allowed to browse responses!" msgstr "" -#: application/helpers/common_helper.php:6426 +#: application/helpers/common_helper.php:6427 msgid "You are not allowed to set assessment rules!" msgstr "" -#: application/helpers/common_helper.php:6431 +#: application/helpers/common_helper.php:6432 msgid "You are not allowed to delete this group!" msgstr "" -#: application/helpers/common_helper.php:6436 +#: application/helpers/common_helper.php:6437 msgid "You are not allowed to import a survey!" msgstr "" -#: application/helpers/common_helper.php:6442 +#: application/helpers/common_helper.php:6443 msgid "You are not allowed to import a group!" msgstr "" -#: application/helpers/common_helper.php:6447 +#: application/helpers/common_helper.php:6448 msgid "You are not allowed to to import a question!" msgstr "" -#: application/helpers/common_helper.php:6456 -#: application/helpers/common_helper.php:6461 +#: application/helpers/common_helper.php:6457 +#: application/helpers/common_helper.php:6462 msgid "Security alert" msgstr "" -#: application/helpers/common_helper.php:6456 -#: application/helpers/common_helper.php:6461 +#: application/helpers/common_helper.php:6457 +#: application/helpers/common_helper.php:6462 msgid "Someone may be trying to use your LimeSurvey session (CSRF attack suspected). If you just clicked on a malicious link, please report this to your system administrator." msgstr "" -#: application/helpers/common_helper.php:6456 -#: application/helpers/common_helper.php:6461 +#: application/helpers/common_helper.php:6457 +#: application/helpers/common_helper.php:6462 msgid "Also this problem can occur when you are working/editing in LimeSurvey in several browser windows/tabs at the same time." msgstr "" -#: application/helpers/common_helper.php:6466 +#: application/helpers/common_helper.php:6467 msgid "You are not allowed to perform this operation!" msgstr "" -#: application/helpers/common_helper.php:7213 +#: application/helpers/common_helper.php:7214 msgid "SQL command failed: %s" msgstr "" @@ -7057,9 +7044,9 @@ msgstr "" #: application/helpers/frontend_helper.php:1521 #: application/helpers/frontend_helper.php:1694 -#: application/helpers/replacements_helper.php:578 -#: application/helpers/replacements_helper.php:599 -#: application/helpers/replacements_helper.php:662 +#: application/helpers/replacements_helper.php:577 +#: application/helpers/replacements_helper.php:598 +#: application/helpers/replacements_helper.php:661 msgid "Security Question" msgstr "" @@ -7123,7 +7110,7 @@ msgstr "" #: application/helpers/qanda_helper.php:200 #: application/helpers/qanda_helper.php:201 -#: application/helpers/qanda_helper.php:1291 +#: application/helpers/qanda_helper.php:1349 msgid "Choose your language" msgstr "" @@ -7167,155 +7154,164 @@ msgstr "" msgid "seconds" msgstr "" -#: application/helpers/qanda_helper.php:1106 -#: application/helpers/qanda_helper.php:1107 +#: application/helpers/qanda_helper.php:1111 +#: application/helpers/qanda_helper.php:1112 msgid "Day" msgstr "" -#: application/helpers/qanda_helper.php:1123 -#: application/helpers/qanda_helper.php:1124 +#: application/helpers/qanda_helper.php:1128 +#: application/helpers/qanda_helper.php:1129 msgid "Month" msgstr "" -#: application/helpers/qanda_helper.php:1126 +#: application/helpers/qanda_helper.php:1131 msgid "Jan" msgstr "" -#: application/helpers/qanda_helper.php:1127 +#: application/helpers/qanda_helper.php:1132 msgid "Feb" msgstr "" -#: application/helpers/qanda_helper.php:1128 +#: application/helpers/qanda_helper.php:1133 msgid "Mar" msgstr "" -#: application/helpers/qanda_helper.php:1129 +#: application/helpers/qanda_helper.php:1134 msgid "Apr" msgstr "" -#: application/helpers/qanda_helper.php:1130 +#: application/helpers/qanda_helper.php:1135 msgid "May" msgstr "" -#: application/helpers/qanda_helper.php:1131 +#: application/helpers/qanda_helper.php:1136 msgid "Jun" msgstr "" -#: application/helpers/qanda_helper.php:1132 +#: application/helpers/qanda_helper.php:1137 msgid "Jul" msgstr "" -#: application/helpers/qanda_helper.php:1133 +#: application/helpers/qanda_helper.php:1138 msgid "Aug" msgstr "" -#: application/helpers/qanda_helper.php:1134 +#: application/helpers/qanda_helper.php:1139 msgid "Sep" msgstr "" -#: application/helpers/qanda_helper.php:1135 +#: application/helpers/qanda_helper.php:1140 msgid "Oct" msgstr "" -#: application/helpers/qanda_helper.php:1136 +#: application/helpers/qanda_helper.php:1141 msgid "Nov" msgstr "" -#: application/helpers/qanda_helper.php:1137 +#: application/helpers/qanda_helper.php:1142 msgid "Dec" msgstr "" -#: application/helpers/qanda_helper.php:1153 -#: application/helpers/qanda_helper.php:1154 +#: application/helpers/qanda_helper.php:1158 +#: application/helpers/qanda_helper.php:1159 msgid "Year" msgstr "" -#: application/helpers/qanda_helper.php:1264 +#: application/helpers/qanda_helper.php:1224 +msgid "Hour" +msgstr "" + +#: application/helpers/qanda_helper.php:1247 +#: application/helpers/qanda_helper.php:1248 +msgid "Minute" +msgstr "" + +#: application/helpers/qanda_helper.php:1322 msgid "Date picker" msgstr "" -#: application/helpers/qanda_helper.php:1265 -#: application/helpers/qanda_helper.php:1272 +#: application/helpers/qanda_helper.php:1323 +#: application/helpers/qanda_helper.php:1330 #: application/views/admin/token/dummytokenform.php:38 #: application/views/admin/token/tokenform.php:148 msgid "Format: %s" msgstr "" -#: application/helpers/qanda_helper.php:1552 +#: application/helpers/qanda_helper.php:1610 msgid "Other answer" msgstr "" -#: application/helpers/qanda_helper.php:1905 +#: application/helpers/qanda_helper.php:1963 msgid "Please enter your comment here" msgstr "" -#: application/helpers/qanda_helper.php:2077 +#: application/helpers/qanda_helper.php:2135 msgid "First choice" msgstr "" -#: application/helpers/qanda_helper.php:2079 +#: application/helpers/qanda_helper.php:2137 msgid "Next choice" msgstr "" -#: application/helpers/qanda_helper.php:2775 +#: application/helpers/qanda_helper.php:2833 msgid "Upload files" msgstr "" -#: application/helpers/qanda_helper.php:2787 +#: application/helpers/qanda_helper.php:2845 msgid "Upload your files" msgstr "" -#: application/helpers/qanda_helper.php:2788 +#: application/helpers/qanda_helper.php:2846 msgid "Return to survey" msgstr "" -#: application/helpers/qanda_helper.php:2791 +#: application/helpers/qanda_helper.php:2849 msgid "File name" msgstr "" -#: application/helpers/qanda_helper.php:2967 -#: application/helpers/qanda_helper.php:3286 -#: application/helpers/qanda_helper.php:4517 -#: application/helpers/qanda_helper.php:6364 +#: application/helpers/qanda_helper.php:3025 +#: application/helpers/qanda_helper.php:3344 +#: application/helpers/qanda_helper.php:4575 +#: application/helpers/qanda_helper.php:6422 msgid "Error: This question has no answers." msgstr "" -#: application/helpers/qanda_helper.php:3429 +#: application/helpers/qanda_helper.php:3487 msgid "Only numbers may be entered in these fields" msgstr "" -#: application/helpers/qanda_helper.php:3468 +#: application/helpers/qanda_helper.php:3526 msgid "Remaining: " msgstr "" -#: application/helpers/qanda_helper.php:3476 +#: application/helpers/qanda_helper.php:3534 msgid "Total: " msgstr "" -#: application/helpers/qanda_helper.php:3678 -#: application/helpers/qanda_helper.php:3683 +#: application/helpers/qanda_helper.php:3736 +#: application/helpers/qanda_helper.php:3741 #: application/views/admin/dataentry/content_view.php:408 msgid "Only numbers may be entered in this field." msgstr "" -#: application/helpers/qanda_helper.php:3862 -#: application/helpers/qanda_helper.php:3863 +#: application/helpers/qanda_helper.php:3920 +#: application/helpers/qanda_helper.php:3921 msgid "Drag and drop the pin to the desired location. You may also right click on the map to move the pin." msgstr "" -#: application/helpers/qanda_helper.php:5089 -#: application/helpers/qanda_helper.php:5468 -#: application/helpers/qanda_helper.php:5824 -#: application/helpers/qanda_helper.php:5972 -#: application/helpers/qanda_helper.php:6593 +#: application/helpers/qanda_helper.php:5147 +#: application/helpers/qanda_helper.php:5526 +#: application/helpers/qanda_helper.php:5882 +#: application/helpers/qanda_helper.php:6030 +#: application/helpers/qanda_helper.php:6651 msgid "Error: There are no answer options for this question and/or they don't exist in this language." msgstr "" -#: application/helpers/qanda_helper.php:5741 +#: application/helpers/qanda_helper.php:5799 msgid "..." msgstr "" -#: application/helpers/qanda_helper.php:5966 +#: application/helpers/qanda_helper.php:6024 msgid "Error: There are no answers defined for this question." msgstr "" @@ -7331,130 +7327,130 @@ msgstr "" msgid "There are {NUMBEROFQUESTIONS} questions in this survey." msgstr "" -#: application/helpers/replacements_helper.php:412 +#: application/helpers/replacements_helper.php:411 msgid "Exit and Clear Survey" msgstr "" -#: application/helpers/replacements_helper.php:413 +#: application/helpers/replacements_helper.php:412 msgid "Are you sure you want to clear all your responses?" msgstr "" -#: application/helpers/replacements_helper.php:442 -#: application/helpers/replacements_helper.php:446 -#: application/helpers/replacements_helper.php:466 +#: application/helpers/replacements_helper.php:441 +#: application/helpers/replacements_helper.php:445 +#: application/helpers/replacements_helper.php:465 msgid "Resume later" msgstr "" -#: application/helpers/replacements_helper.php:505 +#: application/helpers/replacements_helper.php:504 msgid "If you want to check any of the answers you have made, and/or change them, you can do that now by clicking on the [<< prev] button and browsing through your responses." msgstr "" -#: application/helpers/replacements_helper.php:512 -#: application/helpers/replacements_helper.php:521 +#: application/helpers/replacements_helper.php:511 +#: application/helpers/replacements_helper.php:520 msgid "Restart this Survey" msgstr "" -#: application/helpers/replacements_helper.php:530 +#: application/helpers/replacements_helper.php:529 msgid "To remain anonymous please use a pseudonym as your username, also an email address is not required." msgstr "" -#: application/helpers/replacements_helper.php:544 +#: application/helpers/replacements_helper.php:543 msgid "Return To Survey" msgstr "" -#: application/helpers/replacements_helper.php:564 +#: application/helpers/replacements_helper.php:563 msgid "Repeat Password" msgstr "" -#: application/helpers/replacements_helper.php:570 +#: application/helpers/replacements_helper.php:569 msgid "Your Email" msgstr "" -#: application/helpers/replacements_helper.php:585 +#: application/helpers/replacements_helper.php:584 msgid "Saved name" msgstr "" -#: application/helpers/replacements_helper.php:602 +#: application/helpers/replacements_helper.php:601 msgid "Load Now" msgstr "" -#: application/helpers/replacements_helper.php:781 +#: application/helpers/replacements_helper.php:780 msgid "Answers Cleared" msgstr "" -#: application/helpers/replacements_helper.php:784 +#: application/helpers/replacements_helper.php:783 msgid "Your Assessment" msgstr "" -#: application/helpers/replacements_helper.php:785 +#: application/helpers/replacements_helper.php:784 msgid "Caution: JavaScript execution is disabled in your browser. You may not be able to answer all questions in this survey. Please, verify your browser parameters." msgstr "" -#: application/helpers/replacements_helper.php:787 +#: application/helpers/replacements_helper.php:786 msgid "Close this window" msgstr "" -#: application/helpers/replacements_helper.php:801 +#: application/helpers/replacements_helper.php:800 msgid "Load A Previously Saved Survey" msgstr "" -#: application/helpers/replacements_helper.php:802 +#: application/helpers/replacements_helper.php:801 msgid "You can load a survey that you have previously saved from this screen." msgstr "" -#: application/helpers/replacements_helper.php:802 +#: application/helpers/replacements_helper.php:801 msgid "Type in the 'name' you used to save the survey, and the password." msgstr "" -#: application/helpers/replacements_helper.php:810 +#: application/helpers/replacements_helper.php:809 msgid "A Note On Privacy" msgstr "" -#: application/helpers/replacements_helper.php:810 +#: application/helpers/replacements_helper.php:809 msgid "This survey is anonymous." msgstr "" -#: application/helpers/replacements_helper.php:810 +#: application/helpers/replacements_helper.php:809 msgid "The record kept of your survey responses does not contain any identifying information about you unless a specific question in the survey has asked for this. If you have responded to a survey that used an identifying token to allow you to access the survey, you can rest assured that the identifying token is not kept with your responses. It is managed in a separate database, and will only be updated to indicate that you have (or haven't) completed this survey. There is no way of matching identification tokens with survey responses in this survey." msgstr "" -#: application/helpers/replacements_helper.php:829 +#: application/helpers/replacements_helper.php:828 msgid "You must be registered to complete this survey" msgstr "" -#: application/helpers/replacements_helper.php:830 +#: application/helpers/replacements_helper.php:829 msgid "You may register for this survey if you wish to take part." msgstr "" -#: application/helpers/replacements_helper.php:830 +#: application/helpers/replacements_helper.php:829 msgid "Enter your details below, and an email containing the link to participate in this survey will be sent immediately." msgstr "" -#: application/helpers/replacements_helper.php:838 +#: application/helpers/replacements_helper.php:837 msgid "Save Your Unfinished Survey" msgstr "" -#: application/helpers/replacements_helper.php:839 +#: application/helpers/replacements_helper.php:838 msgid "Enter a name and password for this survey and click save below." msgstr "" -#: application/helpers/replacements_helper.php:839 +#: application/helpers/replacements_helper.php:838 msgid "Your survey will be saved using that name and password, and can be completed later by logging in with the same name and password." msgstr "" -#: application/helpers/replacements_helper.php:839 +#: application/helpers/replacements_helper.php:838 msgid "If you give an email address, an email containing the details will be sent to you." msgstr "" -#: application/helpers/replacements_helper.php:839 +#: application/helpers/replacements_helper.php:838 msgid "After having clicked the save button you can either close this browser window or continue filling out the survey." msgstr "" -#: application/helpers/replacements_helper.php:844 +#: application/helpers/replacements_helper.php:843 msgid "You have completed answering the questions in this survey." msgstr "" -#: application/helpers/replacements_helper.php:844 +#: application/helpers/replacements_helper.php:843 msgid "Click on 'Submit' now to complete the process and save your answers." msgstr "" @@ -7870,7 +7866,7 @@ msgstr "" #: application/models/Survey_permissions.php:67 #: application/views/admin/export/exportresults_view.php:36 #: application/views/admin/survey/importSurvey_view.php:68 -#: application/views/admin/survey/surveybar_view.php:185 +#: application/views/admin/survey/surveybar_view.php:196 msgid "Responses" msgstr "" @@ -12646,120 +12642,132 @@ msgstr "" msgid "Currently there are no conditions configured for this survey." msgstr "" -#: application/views/admin/survey/surveybar_view.php:125 +#: application/views/admin/survey/surveybar_view.php:123 +msgid "Regenerate question codes" +msgstr "" + +#: application/views/admin/survey/surveybar_view.php:127 +msgid "Straight" +msgstr "" + +#: application/views/admin/survey/surveybar_view.php:130 +msgid "By question group" +msgstr "" + +#: application/views/admin/survey/surveybar_view.php:136 msgid "Display / Export" msgstr "" -#: application/views/admin/survey/surveybar_view.php:128 +#: application/views/admin/survey/surveybar_view.php:139 msgid "Export..." msgstr "" -#: application/views/admin/survey/surveybar_view.php:133 +#: application/views/admin/survey/surveybar_view.php:144 msgid "Survey structure (.lss)" msgstr "" -#: application/views/admin/survey/surveybar_view.php:139 -#: application/views/admin/survey/surveybar_view.php:144 +#: application/views/admin/survey/surveybar_view.php:150 +#: application/views/admin/survey/surveybar_view.php:155 msgid "Survey archive (.zip)" msgstr "" -#: application/views/admin/survey/surveybar_view.php:143 +#: application/views/admin/survey/surveybar_view.php:154 msgid "You can only archive active surveys." msgstr "" -#: application/views/admin/survey/surveybar_view.php:149 +#: application/views/admin/survey/surveybar_view.php:160 msgid "queXML format (*.xml)" msgstr "" -#: application/views/admin/survey/surveybar_view.php:152 +#: application/views/admin/survey/surveybar_view.php:163 msgid "Excel format (*.xls)" msgstr "" -#: application/views/admin/survey/surveybar_view.php:160 -#: application/views/admin/survey/surveybar_view.php:163 +#: application/views/admin/survey/surveybar_view.php:171 +#: application/views/admin/survey/surveybar_view.php:174 msgid "Printable version" msgstr "" -#: application/views/admin/survey/surveybar_view.php:173 -#: application/views/admin/survey/surveybar_view.php:176 +#: application/views/admin/survey/surveybar_view.php:184 +#: application/views/admin/survey/surveybar_view.php:187 msgid "QueXML export" msgstr "" -#: application/views/admin/survey/surveybar_view.php:189 -#: application/views/admin/survey/surveybar_view.php:192 +#: application/views/admin/survey/surveybar_view.php:200 +#: application/views/admin/survey/surveybar_view.php:203 msgid "Responses & statistics" msgstr "" -#: application/views/admin/survey/surveybar_view.php:191 +#: application/views/admin/survey/surveybar_view.php:202 msgid "This survey is not active - no responses are available." msgstr "" -#: application/views/admin/survey/surveybar_view.php:198 -#: application/views/admin/survey/surveybar_view.php:201 +#: application/views/admin/survey/surveybar_view.php:209 +#: application/views/admin/survey/surveybar_view.php:212 msgid "Data entry screen" msgstr "" -#: application/views/admin/survey/surveybar_view.php:200 +#: application/views/admin/survey/surveybar_view.php:211 msgid "This survey is not active, data entry is not allowed" msgstr "" -#: application/views/admin/survey/surveybar_view.php:207 -#: application/views/admin/survey/surveybar_view.php:210 +#: application/views/admin/survey/surveybar_view.php:218 +#: application/views/admin/survey/surveybar_view.php:221 msgid "Partial (saved) responses" msgstr "" -#: application/views/admin/survey/surveybar_view.php:209 +#: application/views/admin/survey/surveybar_view.php:220 msgid "This survey is not active - no responses are available" msgstr "" -#: application/views/admin/survey/surveybar_view.php:219 +#: application/views/admin/survey/surveybar_view.php:230 msgid "Question group/question organizer disabled" msgstr "" -#: application/views/admin/survey/surveybar_view.php:226 +#: application/views/admin/survey/surveybar_view.php:237 msgid "Reorder question groups / questions" msgstr "" -#: application/views/admin/survey/surveybar_view.php:232 +#: application/views/admin/survey/surveybar_view.php:243 msgid "Token management" msgstr "" -#: application/views/admin/survey/surveybar_view.php:240 +#: application/views/admin/survey/surveybar_view.php:251 msgid "Question groups:" msgstr "" -#: application/views/admin/survey/surveybar_view.php:250 +#: application/views/admin/survey/surveybar_view.php:261 msgid "Previous question group" msgstr "" -#: application/views/admin/survey/surveybar_view.php:254 +#: application/views/admin/survey/surveybar_view.php:265 msgid "No previous question group" msgstr "" -#: application/views/admin/survey/surveybar_view.php:263 +#: application/views/admin/survey/surveybar_view.php:274 msgid "Next question group" msgstr "" -#: application/views/admin/survey/surveybar_view.php:268 +#: application/views/admin/survey/surveybar_view.php:279 msgid "No next question group" msgstr "" -#: application/views/admin/survey/surveybar_view.php:287 +#: application/views/admin/survey/surveybar_view.php:298 msgid "Add new group to survey" msgstr "" -#: application/views/admin/survey/surveybar_view.php:291 -#: application/views/admin/survey/surveybar_view.php:292 +#: application/views/admin/survey/surveybar_view.php:302 +#: application/views/admin/survey/surveybar_view.php:303 msgid "Hide details of this Survey" msgstr "" -#: application/views/admin/survey/surveybar_view.php:294 -#: application/views/admin/survey/surveybar_view.php:295 +#: application/views/admin/survey/surveybar_view.php:305 +#: application/views/admin/survey/surveybar_view.php:306 msgid "Show details of this survey" msgstr "" -#: application/views/admin/survey/surveybar_view.php:298 -#: application/views/admin/survey/surveybar_view.php:299 +#: application/views/admin/survey/surveybar_view.php:309 +#: application/views/admin/survey/surveybar_view.php:310 msgid "Close this survey" msgstr "" @@ -13906,7 +13914,7 @@ msgid "Set this to the IP/net location of your database server. In most cases \" msgstr "" #: application/views/installer/dbconfig_view.php:44 -msgid "If the database not exists it will be created (necessary permission provided). If there are existing LimeSurvey tables these will be upgraded automatically after installation" +msgid "If the database does not yet exist it will be created (make sure your database user has the necessary permissions). In contrast, if there are existing LimeSurvey tables in that database they will be upgraded automatically after installation." msgstr "" #: application/views/installer/dbconfig_view.php:50 From 7a7a50ce191b661578e4f6f176df11bb5006b89e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 8 Aug 2012 01:55:44 -0400 Subject: [PATCH 65/75] Fixed issue #06439: Question type Array (numbers) does not work with numbers >10 as labels --- application/helpers/expressions/em_manager_helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/helpers/expressions/em_manager_helper.php b/application/helpers/expressions/em_manager_helper.php index ce5f7cafad3..a3ac7510e39 100644 --- a/application/helpers/expressions/em_manager_helper.php +++ b/application/helpers/expressions/em_manager_helper.php @@ -5317,7 +5317,7 @@ function _ValidateQuestion($questionSeq) break; case ':': //ARRAY (Multi Flexi) 1 to 10 case ';': //ARRAY (Multi Flexi) Text - if (preg_match('/^' . $sq['rowdivid'] . '/', $sgqa)) + if (preg_match('/^' . $sq['rowdivid'] . '_/', $sgqa)) { $foundSQrelevance=true; if (isset($LEM->ParseResultCache[$sq['eqn']])) From de642de7d31b4049ebfd570c62851a1a1779b8c8 Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Wed, 8 Aug 2012 08:39:12 +0000 Subject: [PATCH 66/75] Fixed issue: fix javascripts path using adminscript and generalscript in config setting --- application/controllers/AdminController.php | 2 +- application/controllers/admin/globalsettings.php | 4 ++-- application/controllers/admin/labels.php | 6 +++--- application/controllers/admin/question.php | 14 +++++++------- application/controllers/admin/saved.php | 4 ++-- application/controllers/admin/surveyadmin.php | 9 +++++---- application/controllers/admin/surveypermission.php | 8 ++++---- application/controllers/admin/templates.php | 2 +- application/controllers/admin/tokens.php | 6 +++--- application/controllers/admin/useraction.php | 12 ++++++------ application/controllers/admin/usergroups.php | 2 +- application/helpers/common_helper.php | 4 ++-- .../views/admin/templates/templatesummary_view.php | 14 +++++++------- 13 files changed, 44 insertions(+), 43 deletions(-) diff --git a/application/controllers/AdminController.php b/application/controllers/AdminController.php index 9680a2d98e9..e252e57432e 100644 --- a/application/controllers/AdminController.php +++ b/application/controllers/AdminController.php @@ -302,7 +302,7 @@ public function _getAdminHeader($meta = false, $return = false) $data['baseurl'] = Yii::app()->baseUrl . '/'; $data['datepickerlang']=""; if (Yii::app()->session["adminlang"] != 'en') - $data['datepickerlang'] = "\n"; + $data['datepickerlang'] = "\n"; $data['sitename'] = Yii::app()->getConfig("sitename"); $data['admintheme'] = Yii::app()->getConfig("admintheme"); diff --git a/application/controllers/admin/globalsettings.php b/application/controllers/admin/globalsettings.php index 618ba26d35f..fa9b3d5e90b 100644 --- a/application/controllers/admin/globalsettings.php +++ b/application/controllers/admin/globalsettings.php @@ -242,8 +242,8 @@ private function _checkSettings() */ protected function _renderWrappedTemplate($sAction = '', $aViewUrls = array(), $aData = array()) { - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . "/scripts/jquery/jquery.selectboxes.min.js"); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . "/scripts/admin/globalsettings.js"); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jquery.selectboxes.min.js"); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . "globalsettings.js"); parent::_renderWrappedTemplate($sAction, $aViewUrls, $aData); } diff --git a/application/controllers/admin/labels.php b/application/controllers/admin/labels.php index b4030e5aad8..66dc260dfb0 100644 --- a/application/controllers/admin/labels.php +++ b/application/controllers/admin/labels.php @@ -235,8 +235,8 @@ public function view($lid = 0) $aData = array(); // Includes some javascript files - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/labels.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/updateset.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'labels.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'updateset.js'); // Checks if user have the sufficient rights to manage the labels if (Yii::app()->session['USER_RIGHT_SUPERADMIN'] == 1 || Yii::app()->session['USER_RIGHT_MANAGE_LABEL'] == 1) @@ -361,7 +361,7 @@ public function process() */ public function exportmulti() { - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/labels.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'labels.js'); $this->_renderWrappedTemplate('labels', 'exportmulti_view'); } diff --git a/application/controllers/admin/question.php b/application/controllers/admin/question.php index da09d63fb42..ca7f48be2f6 100644 --- a/application/controllers/admin/question.php +++ b/application/controllers/admin/question.php @@ -256,11 +256,11 @@ public function answeroptions($surveyid, $gid, $qid) $surveyid = sanitize_int($surveyid); $qid = sanitize_int($qid); $gid = sanitize_int($gid); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl .'/scripts/jquery/jquery.dd.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl .'/scripts/admin/answers.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl .'/scripts/jquery/jquery.blockUI.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl .'/scripts/jquery/jquery.selectboxes.min.js'); - $this->getController()->_css_admin_includes(Yii::app()->baseUrl . '/scripts/jquery/dd.css'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.dd.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'answers.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.blockUI.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.selectboxes.min.js'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/dd.css'); $aData['display']['menu_bars']['surveysummary'] = 'viewgroup'; $aData['display']['menu_bars']['gid_action'] = 'addquestion'; @@ -1249,8 +1249,8 @@ function checkconditions(value, name, type, evt_type) */ protected function _renderWrappedTemplate($sAction = 'survey/Question', $aViewUrls = array(), $aData = array()) { - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/jquery/jquery.dd.js'); - $this->getController()->_css_admin_includes(Yii::app()->baseUrl . '/scripts/jquery/dd.css'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.dd.js'); + $this->getController()->_css_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/dd.css'); $this->getController()->_css_admin_includes(Yii::app()->getConfig('adminstyleurl')."superfish.css"); parent::_renderWrappedTemplate($sAction, $aViewUrls, $aData); } diff --git a/application/controllers/admin/saved.php b/application/controllers/admin/saved.php index 7ad6e802517..0ce79a67a77 100644 --- a/application/controllers/admin/saved.php +++ b/application/controllers/admin/saved.php @@ -35,8 +35,8 @@ public function view($iSurveyId) die(); } - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . 'scripts/jquery/jquery.tablesorter.min.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . 'scripts/admin/saved.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.tablesorter.min.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'saved.js'); $aThisSurvey = getSurveyInfo($iSurveyId); $aData['sSurveyName'] = $aThisSurvey['name']; diff --git a/application/controllers/admin/surveyadmin.php b/application/controllers/admin/surveyadmin.php index 82ea386e2c5..c77d02a3e99 100644 --- a/application/controllers/admin/surveyadmin.php +++ b/application/controllers/admin/surveyadmin.php @@ -51,7 +51,7 @@ public function index() $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/js/i18n/grid.locale-en.js"); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/js/jquery.jqGrid.min.js"); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jquery.coookie.js"); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . "/scripts/admin/listsurvey.js"); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . "listsurvey.js"); $this->getController()->_css_admin_includes(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.css'); $this->getController()->_css_admin_includes(Yii::app()->getConfig('publicstyleurl') . 'jquery.multiselect.filter.css'); $this->getController()->_css_admin_includes(Yii::app()->getConfig('adminstyleurl') . "displayParticipants.css"); @@ -757,7 +757,7 @@ public function editlocalsettings($iSurveyID) $aData['surveyid'] = $iSurveyID = sanitize_int($iSurveyID); $aViewUrls = array(); - $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts').'admin/surveysettings.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts').'surveysettings.js'); if (hasSurveyPermission($iSurveyID, 'surveylocale', 'read')) { @@ -1028,7 +1028,7 @@ private function _showReorderForm($iSurveyID) $aData['surveyid'] = $iSurveyID; $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.ui.nestedSortable.js'); - $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'admin/organize.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'organize.js'); $this->_renderWrappedTemplate('survey', 'organizeGroupsAndQuestions_view', $aData); } @@ -1428,10 +1428,11 @@ private function _registerScriptFiles($files = array()) if (empty($files)) { $generalscripts_path = Yii::app()->getConfig('generalscripts'); + $adminscripts_path = Yii::app()->getConfig('adminscripts'); $styleurl = Yii::app()->getConfig('styleurl'); $js_files = array( - $generalscripts_path . 'admin/surveysettings.js', + $adminscripts_path . 'surveysettings.js', $generalscripts_path . 'jquery/jqGrid/js/i18n/grid.locale-en.js', $generalscripts_path . 'jquery/jqGrid/js/jquery.jqGrid.min.js', $generalscripts_path . 'jquery/jquery.json.min.js', diff --git a/application/controllers/admin/surveypermission.php b/application/controllers/admin/surveypermission.php index d980255f2b7..676818791de 100644 --- a/application/controllers/admin/surveypermission.php +++ b/application/controllers/admin/surveypermission.php @@ -38,8 +38,8 @@ function index($surveyid) { $aBaseSurveyPermissions=Survey_permissions::model()->getBasePermissions(); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl.'/scripts/jquery/jquery.tablesorter.min.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl.'/scripts/admin/surveysecurity.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.tablesorter.min.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'surveysecurity.js'); $result2 = Survey_permissions::model()->getUserDetails($surveyid); @@ -374,8 +374,8 @@ function set($surveyid) { //$js_admin_includes[]='../scripts/jquery/jquery.tablesorter.min.js'; //$js_admin_includes[]='scripts/surveysecurity.js'; - $this->getController()->_js_admin_includes(Yii::app()->baseUrl.'/scripts/jquery/jquery.tablesorter.min.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl.'/scripts/admin/surveysecurity.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') .'jquery/jquery.tablesorter.min.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'surveysecurity.js'); if ($action == "setsurveysecurity") { $query = "select users_name from {{users}} where uid=:uid"; diff --git a/application/controllers/admin/templates.php b/application/controllers/admin/templates.php index c18f0014e51..6d674de5dd2 100644 --- a/application/controllers/admin/templates.php +++ b/application/controllers/admin/templates.php @@ -71,7 +71,7 @@ public function upload() { $clang = $this->getController()->lang; -// $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/templates.js'); +// $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'templates.js'); $aViewUrls = $this->_initialise('default', 'welcome', 'startpage.pstpl', FALSE); $lid = returnGlobal('lid'); diff --git a/application/controllers/admin/tokens.php b/application/controllers/admin/tokens.php index 94ebd76230c..0d53112acb4 100644 --- a/application/controllers/admin/tokens.php +++ b/application/controllers/admin/tokens.php @@ -263,8 +263,8 @@ function browse($iSurveyId, $limit = 50, $start = 0, $order = false, $searchstri self::_newtokentable($iSurveyId); } // Javascript - $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "admin/tokens.js"); - $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "admin/tokentocpdb.js"); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . "tokens.js"); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . "tokentocpdb.js"); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jquery.multiselect.min.js"); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/js/i18n/grid.locale-en.js"); $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . "jquery/jqGrid/js/jquery.jqGrid.min.js"); @@ -1798,7 +1798,7 @@ function import($iSurveyId) die('access denied'); } - $this->getController()->_js_admin_includes('scripts/tokens.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'tokens.js'); $aEncodings = array( "armscii8" => $clang->gT("ARMSCII-8 Armenian") diff --git a/application/controllers/admin/useraction.php b/application/controllers/admin/useraction.php index eb25741ba71..53886718459 100644 --- a/application/controllers/admin/useraction.php +++ b/application/controllers/admin/useraction.php @@ -37,8 +37,8 @@ function __construct($controller, $id) */ public function index() { - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/jquery/jquery.tablesorter.min.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/users.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.tablesorter.min.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts').'users.js'); $userlist = getUserList(); $usrhimself = $userlist[0]; @@ -393,8 +393,8 @@ function moduser() function setUserRights() { - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/jquery/jquery.tablesorter.min.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/users.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.tablesorter.min.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'users.js'); $postuser = Yii::app()->request->getPost('user'); $postemail = Yii::app()->request->getPost('email'); $postuserid = Yii::app()->request->getPost('uid'); @@ -510,8 +510,8 @@ function userrights() function setusertemplates() { - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/jquery/jquery.tablesorter.min.js'); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . '/scripts/admin/users.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.tablesorter.min.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts') . 'users.js'); $aData['postuser'] = Yii::app()->request->getPost("user"); $aData['postemail'] = Yii::app()->request->getPost("email"); $postuserid = Yii::app()->request->getPost("uid"); diff --git a/application/controllers/admin/usergroups.php b/application/controllers/admin/usergroups.php index 9d5bd33e7d0..59bd2e3a685 100644 --- a/application/controllers/admin/usergroups.php +++ b/application/controllers/admin/usergroups.php @@ -420,7 +420,7 @@ function user($ugid, $action = 'add') protected function _renderWrappedTemplate($sAction = 'usergroup', $aViewUrls = array(), $aData = array()) { $this->getController()->_css_admin_includes(Yii::app()->getConfig('adminstyleurl')."superfish.css"); - $this->getController()->_js_admin_includes(Yii::app()->baseUrl . 'scripts/admin/users.js'); + $this->getController()->_js_admin_includes(Yii::app()->getConfig('adminscripts').'users.js'); $aData['display']['menu_bars']['user_group'] = true; diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index aa2dfcf8bd0..2e3b6afe3fb 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -7325,8 +7325,8 @@ function getPrintableHeader() global $rooturl,$homeurl; $headelements = ' - - + + '; return $headelements; } diff --git a/application/views/admin/templates/templatesummary_view.php b/application/views/admin/templates/templatesummary_view.php index 2d62c595ed2..ade058a13a9 100644 --- a/application/views/admin/templates/templatesummary_view.php +++ b/application/views/admin/templates/templatesummary_view.php @@ -1,15 +1,15 @@ - + - - - + + + - - + + @@ -44,7 +44,7 @@ } ?>

    From 04ddf7d5b7e109c0592da668877b7969536ea64e Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Wed, 8 Aug 2012 11:32:55 +0200 Subject: [PATCH 67/75] Fixed issue #6445: No existing answer option imput field to start with when editing answer options --- application/controllers/admin/question.php | 493 +++++++++++---------- styles/gringegreen/jquery-ui/jquery-ui.css | 4 +- 2 files changed, 248 insertions(+), 249 deletions(-) diff --git a/application/controllers/admin/question.php b/application/controllers/admin/question.php index ca7f48be2f6..81c42a57ef7 100644 --- a/application/controllers/admin/question.php +++ b/application/controllers/admin/question.php @@ -3,37 +3,37 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); /* - * LimeSurvey - * Copyright (C) 2007-2011 The LimeSurvey Project Team / Carsten Schmitz - * All rights reserved. - * License: GNU/GPL License v2 or later, see LICENSE.php - * LimeSurvey is free software. This version may have been modified pursuant - * to the GNU General Public License, and as distributed it includes or - * is derivative of works licensed under the GNU General Public License or - * other free or open source software licenses. - * See COPYRIGHT.php for copyright notices and details. - * - * $Id$ - */ - - /** - * question - * - * @package LimeSurvey - * @author - * @copyright 2011 - * @version $Id$ - * @access public - */ +* LimeSurvey +* Copyright (C) 2007-2011 The LimeSurvey Project Team / Carsten Schmitz +* All rights reserved. +* License: GNU/GPL License v2 or later, see LICENSE.php +* LimeSurvey is free software. This version may have been modified pursuant +* to the GNU General Public License, and as distributed it includes or +* is derivative of works licensed under the GNU General Public License or +* other free or open source software licenses. +* See COPYRIGHT.php for copyright notices and details. +* +* $Id$ +*/ + +/** +* question +* +* @package LimeSurvey +* @author +* @copyright 2011 +* @version $Id$ +* @access public +*/ class question extends Survey_Common_Action { /** - * Function responsible to import a question. - * - * @access public - * @return void - */ + * Function responsible to import a question. + * + * @access public + * @return void + */ public function import() { $action = returnGlobal('action'); @@ -98,14 +98,14 @@ public function import() } /** - * Load edit default values of a question screen - * - * @access public - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return void - */ + * Load edit default values of a question screen + * + * @access public + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return void + */ public function editdefaultvalues($surveyid, $gid, $qid) { $surveyid = sanitize_int($surveyid); @@ -121,9 +121,9 @@ public function editdefaultvalues($surveyid, $gid, $qid) array_unshift($questlangs, $baselang); $questionrow = Questions::model()->findByAttributes(array( - 'qid' => $qid, - 'gid' => $gid, - 'language' => $baselang + 'qid' => $qid, + 'gid' => $gid, + 'language' => $baselang ))->attributes; $qtproperties = getQuestionTypeList('', 'array'); @@ -141,10 +141,10 @@ public function editdefaultvalues($surveyid, $gid, $qid) $langopts[$language][$questionrow['type']][$scale_id] = array(); $defaultvalue = Defaultvalues::model()->findByAttributes(array( - 'specialtype' => '', - 'qid' => $qid, - 'scale_id' => $scale_id, - 'language' => $language + 'specialtype' => '', + 'qid' => $qid, + 'scale_id' => $scale_id, + 'language' => $language )); $defaultvalue = $defaultvalue != null ? $defaultvalue->defaultvalue : null; @@ -152,18 +152,18 @@ public function editdefaultvalues($surveyid, $gid, $qid) $langopts[$language][$questionrow['type']][$scale_id]['defaultvalue'] = $defaultvalue; $answerresult = Answers::model()->findAllByAttributes(array( - 'qid' => $qid, - 'language' => $language + 'qid' => $qid, + 'language' => $language ), array('order' => 'sortorder')); $langopts[$language][$questionrow['type']][$scale_id]['answers'] = $answerresult; if ($questionrow['other'] == 'Y') { $defaultvalue = Defaultvalues::model()->findByAttributes(array( - 'specialtype' => 'other', - 'qid' => $qid, - 'scale_id' => $scale_id, - 'language' => $language + 'specialtype' => 'other', + 'qid' => $qid, + 'scale_id' => $scale_id, + 'language' => $language )); $defaultvalue = $defaultvalue != null ? $defaultvalue->defaultvalue : null; @@ -174,18 +174,18 @@ public function editdefaultvalues($surveyid, $gid, $qid) // If there are subquestions and no answerscales if ($qtproperties[$questionrow['type']]['answerscales'] == 0 && - $qtproperties[$questionrow['type']]['subquestions'] > 0) + $qtproperties[$questionrow['type']]['subquestions'] > 0) { for ($scale_id = 0; $scale_id < $qtproperties[$questionrow['type']]['subquestions']; $scale_id++) { $langopts[$language][$questionrow['type']][$scale_id] = array(); $sqresult = Questions::model()->findAllByAttributes(array( - 'sid' => $surveyid, - 'gid' => $gid, - 'parent_qid' => $qid, - 'language' => $language, - 'scale_id' => 0 + 'sid' => $surveyid, + 'gid' => $gid, + 'parent_qid' => $qid, + 'language' => $language, + 'scale_id' => 0 ), array('order' => 'question_order')); $langopts[$language][$questionrow['type']][$scale_id]['sqresult'] = array(); @@ -197,10 +197,10 @@ public function editdefaultvalues($surveyid, $gid, $qid) foreach ($sqresult as $aSubquestion) { $defaultvalue = Defaultvalues::model()->findByAttributes(array( - 'specialtype' => '', - 'qid' => $qid, - 'scale_id' => $scale_id, - 'language' => $language + 'specialtype' => '', + 'qid' => $qid, + 'scale_id' => $scale_id, + 'language' => $language )); $defaultvalue = $defaultvalue != null ? $defaultvalue->defaultvalue : null; @@ -227,14 +227,14 @@ public function editdefaultvalues($surveyid, $gid, $qid) } $aData = array( - 'qid' => $qid, - 'surveyid' => $surveyid, - 'langopts' => $langopts, - 'questionrow' => $questionrow, - 'questlangs' => $questlangs, - 'gid' => $gid, - 'qtproperties' => $qtproperties, - 'baselang' => $baselang, + 'qid' => $qid, + 'surveyid' => $surveyid, + 'langopts' => $langopts, + 'questionrow' => $questionrow, + 'questlangs' => $questlangs, + 'gid' => $gid, + 'qtproperties' => $qtproperties, + 'baselang' => $baselang, ); $aData['display']['menu_bars']['surveysummary'] = 'editdefaultvalues'; $aData['display']['menu_bars']['qid_action'] = 'editdefaultvalues'; @@ -243,14 +243,14 @@ public function editdefaultvalues($surveyid, $gid, $qid) } /** - * Load complete editing of answer options screen. - * - * @access public - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return - */ + * Load complete editing of answer options screen. + * + * @access public + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return + */ public function answeroptions($surveyid, $gid, $qid) { $surveyid = sanitize_int($surveyid); @@ -278,14 +278,14 @@ public function answeroptions($surveyid, $gid, $qid) } /** - * Load editing of answer options specific screen only. - * - * @access public - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return void - */ + * Load editing of answer options specific screen only. + * + * @access public + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return void + */ public function _editansweroptions($surveyid, $gid, $qid) { Yii::app()->loadHelper('database'); @@ -313,15 +313,15 @@ public function _editansweroptions($surveyid, $gid, $qid) $ans->addCondition("qid=$qid")->addCondition("scale_id=$i")->addCondition("language='$baselang'"); $qresult = Answers::model()->count($ans); - if ((int)$qresult=0) - Answers::model()->insert(array( - 'qid' => $qid, - 'code' => 'A1', - 'answer' => $clang->gT('Some example answer option'), - 'language' => $baselang, - 'sortorder' => 0, - 'scale_id' => $i, - )); + if ((int)$qresult==0) + $oAnswer= new Answers; + $oAnswer->qid = $qid; + $oAnswer->code = 'A1'; + $oAnswer->answer = $clang->gT('Some example answer option'); + $oAnswer->language = $baselang; + $oAnswer->sortorder = 0; + $oAnswer->scale_id = $i; + $oAnswer->save(); } @@ -337,19 +337,20 @@ public function _editansweroptions($surveyid, $gid, $qid) // Means that no record for the language exists in the answers table if (empty($iAnswerCount)) foreach (Answers::model()->findAllByAttributes(array( - 'qid' => $qid, - 'scale_id' => $i, - 'language' => $baselang - )) as $answer) - Answers::model()->insert(array( - 'qid' => $answer->qid, - 'code' => $answer->code, - 'answer' => $answer->answer, - 'language' => $language, - 'sortorder' => $answer->sortorder, - 'scale_id' => $i, - 'assessment_value' => $answer->assessment_value, - )); + 'qid' => $qid, + 'scale_id' => $i, + 'language' => $baselang + )) as $answer) + + $oAnswer= new Answers; + $oAnswer->qid = $answer->qid; + $oAnswer->code = $answer->code; + $oAnswer->answer = $answer->answer; + $oAnswer->language = $language; + $oAnswer->sortorder = $answer->sortorder; + $oAnswer->scale_id = $i; + $oAnswer->assessment_value = $answer->assessment_value; + $oAnswer->save(); } } @@ -375,8 +376,8 @@ public function _editansweroptions($surveyid, $gid, $qid) Yii::app()->loadHelper('admin/htmleditor'); $row = Answers::model()->findByAttributes(array( - 'qid' => $qid, - 'language' => Survey::model()->findByPk($surveyid)->language + 'qid' => $qid, + 'language' => Survey::model()->findByPk($surveyid)->language ), array('order' => 'sortorder desc')); if (!is_null($row)) @@ -407,14 +408,14 @@ public function _editansweroptions($surveyid, $gid, $qid) } /** - * Load complete subquestions screen. - * - * @access public - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return void - */ + * Load complete subquestions screen. + * + * @access public + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return void + */ public function subquestions($surveyid, $gid, $qid) { $aData['surveyid'] = $surveyid = sanitize_int($surveyid); @@ -437,14 +438,14 @@ public function subquestions($surveyid, $gid, $qid) } /** - * Load only subquestion specific screen only. - * - * @access public - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return void - */ + * Load only subquestion specific screen only. + * + * @access public + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return void + */ public function _editsubquestion($surveyid, $gid, $qid) { $surveyid = sanitize_int($surveyid); @@ -466,30 +467,30 @@ public function _editsubquestion($surveyid, $gid, $qid) for ($iScale = 0; $iScale < $iScaleCount; $iScale++) { $subquestiondata = Questions::model()->findAllByAttributes(array( - 'parent_qid' => $qid, - 'language' => $baselang, - 'scale_id' => $iScale + 'parent_qid' => $qid, + 'language' => $baselang, + 'scale_id' => $iScale )); if (empty($subquestiondata)) { //Questions::model()->insert(); $data = array( - 'sid' => $surveyid, - 'gid' => $gid, - 'parent_qid' => $qid, - 'title' => 'SQ001', - 'question' => $clang->gT('Some example subquestion'), - 'question_order' => 1, - 'language' => $baselang, - 'scale_id' => $iScale, + 'sid' => $surveyid, + 'gid' => $gid, + 'parent_qid' => $qid, + 'title' => 'SQ001', + 'question' => $clang->gT('Some example subquestion'), + 'question_order' => 1, + 'language' => $baselang, + 'scale_id' => $iScale, ); Questions::model()->insertRecords($data); $subquestiondata = Questions::model()->findAllByAttributes(array( - 'parent_qid' => $qid, - 'language' => $baselang, - 'scale_id' => $iScale + 'parent_qid' => $qid, + 'language' => $baselang, + 'scale_id' => $iScale )); } @@ -499,14 +500,14 @@ public function _editsubquestion($surveyid, $gid, $qid) foreach ($subquestiondata as $row) { $qrow = Questions::model()->count(' - parent_qid = :qid AND - language = :language AND - qid = '.$row->qid.' AND - scale_id = :iScale', - array( - ':qid' => $qid, - ':language' => $language, - ':iScale' => $iScale + parent_qid = :qid AND + language = :language AND + qid = '.$row->qid.' AND + scale_id = :iScale', + array( + ':qid' => $qid, + ':language' => $language, + ':iScale' => $iScale )); // Means that no record for the language exists in the questions table @@ -527,15 +528,15 @@ public function _editsubquestion($surveyid, $gid, $qid) $question->save(); /** //activerecord is not not new bugfix! Questions::model()->insert(array( - 'qid' => $row->qid, - 'sid' => $surveyid, - 'gid' => $row->gid, - 'parent_qid' => $qid, - 'title' => $row->title, - 'question' => $row->question, - 'question_order' => $row->question_order, - 'language' => $language, - 'scale_id' => $iScale, + 'qid' => $row->qid, + 'sid' => $surveyid, + 'gid' => $row->gid, + 'parent_qid' => $qid, + 'title' => $row->title, + 'question' => $row->question, + 'question_order' => $row->question_order, + 'language' => $language, + 'scale_id' => $iScale, )); */ switchMSSQLIdentityInsert('questions', false); @@ -561,9 +562,9 @@ public function _editsubquestion($surveyid, $gid, $qid) { // Check if any nulls exist. If they do, redo the sortorders $cacount = Questions::model()->count(array( - 'parent_qid' => $qid, - 'question_order' => null, - 'language' => $baselang + 'parent_qid' => $qid, + 'question_order' => null, + 'language' => $baselang )); if ($cacount) @@ -574,8 +575,8 @@ public function _editsubquestion($surveyid, $gid, $qid) // Print Key Control JavaScript $result = Questions::model()->findAllBYAttributes(array( - 'parent_qid' => $qid, - 'language' => Survey::model()->findByPk($surveyid)->language + 'parent_qid' => $qid, + 'language' => Survey::model()->findByPk($surveyid)->language ), array('order' => 'question_order desc')); $aData['anscount'] = $anscount = count($result); @@ -584,9 +585,9 @@ public function _editsubquestion($surveyid, $gid, $qid) $maxsortorder = $row['question_order'] + 1; /** - * The following line decides if the assessment input fields are visible or not - * for some question types the assessment values is set in the label set instead of the answers - */ + * The following line decides if the assessment input fields are visible or not + * for some question types the assessment values is set in the label set instead of the answers + */ $qtypes = getQuestionTypeList('', 'array'); Yii::app()->loadHelper('surveytranslator'); @@ -625,15 +626,15 @@ public function _editsubquestion($surveyid, $gid, $qid) } /** - * Load edit/new question screen depending on $action. - * - * @access public - * @param string $action - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return void - */ + * Load edit/new question screen depending on $action. + * + * @access public + * @param string $action + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return void + */ public function index($sa, $surveyid, $gid, $qid=null) { $action = $sa; @@ -686,14 +687,14 @@ public function index($sa, $surveyid, $gid, $qid=null) { $esrow = $esrow->attributes; $basesettings = array( - 'question_order' => $esrow['question_order'], - 'other' => $esrow['other'], - 'mandatory' => $esrow['mandatory'], - 'type' => $esrow['type'], - 'title' => $esrow['title'], - 'preg' => $esrow['preg'], - 'question' => $esrow['question'], - 'help' => $esrow['help'] + 'question_order' => $esrow['question_order'], + 'other' => $esrow['other'], + 'mandatory' => $esrow['mandatory'], + 'type' => $esrow['type'], + 'title' => $esrow['title'], + 'preg' => $esrow['preg'], + 'question' => $esrow['question'], + 'help' => $esrow['help'] ); } } @@ -706,27 +707,27 @@ public function index($sa, $surveyid, $gid, $qid=null) if ($value != 99) { Questions::model()->insert(array( - 'qid' => $qid, - 'sid' => $surveyid, - 'gid' => $gid, - 'type' => $basesettings['type'], - 'title' => $basesettings['title'], - 'question' => $basesettings['question'], - 'preg' => $basesettings['preg'], - 'help' => $basesettings['help'], - 'other' => $basesettings['other'], - 'mandatory' => $basesettings['mandatory'], - 'question_order' => $basesettings['question_order'], - 'language' => $key, + 'qid' => $qid, + 'sid' => $surveyid, + 'gid' => $gid, + 'type' => $basesettings['type'], + 'title' => $basesettings['title'], + 'question' => $basesettings['question'], + 'preg' => $basesettings['preg'], + 'help' => $basesettings['help'], + 'other' => $basesettings['other'], + 'mandatory' => $basesettings['mandatory'], + 'question_order' => $basesettings['question_order'], + 'language' => $key, )); } } $eqresult = Questions::model()->with('groups')->together()->findByAttributes(array( - 'sid' => $surveyid, - 'gid' => $gid, - 'qid' => $qid, - 'language' => $baselang + 'sid' => $surveyid, + 'gid' => $gid, + 'qid' => $qid, + 'language' => $baselang )); } else @@ -828,15 +829,15 @@ public function index($sa, $surveyid, $gid, $qid=null) } /** - * Function responsible for deleting a question. - * - * @access public - * @param string $action - * @param int $surveyid - * @param int $gid - * @param int $qid - * @return void - */ + * Function responsible for deleting a question. + * + * @access public + * @param string $action + * @param int $surveyid + * @param int $gid + * @param int $qid + * @return void + */ public function delete($surveyid, $gid, $qid) { $clang = $this->getController()->lang; @@ -903,11 +904,11 @@ public function delete($surveyid, $gid, $qid) } /** - * This function prepares the data for the advanced question attributes view - * - * @access public - * @return void - */ + * This function prepares the data for the advanced question attributes view + * + * @access public + * @return void + */ public function ajaxquestionattributes() { $surveyid = (int) $_POST['sid']; @@ -950,11 +951,11 @@ public function ajaxquestionattributes() } /** - * This function prepares the data for label set details - * - * @access public - * @return void - */ + * This function prepares the data for label set details + * + * @access public + * @return void + */ public function ajaxlabelsetdetails() { $lid=returnglobal('lid'); @@ -991,11 +992,11 @@ public function ajaxlabelsetdetails() } /** - * This function prepares the data for labelset - * - * @access public - * @return void - */ + * This function prepares the data for labelset + * + * @access public + * @return void + */ public function ajaxlabelsetpicker() { $match=(int)returnglobal('match'); @@ -1013,14 +1014,14 @@ public function ajaxlabelsetpicker() } /** - * Load preview of a question screen. - * - * @access public - * @param int $surveyid - * @param int $qid - * @param string $lang - * @return void - */ + * Load preview of a question screen. + * + * @access public + * @param int $surveyid + * @param int $qid + * @param string $lang + * @return void + */ public function preview($surveyid, $qid, $lang = null) { $surveyid = sanitize_int($surveyid); @@ -1054,7 +1055,7 @@ public function preview($surveyid, $qid, $lang = null) if (isset($field['defaultvalue'])) $_SESSION['survey_'.$surveyid][$field['fieldname']] = $field['defaultvalue']; - $clang = new limesurvey_lang($language); + $clang = new limesurvey_lang($language); $thissurvey = getSurveyInfo($surveyid); @@ -1065,22 +1066,22 @@ public function preview($surveyid, $qid, $lang = null) $qrows = Questions::model()->findByAttributes(array('sid' => $surveyid, 'qid' => $qid, 'language' => $language))->getAttributes(); $ia = array( - 0 => $qid, - 1 => $surveyid . 'X' . $qrows['gid'] . 'X' . $qid, - 2 => $qrows['title'], - 3 => $qrows['question'], - 4 => $qrows['type'], - 5 => $qrows['gid'], - 6 => $qrows['mandatory'], - 7 => 'N', - 8 => 'N' + 0 => $qid, + 1 => $surveyid . 'X' . $qrows['gid'] . 'X' . $qid, + 2 => $qrows['title'], + 3 => $qrows['question'], + 4 => $qrows['type'], + 5 => $qrows['gid'], + 6 => $qrows['mandatory'], + 7 => 'N', + 8 => 'N' ); $radix=getRadixPointData($thissurvey['surveyls_numberformat']); $radix = $radix['seperator']; $surveyOptions = array( - 'radix'=>$radix, - ); + 'radix'=>$radix, + ); LimeExpressionManager::StartSurvey($surveyid, 'question', $surveyOptions, false, $LEMdebugLevel); $qseq = LimeExpressionManager::GetQuestionSeq($qid); $moveResult = LimeExpressionManager::JumpTo($qseq + 1, true, false, true); @@ -1179,7 +1180,7 @@ function checkconditions(value, name, type, evt_type) $answer = $answers[0][1]; -// $help = $answers[0][2]; + // $help = $answers[0][2]; $qinfo = LimeExpressionManager::GetQuestionStatus($qid); $help = $qinfo['info']['help']; @@ -1232,7 +1233,7 @@ function checkconditions(value, name, type, evt_type) echo LimeExpressionManager::GetDebugTimingMessage(); } if ($LEMdebugLevel >= 2) { - echo "

    eT("Token summary"); ?>eT("Token summary"); ?>
    eT("Total records in this token table"); ?>
    eT("Total invitations sent"); ?>
    eT("Question:"); ?>
    eT("Help:"); ?>
    $clang->gT("Database name"))); ?>
    -
    eT("If the database not exists it will be created (necessary permission provided). If there are existing LimeSurvey tables these will be upgraded automatically after installation"); ?>
    +
    eT("If the database does not yet exist it will be created (make sure your database user has the necessary permissions). In contrast, if there are existing LimeSurvey tables in that database they will be upgraded automatically after installation."); ?>
    'required')) ?>
    Group/Question Validation Results:".$moveResult['message']."
    \n"; + echo "
    Group/Question Validation Results:".$moveResult['message']."
    \n"; } echo "\n"; @@ -1241,12 +1242,12 @@ function checkconditions(value, name, type, evt_type) } /** - * Renders template(s) wrapped in header and footer - * - * @param string $sAction Current action, the folder to fetch views from - * @param string|array $aViewUrls View url(s) - * @param array $aData Data to be passed on. Optional. - */ + * Renders template(s) wrapped in header and footer + * + * @param string $sAction Current action, the folder to fetch views from + * @param string|array $aViewUrls View url(s) + * @param array $aData Data to be passed on. Optional. + */ protected function _renderWrappedTemplate($sAction = 'survey/Question', $aViewUrls = array(), $aData = array()) { $this->getController()->_js_admin_includes(Yii::app()->getConfig('generalscripts') . 'jquery/jquery.dd.js'); diff --git a/styles/gringegreen/jquery-ui/jquery-ui.css b/styles/gringegreen/jquery-ui/jquery-ui.css index 4466e537644..f3e069f7f99 100644 --- a/styles/gringegreen/jquery-ui/jquery-ui.css +++ b/styles/gringegreen/jquery-ui/jquery-ui.css @@ -147,15 +147,13 @@ } .ui-state-active,.ui-widget-content .ui-state-active { - /* background-color: #797979; */ - background-color: #DBEAF9; + background-color: #EFFBDB; font-weight: bold; color: #4e8632; outline: none; } .ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited { - color: #fff; outline: none; text-decoration: none; } From 780d8117e13210c15d9f711b2fe7396e67f844fc Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Wed, 8 Aug 2012 12:00:09 +0200 Subject: [PATCH 68/75] Fixed issue #6438: Statistics doesn't work with numerical question types --- application/helpers/admin/statistics_helper.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/application/helpers/admin/statistics_helper.php b/application/helpers/admin/statistics_helper.php index a636f762e7e..85c8fbf41a0 100644 --- a/application/helpers/admin/statistics_helper.php +++ b/application/helpers/admin/statistics_helper.php @@ -865,14 +865,13 @@ function buildOutputList($rt, $language, $surveyid, $outputType, $sql) { } //loop through results - foreach ($nresult->readAll() as $nrow) + foreach ($nresult as $nrow) { - $nrow=array_values($nrow); - $qtitle=flattenText($nrow[0]); //clean up title - $qtype=$nrow[1]; - $qquestion=flattenText($nrow[2]); - $qiqid=$nrow[3]; - $qlid=$nrow[4]; + $qtitle=flattenText($nrow->title); //clean up title + $qtype=$nrow->type; + $qquestion=flattenText($nrow->question); + $qiqid=$nrow->qid; + $qlid=$nrow->parent_qid; } //Get answer texts for multiple numerical @@ -3265,7 +3264,7 @@ function generate_statistics($surveyid, $allfields, $q2show='all', $usegraph=0, // Inform the module that our data will arrive as UTF-8. // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) $workbook->setTempDir($tempdir); - + // Inform the module that our data will arrive as UTF-8. // Set the temporary directory to avoid PHP error messages due to open_basedir restrictions and calls to tempnam("", ...) if (!empty($tempdir)) { From ba64ed435255fc9754082bbf5959fa168ee2bbe4 Mon Sep 17 00:00:00 2001 From: Carsten Schmitz Date: Wed, 8 Aug 2012 12:32:54 +0200 Subject: [PATCH 69/75] Fixed issue #6448: Error when saving global settings on MSSQL --- application/views/admin/globalSettings_view.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/application/views/admin/globalSettings_view.php b/application/views/admin/globalSettings_view.php index aa152e4ca28..f40cfa32256 100644 --- a/application/views/admin/globalSettings_view.php +++ b/application/views/admin/globalSettings_view.php @@ -223,7 +223,7 @@
  • -