From e979de0a333c1f841ed7f966d1a9f3ef80f0a295 Mon Sep 17 00:00:00 2001 From: Gabriel Jenik Date: Fri, 5 May 2023 12:51:27 -0300 Subject: [PATCH] Fixed issue #18612: When surveys are copied without copying resources links are not handled (#3009) * Fixed issue #18612: When surveys are copied without copying resources, links are not handled * Fixed issue #18612: When surveys are copied without copying resources links are not handled Unit tests for checkOldLinks function added. --------- Co-authored-by: lapiudevgit --- application/helpers/admin/import_helper.php | 147 +++++++++++++++++++- application/helpers/common_helper.php | 26 ++++ tests/unit/helpers/CheckOldLinksTest.php | 60 ++++++++ 3 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 tests/unit/helpers/CheckOldLinksTest.php diff --git a/application/helpers/admin/import_helper.php b/application/helpers/admin/import_helper.php index 3b245d629f3..2b75fee8001 100644 --- a/application/helpers/admin/import_helper.php +++ b/application/helpers/admin/import_helper.php @@ -118,6 +118,7 @@ function XMLImportGroup($sFullFilePath, $iNewSID, $bTranslateLinksFields) } unset($insertdata['id']); // now translate any links + // TODO: Should this depend on $bTranslateLinksFields? $insertdata['group_name'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['group_name']); $insertdata['description'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['description']); if (isset($aGIDReplacements[$insertdata['gid']])) { @@ -213,6 +214,17 @@ function XMLImportGroup($sFullFilePath, $iNewSID, $bTranslateLinksFields) $importedQuestions[$aQIDReplacements[$iOldQID]] = $oQuestion; } + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a question_l10ns section. + if (!$bTranslateLinksFields && !isset($xml->question_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->question)) { + $results['importwarnings'][] = sprintf(gT("Question %s has outdated links."), $oQuestion->title); + } + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->help)) { + $results['importwarnings'][] = sprintf(gT("Help text for question %s has outdated links."), $oQuestion->title); + } + } + if (isset($oQuestionL10n)) { $oQuestionL10n->qid = $aQIDReplacements[$iOldQID]; $oQuestionL10n->save(); @@ -312,6 +324,15 @@ function XMLImportGroup($sFullFilePath, $iNewSID, $bTranslateLinksFields) $results['questions']++; } + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a question_l10ns section. + if (!$bTranslateLinksFields && !isset($xml->question_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->question)) { + $parentQuestion = $importedQuestions[$insertdata['parent_qid']]; + $results['importwarnings'][] = sprintf(gT("Subquestion %s of question %s has outdated links."), $oQuestion->title, $parentQuestion->title); + } + } + if (isset($oQuestionL10n)) { $oQuestionL10n->qid = $aQIDReplacements[$iOldQID]; $oQuestionL10n->save(); @@ -338,6 +359,7 @@ function XMLImportGroup($sFullFilePath, $iNewSID, $bTranslateLinksFields) } unset($insertdata['id']); // now translate any links + // TODO: Should this depend on $bTranslateLinksFields? $insertdata['question'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']); $insertdata['help'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']); if (isset($aQIDReplacements[$insertdata['qid']])) { @@ -639,6 +661,7 @@ function XMLImportQuestion($sFullFilePath, $iNewSID, $iNewGID, $options = array( // now translate any links if (!isset($xml->question_l10ns->rows->row)) { + // TODO: Should this depend on $options['translinkfields']? $insertdata['question'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']); $insertdata['help'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']); $oQuestionL10n = new QuestionL10n(); @@ -797,6 +820,14 @@ function XMLImportQuestion($sFullFilePath, $iNewSID, $iNewGID, $options = array( $results['questions']++; } + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a question_l10ns section. + if (!$options['translinkfields'] && !isset($xml->question_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->question)) { + $results['importwarnings'][] = sprintf(gT("Subquestion %s has outdated links."), $oQuestion->title); + } + } + if (isset($oQuestionL10n)) { $oQuestionL10n->qid = $aQIDReplacements[$iOldQID]; $oQuestionL10n->save(); @@ -822,6 +853,7 @@ function XMLImportQuestion($sFullFilePath, $iNewSID, $iNewGID, $options = array( } unset($insertdata['id']); // now translate any links + // TODO: Should this depend on $options['translinkfields']? $insertdata['question'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['question']); $insertdata['help'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['help']); if (isset($aQIDReplacements[$insertdata['qid']])) { @@ -873,6 +905,15 @@ function XMLImportQuestion($sFullFilePath, $iNewSID, $iNewGID, $options = array( if ($oAnswer->save() && isset($xml->answer_l10ns->rows->row)) { $aAIDReplacements[$iOldAID] = $oAnswer->aid; } + + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a answer_l10ns section. + if (!$options['translinkfields'] && !isset($xml->answer_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oAnswerL10n->answer)) { + $results['importwarnings'][] = sprintf(gT("Answer option %s has outdated links."), $insertdata['code']); + } + } + $results['answers']++; if (isset($oAnswerL10n)) { $oAnswer = Answer::model()->findByAttributes( @@ -909,6 +950,13 @@ function XMLImportQuestion($sFullFilePath, $iNewSID, $iNewGID, $options = array( $oAnswerL10n = new AnswerL10n(); $oAnswerL10n->setAttributes($insertdata, false); $oAnswerL10n->save(); + + // If translate links is disabled, check for old links. + if (!$options['translinkfields']) { + if (checkOldLinks('survey', $iOldSID, $oAnswerL10n->answer)) { + $results['importwarnings'][] = sprintf(gT("Answer option %s has outdated links."), $insertdata['code']); + } + } } } @@ -1408,6 +1456,31 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul if (isset($insertdata['surveyls_email_confirm'])) { $insertdata['surveyls_email_confirm'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['surveyls_email_confirm']); } + } else { + if (checkOldLinks('survey', $iOldSID, $insertdata['surveyls_title'])) { + $results['importwarnings'][] = gT("Survey title has outdated links."); + } + if (isset($insertdata['surveyls_description']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_description'])) { + $results['importwarnings'][] = gT("Survey description has outdated links."); + } + if (isset($insertdata['surveyls_welcometext']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_welcometext'])) { + $results['importwarnings'][] = gT("Welcome text has outdated links."); + } + if (isset($insertdata['surveyls_urldescription']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_urldescription'])) { + $results['importwarnings'][] = gT("URL description has outdated links."); + } + if (isset($insertdata['surveyls_email_invite']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_email_invite'])) { + $results['importwarnings'][] = gT("Invitation email template has outdated links."); + } + if (isset($insertdata['surveyls_email_remind']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_email_remind'])) { + $results['importwarnings'][] = gT("Reminder email template has outdated links."); + } + if (isset($insertdata['surveyls_email_register']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_email_register'])) { + $results['importwarnings'][] = gT("Registration email template has outdated links."); + } + if (isset($insertdata['surveyls_email_confirm']) && checkOldLinks('survey', $iOldSID, $insertdata['surveyls_email_confirm'])) { + $results['importwarnings'][] = gT("Confirmation email template has outdated links."); + } } if (isset($insertdata['surveyls_attributecaptions']) && substr((string) $insertdata['surveyls_attributecaptions'], 0, 1) != '{') { @@ -1459,6 +1532,13 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul if ($bTranslateInsertansTags) { $insertdata['group_name'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['group_name']); $insertdata['description'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['description']); + } else { + if (checkOldLinks('survey', $iOldSID, $insertdata['group_name'])) { + $results['importwarnings'][] = gT("Group name has outdated links."); + } + if (checkOldLinks('survey', $iOldSID, $insertdata['description'])) { + $results['importwarnings'][] = gT("Group description has outdated links."); + } } $aDataL10n['group_name'] = $insertdata['group_name']; $aDataL10n['description'] = $insertdata['description']; @@ -1502,6 +1582,7 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul continue; //Skip invalid group ID } // now translate any links + // TODO: Should this depend on $bTranslateLinksFields? $insertdata['group_name'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['group_name']); if (isset($insertdata['description'])) { $insertdata['description'] = translateLinks('survey', $iOldSID, $iNewSID, $insertdata['description']); @@ -1609,6 +1690,17 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul $importedQuestions[$aQIDReplacements[$iOldQID]] = $oQuestion; } + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a question_l10ns section. + if (!$bTranslateInsertansTags && !isset($xml->question_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->question)) { + $results['importwarnings'][] = sprintf(gT("Question %s has outdated links."), $oQuestion->title); + } + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->help)) { + $results['importwarnings'][] = sprintf(gT("Help text for question %s has outdated links."), $oQuestion->title); + } + } + if (isset($oQuestionL10n)) { $oQuestionL10n->qid = $aQIDReplacements[$iOldQID]; $oQuestionL10n->save(); @@ -1628,6 +1720,8 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul } // Import subquestions ------------------------------------------------------- + /** @var Question[] */ + $importedSubQuestions = []; if (isset($xml->subquestions)) { foreach ($xml->subquestions->rows->row as $row) { $insertdata = array(); @@ -1711,8 +1805,17 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul throw new Exception(gT("Error while saving: ") . print_r($oQuestion->errors, true)); } $aQIDReplacements[$iOldQID] = $oQuestion->qid; - ; $results['subquestions']++; + $importedSubQuestions[$aQIDReplacements[$iOldQID]] = $oQuestion; + } + + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a question_l10ns section. + if (!$bTranslateInsertansTags && !isset($xml->question_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->question)) { + $parentQuestion = $importedQuestions[$insertdata['parent_qid']]; + $results['importwarnings'][] = sprintf(gT("Subquestion %s of question %s has outdated links."), $oQuestion->title, $parentQuestion->title); + } } if (isset($oQuestionL10n)) { @@ -1755,6 +1858,30 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul $oQuestionL10n = new QuestionL10n(); $oQuestionL10n->setAttributes($insertdata, false); $oQuestionL10n->save(); + + // If translate links is disabled, check for old links. + if (!$bTranslateInsertansTags) { + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->question)) { + // The question_l10ns includes L10n data for both questions and subquestions. + // If it's a normal question, it should be in $importedQuestions. + if (isset($importedQuestions[$insertdata['qid']])) { + $question = $importedQuestions[$insertdata['qid']]; + $results['importwarnings'][] = sprintf(gT("Question %s has outdated links."), $question->title); + } elseif (isset($importedSubQuestions[$insertdata['qid']])) { + $subquestion = $importedSubQuestions[$insertdata['qid']]; + $parentQuestion = $importedQuestions[$subquestion->parent_qid]; + $results['importwarnings'][] = sprintf(gT("Subquestion %s of question %s has outdated links."), $subquestion->title, $parentQuestion->title); + } + } + if (checkOldLinks('survey', $iOldSID, $oQuestionL10n->help)) { + // If it's a normal question, it should be in $importedQuestions. Subquestions are not + // supposed to have a help text. + if (isset($importedQuestions[$insertdata['qid']])) { + $question = $importedQuestions[$insertdata['qid']]; + $results['importwarnings'][] = sprintf(gT("Help text for question %s has outdated links."), $question->title); + } + } + } } } @@ -1796,6 +1923,16 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul if ($oAnswer->save() && isset($xml->answer_l10ns->rows->row) && isset($iOldAID)) { $aAIDReplacements[$iOldAID] = $oAnswer->aid; } + + // If translate links is disabled, check for old links. + // We only do it here if the XML doesn't have a answer_l10ns section. + if (!$bTranslateInsertansTags && !isset($xml->answer_l10ns->rows->row)) { + if (checkOldLinks('survey', $iOldSID, $oAnswerL10n->answer)) { + $question = $importedQuestions[$insertdata['qid']]; + $results['importwarnings'][] = sprintf(gT("Answer option %s of question %s has outdated links."), $insertdata['code'], $question->title); + } + } + $results['answers']++; if (isset($oAnswerL10n)) { $oAnswer = Answer::model()->findByAttributes(['qid' => $insertdata['qid'], 'code' => $insertdata['code'], 'scale_id' => $insertdata['scale_id']]); @@ -1826,6 +1963,14 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul $oAnswerL10n = new AnswerL10n(); $oAnswerL10n->setAttributes($insertdata, false); $oAnswerL10n->save(); + + // If translate links is disabled, check for old links. + if (!$bTranslateInsertansTags) { + if (checkOldLinks('survey', $iOldSID, $oAnswerL10n->answer)) { + $question = $importedQuestions[$insertdata['qid']]; + $results['importwarnings'][] = sprintf(gT("Answer option %s of question %s has outdated links."), $insertdata['code'], $question->title); + } + } } } diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 858b1519938..3b0e1336aa0 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -2646,6 +2646,32 @@ function translateLinks($sType, $iOldSurveyID, $iNewSurveyID, string $sString) } } +/** + * Returns true if there are old links in answer/question/survey/email template/label set texts. + * + * @param string $type 'survey' or 'label' + * @param mixed $oldSurveyId + * @param mixed $string + * @return boolean True if the provided string includes links to the old survey. If the type is not 'survey' or 'label', it returns false. + */ +function checkOldLinks($type, $oldSurveyId, $string) +{ + if (empty($string)) { + return false; + } + $oldSurveyId = (int) $oldSurveyId; + if ($type == 'survey') { + $pattern = '(http(s)?:\/\/)?(([a-z0-9\/\.])*(?=(\/upload))\/upload\/surveys\/' . $oldSurveyId . '\/)'; + return preg_match('/' . $pattern . '/u', $string, $m); + } elseif ($type == 'label') { + $pattern = '(http(s)?:\/\/)?(([a-z0-9\/\.])*(?=(\/upload))\/upload\/labels\/' . $oldSurveyId . '\/)'; + return preg_match('/' . $pattern . '/u', $string, $m); + } else // unknown type + { + return false; + } +} + /** * This function creates the old fieldnames for survey import * diff --git a/tests/unit/helpers/CheckOldLinksTest.php b/tests/unit/helpers/CheckOldLinksTest.php new file mode 100644 index 00000000000..39791dfee53 --- /dev/null +++ b/tests/unit/helpers/CheckOldLinksTest.php @@ -0,0 +1,60 @@ +assertFalse($oldLinks, 'The link should be empty.'); + } + + public function testUnknownType() + { + $oldLinks = checkOldLinks('encuesta', '111111', ''); + $this->assertFalse($oldLinks, 'Link type is not survey or label.'); + } + + public function testNoSurveyOldLinks() + { + $newLink = 'http://' . getenv('DOMAIN') . '/upload/surveys/222222/'; + $oldLinks = checkOldLinks('survey', '111111', $newLink); + + $this->assertFalse((bool)$oldLinks, 'The url ' . $newLink . ' is an old link.'); + } + + public function testSurveyOldLinks() + { + $newLink = 'http://' . getenv('DOMAIN') . '/upload/surveys/2222/'; + $oldLinks = checkOldLinks('survey', '2222', $newLink); + + $this->assertTrue((bool)$oldLinks, 'The url ' . $newLink . ' is not an old link.'); + } + + public function testNoLabelOldLinks() + { + $newLink = 'http://' . getenv('DOMAIN') . '/upload/labels/222222/'; + $oldLinks = checkOldLinks('label', '111111', $newLink); + + $this->assertFalse((bool)$oldLinks, 'The url ' . $newLink . ' is an old link.'); + } + + public function testLabelOldLinks() + { + $newLink = 'http://' . getenv('DOMAIN') . '/upload/labels/2222/'; + $oldLinks = checkOldLinks('label', '2222', $newLink); + + $this->assertTrue((bool)$oldLinks, 'The url ' . $newLink . ' is not an old link.'); + } +}