View Issue Details

IDProjectCategoryView StatusLast Update
17281Bug reportsRemoteControlpublic2021-06-09 13:56
Reporterpuitsc Assigned Toollehar  
PrioritynormalSeveritypartial_block 
Status feedbackResolutionopen 
Product Version4.5.x 
Summary17281: set_question_properties fails with error "table ls_questions does not have a column named 'language'"
DescriptionWhen updating a question or help text using remote control, I get the error message "table ls_questions does not have a column named 'language'".
Steps To ReproduceCalling set_question_properties($sSessionKey, $iQuestionID, $aQuestionData, $sLanguage = null) with

valid sSessionKey and iQuestionID and

$aQuestionData['title'] = 'Updated Question';
$sLanguage = 'de';

Additional Informationset_group_properties processes $aGroupData['questiongroupl10ns'][$language] whereas set_question_properties seems to be not yet updated to the new L10N structure.
TagsNo tags attached.
Complete LimeSurvey version number (& build)4.5.2+210426
I will donate to the project if issue is resolvedNo
Browser
Database & DB-VersionMaria DB 10.3.27
Server OS (if known)
Webserver software & version (if known)
PHP Version7.2.24

Activities

ollehar

ollehar

2021-05-04 17:25

administrator   ~64226

@gabrieljenik You want to fix this one?
puitsc

puitsc

2021-05-04 17:54

reporter   ~64232

@ollehar @gabrieljenik - I gave it a try and used the set_group_properties function - please feel free to use the code

I wasn't sure how to handle the $sLanguage paramenter though.
set_question_properties.txt (7,432 bytes)   
    public function set_question_properties($sSessionKey, $iQuestionID, $aQuestionData, $sLanguage = null)
    {
        if ($this->_checkSessionKey($sSessionKey)) {
            Yii::app()->loadHelper("surveytranslator");
            $iQuestionID = (int) $iQuestionID;
            //$oQuestion = Question::model()->findByAttributes(array('qid' => $iQuestionID));
            $oQuestion = Question::model()->with('questionl10ns')->findByAttributes(array('qid' => $iQuestionID));
            if (is_null($oQuestion)) {
                            return array('status' => 'Error: Invalid question ID');
            }

            $iSurveyID = $oQuestion->sid;

            if (Permission::model()->hasSurveyPermission($iSurveyID, 'survey', 'update')) {
                $aResult = array();
                // Remove fields that may not be modified
                unset($aQuestionData['qid']);
                unset($aQuestionData['gid']);
                unset($aQuestionData['sid']);
                unset($aQuestionData['parent_qid']);
                unset($aQuestionData['type']);

                // Backwards compatibility for sLanguage parameter
                if (is_null($sLanguage)) {
                    $sLanguage = Survey::model()->findByPk($iSurveyID)->language;
                }
                if (!array_key_exists($sLanguage, getLanguageDataRestricted())) {
                    return array('status' => 'Error: Invalid language');
                }

                // Backwards compatibility for L10n data
                if (!empty($aQuestionData['language'])) {
                    $language = $aQuestionData['language'];
                    $aQuestionData['questionl10ns'][$language] = array(
                        'language' => $language,
                        'question' => !empty($aQuestionData['question']) ? $aQuestionData['question'] : '',
                        'help' => !empty($aQuestionData['help']) ? $aQuestionData['help'] : '',
                        'script' => !empty($aQuestionData['script']) ? $aQuestionData['script'] : '',
                    );
                }

                // Process L10n data
                if (!empty($aQuestionData['questionl10ns']) && is_array($aQuestionData['questionl10ns'])) {
                    $aL10nDestinationFields = array_flip(QuestionL10n::model()->tableSchema->columnNames);
                    foreach ($aQuestionData['questionl10ns'] as $language => $aLanguageData) {
                        // Get existing L10n data or create new
                        if (isset($oQuestion->questionl10ns[$language])) {
                            $oQuestionL10n = $oQuestion->questionl10ns[$language];
                        } else {
                            $oQuestionL10n = new QuestionL10n();
                            $oQuestionL10n->gid = $iGroupID;
                            $oQuestionL10n->setAttribute('language', $language);
                            $oQuestionL10n->setAttribute('question', '');
                            $oQuestionL10n->setAttribute('help', '');
                            $oQuestionL10n->setAttribute('script', '');
                            if (!$oQuestionL10n->save()) {
                                $aResult['questionl10ns'][$language] = false;
                                continue;
                            }
                        }

                        // Remove invalid fields
                        $aQuestionL10nData = array_intersect_key($aLanguageData, $aL10nDestinationFields);
                        if (empty($aQuestionL10nData)) {
                            $aResult['questionl10ns'][$language] = 'Empty question L10n data';
                            continue;
                        }

                        $aQuestionL10nAttributes = $oQuestionL10n->getAttributes();
                        foreach ($aQuestionL10nData as $sFieldName => $sValue) {
                            $oQuestionL10n->setAttribute($sFieldName, $sValue);
                            try {
                                // save the change to database - one by one to allow for validation to work
                                $bSaveResult = $oQuestionL10n->save();
                                $aResult['questionl10ns'][$language][$sFieldName] = $bSaveResult;
                                //unset failed values
                                if (!$bSaveResult) {
                                    $oQuestionL10n->$sFieldName = $aL10nAttributes[$sFieldName];
                                }
                            } catch (Exception $e) {
                                //unset values that cause exception
                                $oQuestionL10n->$sFieldName = $aL10nAttributes[$sFieldName];
                            }
                        }
                    }
                }

                // Remove invalid fields
                $aDestinationFields = array_flip(Question::model()->tableSchema->columnNames);
                $aQuestionData = array_intersect_key($aQuestionData, $aDestinationFields);
                $aQuestionAttributes = $oQuestion->getAttributes();
                if (empty($aQuestionData)) {
                    if (empty($aResult)) {
                        return array('status' => 'No valid Data');
                    } else {
                        return $aResult;
                    }
                }

                //all the dependencies that this question has to other questions
                $has_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");


                foreach ($aQuestionData as $sFieldName => $sValue) {
                    //We do not allow questions with dependencies in the same group to change order - that would lead to broken dependencies
                    if ((isset($has_dependencies) || isset($is_criteria_question)) && $sFieldName == 'question_order') {
                        $aResult[$sFieldName] = 'Questions with dependencies - Order cannot be changed';
                        continue;
                    }
                    $oQuestion->setAttribute($sFieldName, $sValue);

                    try {
                        $bSaveResult = $oQuestion->save(); // save the change to database
                        Question::model()->updateQuestionOrder($oQuestion->gid);
                        $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');
            }
        } else {
            return array('status' => 'Invalid Session key');
        }
    }

set_question_properties.txt (7,432 bytes)   
floms

floms

2021-06-07 18:31

reporter   ~64772

push
ollehar

ollehar

2021-06-09 13:55

administrator   ~64799

@puitsc Can you make a PR for this, perhaps?

Issue History

Date Modified Username Field Change
2021-05-03 14:02 puitsc New Issue
2021-05-04 17:24 ollehar Priority none => normal
2021-05-04 17:25 ollehar Note Added: 64226
2021-05-04 17:54 puitsc Note Added: 64232
2021-05-04 17:54 puitsc File Added: set_question_properties.txt
2021-06-07 18:31 floms Note Added: 64772
2021-06-09 13:55 ollehar Note Added: 64799
2021-06-09 13:56 ollehar Assigned To => ollehar
2021-06-09 13:56 ollehar Status new => feedback