Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed bug #15919: Cannot import custom question theme based on an arr…
…ay question (#1799)
  • Loading branch information
gabrieljenik committed Mar 25, 2021
1 parent bc372a8 commit 6ed4e91
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 50 deletions.
32 changes: 27 additions & 5 deletions application/controllers/admin/themes.php
Expand Up @@ -368,7 +368,6 @@ protected function uploadTemplate()
TemplateManifest::importManifest($sNewDirectoryName, ['extends' => $destdir]);
}
if ($themeType == 'question') {
$questionTheme = new QuestionTheme();
$sPathToThemeDirectory = $destdir . DIRECTORY_SEPARATOR . 'survey' . DIRECTORY_SEPARATOR . 'questions' . DIRECTORY_SEPARATOR . 'answer';
// check if the required path is right and existing
if (!is_dir($sPathToThemeDirectory)) {
Expand All @@ -379,17 +378,39 @@ protected function uploadTemplate()
);
$this->getController()->redirect(array("themeOptions/index#questionthemes"));
}
$sThemeDirectory = scandir($sPathToThemeDirectory)[2];
// install the Question Theme
$sQuestionThemeTitle = $questionTheme->importManifest($sPathToThemeDirectory . DIRECTORY_SEPARATOR . $sThemeDirectory);
if (empty($sQuestionThemeTitle)) {
// Question themes that apply to more than one question type, are technically different themes but can be distributed
// in the same ZIP. So we must try to install all the available themes in the folder.
$importedThemes = 0;
$directory = new RecursiveDirectoryIterator($sPathToThemeDirectory);
$iterator = new RecursiveIteratorIterator($directory);
$aImportErrors = [];
foreach ($iterator as $info) {
if ($info->isFile() && $info->getBasename() == 'config.xml') {
$questionConfigFilePath = dirname($info->getPathname());
$sQuestionThemeTitle = null;
try {
$questionTheme = new QuestionTheme();
$sQuestionThemeTitle = $questionTheme->importManifest($questionConfigFilePath, false, true);
} catch (Throwable $t) {
$sThemeDirectoryName = $questionTheme->getThemeDirectoryPath($questionConfigFilePath . "/config.xml");
$aImportErrors[$sThemeDirectoryName] = $t->getMessage();
}
if (!empty($sQuestionThemeTitle)) {
$importedThemes++;
}
}
}
if ($importedThemes == 0) {
rmdirr($destdir);
App()->setFlashMessage(
gT("An error occured while generating the Question theme"),
'error'
);
$this->getController()->redirect(array("themeOptions/index#questionthemes"));
}
if (count($aImportErrors) > 0) {
Yii::app()->setFlashMessage(gT("Some of the themes couldn't be imported."), 'error');
}
}
}
} else {
Expand All @@ -405,6 +426,7 @@ protected function uploadTemplate()
return array(
'aImportedFilesInfo' => $aImportedFilesInfo,
'aErrorFilesInfo' => $aErrorFilesInfo,
'aImportErrors' => $aImportErrors,
'lid' => $lid,
'newdir' => $sNewDirectoryName,
'theme' => $themeType
Expand Down
23 changes: 19 additions & 4 deletions application/models/QuestionTheme.php
Expand Up @@ -292,7 +292,7 @@ public function getManifestButtons()
* @return bool|string
* @throws Exception
*/
public function importManifest($sXMLDirectoryPath, $bSkipConversion = false)
public function importManifest($sXMLDirectoryPath, $bSkipConversion = false, $bThrowConversionException = false)
{
if (empty($sXMLDirectoryPath)) {
throw new InvalidArgumentException('$templateFolder cannot be empty');
Expand All @@ -302,8 +302,12 @@ public function importManifest($sXMLDirectoryPath, $bSkipConversion = false)
if ($bSkipConversion === false) {
$aConvertSuccess = self::convertLS3toLS4($sXMLDirectoryPath);
if (!$aConvertSuccess['success']) {
App()->setFlashMessage($aConvertSuccess['message'], 'error');
App()->getController()->redirect(array("themeOptions/index#questionthemes"));
if ($bThrowConversionException) {
throw new Exception($aConvertSuccess['message']);
} else {
App()->setFlashMessage($aConvertSuccess['message'], 'error');
App()->getController()->redirect(array("themeOptions/index#questionthemes"));
}
}
}

Expand Down Expand Up @@ -919,7 +923,7 @@ public static function convertLS3toLS4($sXMLDirectoryPath)
$oThemeConfig->compatibility->version = '4.0';
}

$sThemeDirectoryName = basename(dirname($sQuestionConfigFilePath, 1)); //todo: this does not work for all themes in array/... like arrays/10point
$sThemeDirectoryName = self::getThemeDirectoryPath($sQuestionConfigFilePath);
$sPathToCoreConfigFile = str_replace('\\', '/', App()->getConfig('rootdir') . '/application/views/survey/questions/answer/' . $sThemeDirectoryName . '/config.xml');
// check if core question theme can be found to fill in missing information
if (!is_file($sPathToCoreConfigFile)) {
Expand Down Expand Up @@ -1045,4 +1049,15 @@ public static function getAdditionalAttrFromExtendedTheme($sQuestionThemeName, $
}
return $additionalAttributes;
}

public static function getThemeDirectoryPath($sQuestionConfigFilePath)
{
$sQuestionConfigFilePath = str_replace('\\', '/', $sQuestionConfigFilePath);
$aMatches = array();
$sThemeDirectoryName = '';
if (preg_match('$questions/answer/(.*)/config.xml$', $sQuestionConfigFilePath, $aMatches)) {
$sThemeDirectoryName = $aMatches[1];
}
return $sThemeDirectoryName;
}
}
75 changes: 34 additions & 41 deletions application/views/admin/themes/importuploaded_view.php
Expand Up @@ -2,14 +2,14 @@
// TODO : move all this to controller
$okfiles = 0;
$errfiles = 0;
if (count($aErrorFilesInfo) == 0 && count($aImportedFilesInfo) > 0)
if (count($aErrorFilesInfo) == 0 && empty($aImportErrors) && count($aImportedFilesInfo) > 0)
{
$status = gT("Success");
$class = '';
$statusClass = 'text-success';
$okfiles = count($aImportedFilesInfo);
}
elseif (count($aErrorFilesInfo) > 0 && count($aImportedFilesInfo) > 0)
elseif ((count($aErrorFilesInfo) > 0 || !empty($aImportErrors)) && count($aImportedFilesInfo) > 0)
{
$status = gT("Partial");
$class = 'message-box-warning';
Expand Down Expand Up @@ -40,47 +40,40 @@
<?php echo gT("Files imported:") . " $okfiles" ?><br />
<?php echo gT("Files skipped:") . " $errfiles" ?><br />
</p>
<p>
<?php
if (count($aImportedFilesInfo) > 0)
{
?>
<br /><strong><u><?php eT("Imported files:") ?></u></strong><br />
<ul style="max-height: 250px; overflow-y:scroll;" class="list-unstyled">
<?php
foreach ($aImportedFilesInfo as $entry)
{
if ($entry['is_folder']){
?>
<li><?php printf(gT("Folder: %s"),CHtml::encode($entry["filename"])); ?></li>
<?php
}
else
{ ?>
<li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>


<?php
}
}
}
if (count($aErrorFilesInfo) > 0)
{
?>
</ul>
<br /><strong><u><?php eT("Skipped files:") ?></u></strong><br />
<ul style="max-height: 250px; overflow-y:scroll;" class="list-unstyled">
<?php
foreach ($aErrorFilesInfo as $entry)
{
?>
<?php if (count($aImportedFilesInfo) > 0): ?>
<p>
<br><strong><u><?php eT("Imported files:") ?></u></strong><br>
</p>
<ul style="max-height: 250px; overflow-y:scroll;" class="list-unstyled">
<?php foreach ($aImportedFilesInfo as $entry): ?>
<?php if ($entry['is_folder']): ?>
<li><?php printf(gT("Folder: %s"),CHtml::encode($entry["filename"])); ?></li>
<?php else: ?>
<li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>
<?php
}
}
?>
<?php endif; ?>
<?php endforeach; ?>
</ul>
</p>
<?php endif; ?>
<?php if (count($aErrorFilesInfo) > 0): ?>
<p>
<br><strong><u><?php eT("Skipped files:") ?></u></strong><br>
</p>
<ul style="max-height: 250px; overflow-y:scroll;" class="list-unstyled">
<?php foreach ($aErrorFilesInfo as $entry): ?>
<li><?php printf(gT("File: %s"),CHtml::encode($entry["filename"])); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php if (!empty($aImportErrors)): ?>
<p>
<br><strong><u><?php eT("Error details:") ?></u></strong><br>
</p>
<ul style="max-height: 250px; overflow-y:scroll;" class="list-unstyled">
<?php foreach ($aImportErrors as $sThemeDirectoryName => $error): ?>
<li><?php echo sprintf(gT("Error importing folder: %s"),CHtml::encode($sThemeDirectoryName)) . ": " . CHtml::encode($error); ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<p>
<input type='submit' class="btn btn-default btn-lg" id="button-open-theme"
value='<?php eT("Open imported theme") ?>'
Expand Down

0 comments on commit 6ed4e91

Please sign in to comment.