Skip to content

Commit

Permalink
Fixed issue #18602: When surveys are copied without copying attachmen…
Browse files Browse the repository at this point in the history
…ts, attachment info is copied but not updated (#3430)
  • Loading branch information
gabrieljenik committed Sep 13, 2023
1 parent 14e4d01 commit b938b37
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 12 deletions.
31 changes: 31 additions & 0 deletions application/controllers/admin/EmailTemplates.php
Expand Up @@ -70,6 +70,11 @@ public function index($iSurveyId)
if (is_array($attachments)) {
foreach ($attachments as &$template) {
foreach ($template as &$attachment) {
// If the file is missing we add an error message
if (!$this->attachmentExists($iSurveyId, $attachment)) {
$attachment['error'] = gT("File not found.");
}
// For security reasons we don't include the full upload path in the frontend
if (substr((string) $attachment['url'], 0, strlen($uploadDir)) == $uploadDir) {
$attachment['url'] = str_replace('\\', '/', substr((string) $attachment['url'], strlen($uploadDir)));
}
Expand Down Expand Up @@ -322,4 +327,30 @@ protected function renderWrappedTemplate($sAction = 'emailtemplates', $aViewUrls
$aData['display']['menu_bars']['surveysummary'] = 'editemailtemplates';
parent::renderWrappedTemplate($sAction, $aViewUrls, $aData, $sRenderFile);
}

/**
* Checks that the specified attachment exists on one of the allowed paths.
* @param array<string,mixed> The attachment data
* @return bool True if the file exists within the survey or global upload dirs.
*/
private function attachmentExists($surveyId, $attachment)
{
$isInSurvey = Yii::app()->is_file(
$attachment['url'],
Yii::app()->getConfig('uploaddir') . DIRECTORY_SEPARATOR . "surveys" . DIRECTORY_SEPARATOR . $surveyId,
false
);

$isInGlobal = Yii::app()->is_file(
$attachment['url'],
Yii::app()->getConfig('uploaddir') . DIRECTORY_SEPARATOR . "global",
false
);

if ($isInSurvey || $isInGlobal) {
return true;
}

return false;
}
}
10 changes: 10 additions & 0 deletions application/helpers/admin/import_helper.php
Expand Up @@ -1324,6 +1324,8 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul
$results['theme_options_differences'] = array();
$sTemplateName = '';

/** @var bool Indicates if the email templates have attachments with untranslated URLs or not */
$hasOldAttachments = false;

$aLanguagesSupported = array();
foreach ($xml->languages->language as $language) {
Expand Down Expand Up @@ -1504,6 +1506,10 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul
$attachment['url'] = translateLinks('survey', $iOldSID, $iNewSID, $attachment['url'], true);
}
}
// If links are not translated and the email templates have attachments, we need to show a warning
if (!$bTranslateInsertansTags && !empty($template)) {
$hasOldAttachments = true;
}
}
} elseif (is_null($attachments)) {
// JSON decode failed. Most probably the attachments were in the PHP serialization format.
Expand Down Expand Up @@ -1544,6 +1550,10 @@ function XMLImportSurvey($sFullFilePath, $sXMLdata = null, $sNewSurveyName = nul
$results['importwarnings'][] = gT("The email attachments have not been imported because they were in an old format.");
}

if ($hasOldAttachments) {
$results['importwarnings'][] = gT("Email templates have attachments but the resources have not been copied. Please update the attachments manually.");
}

// Import groups table ===================================================================================
if (isset($xml->groups->rows->row)) {
foreach ($xml->groups->rows->row as $row) {
Expand Down
@@ -1,9 +1,35 @@

<?php
$script = array();
$script = [];
$hideAttacehemtTable = true;
$attachmentsHaveErrors = false;
if (isset($esrow->attachments[$tab])) {
foreach ($esrow->attachments[$tab] as $attachment) {
$script[] = sprintf(
"prepEmailTemplates.addAttachment($('#attachments-%s-%s'), %s, %s, %s, %s);",
$grouplang,
$tab,
json_encode($attachment['url']),
json_encode($attachment['relevance']),
json_encode($attachment['size']),
json_encode($attachment['error'] ?? '')
);
if (!empty($attachment['error'])) {
$attachmentsHaveErrors = true;
}
}
$hideAttacehemtTable = false;
}
?>

<div id='<?php echo "tab-".CHtml::encode($grouplang)."-".CHtml::encode($tab); ?>' class="tab-pane fade in <?=CHtml::encode($active); ?>">
<?php if ($attachmentsHaveErrors): ?>
<div class="row">
<div class='col-sm-12'>
<div class="alert alert-danger"><?= gT("There are errors with this template's attachments. Please check them below.") ?></div>
</div>
</div>
<?php endif; ?>
<div class="row">
<div class='mb-3 col-md-12'>
<label class=' form-label' for='email_<?php echo $tab; ?>_subj_<?php echo $grouplang; ?>'><?php echo $details['subject'] ?></label>
Expand Down Expand Up @@ -66,16 +92,6 @@

<?php } ?>

<?php
$hideAttacehemtTable = true;
if (isset($esrow->attachments[$tab])) {
foreach ($esrow->attachments[$tab] as $attachment) {
$script[] = sprintf("prepEmailTemplates.addAttachment($('#attachments-%s-%s'), %s, %s, %s );", $grouplang, $tab, json_encode($attachment['url']), json_encode($attachment['relevance']), json_encode($attachment['size']));
}
$hideAttacehemtTable = false;
}
?>

<div class="row selector__table-container <?=($hideAttacehemtTable===true ? 'd-none' : '')?>">
<div class='mb-3 col-12'>
<div class='mb-3'>
Expand Down
9 changes: 8 additions & 1 deletion assets/packages/emailtemplates/emailtemplates.js
@@ -1,5 +1,9 @@
// $Id: saved.js 9330 2010-10-24 22:23:56Z c_schmitz $

/**
* NOTE: After updating this file, generate the "minified" version with:
* uglifyjs -c -- emailtemplates.js > emailtemplates.min.js
*/

// Namespace
var LS = LS || { onDocumentReady: {} };
Expand Down Expand Up @@ -71,7 +75,7 @@ var PrepEmailTemplates = function(){
* @param size
* @return void
*/
addAttachment = function (target, url, relevance, size)
addAttachment = function (target, url, relevance, size, error)
{
if (typeof relevance == 'undefined')
{
Expand Down Expand Up @@ -102,6 +106,9 @@ var PrepEmailTemplates = function(){

$(newrow).find('input.relevance').val(relevance).attr('name', 'attachments' + templatetype + '[' + index + '][relevance]');
$(newrow).find('input.filename').attr('name', 'attachments' + templatetype + '[' + index + '][url]');
if (error) {
$(newrow).find('input.filename').parent().append($("<span class='fa fa-exclamation-triangle text-danger' title='" + error + "'></span>"));
}
$(newrow).appendTo($(target).find('tbody'));
const modal = bootstrap.Modal.getOrCreateInstance(document.getElementById('kc-modal-open'));
modal.hide();
Expand Down
1 change: 1 addition & 0 deletions assets/packages/emailtemplates/emailtemplates.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b938b37

Please sign in to comment.