Skip to content

Commit

Permalink
Fixed issue #19344: Survey activation error when create a new survey …
Browse files Browse the repository at this point in the history
…using MSSQL (#3696)
  • Loading branch information
c-schmitz committed Jan 16, 2024
1 parent 356f60b commit 3593c6d
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
29 changes: 24 additions & 5 deletions application/controllers/admin/CheckIntegrity.php
Expand Up @@ -710,10 +710,10 @@ protected function checkintegrity()
// Fix subquestions
fixSubquestions();

/*** Check for active survey tables with missing survey entry and rename them ***/
/*** Check for active survey tables with missing survey entry or where survey entry is inactivate and rename them ***/
$sDBPrefix = Yii::app()->db->tablePrefix;
$aResult = Yii::app()->db->createCommand(dbSelectTablesLike('{{survey}}\_%'))->queryColumn();
$sSurveyIDs = Yii::app()->db->createCommand('select sid from {{surveys}}')->queryColumn();
$sSurveyIDs = Yii::app()->db->createCommand("select sid from {{surveys}} where active='Y'")->queryColumn();
foreach ($aResult as $aRow) {
$sTableName = (string) substr((string) $aRow, strlen((string) $sDBPrefix));
if ($sTableName == 'survey_links' || $sTableName == 'survey_url_parameters') {
Expand All @@ -723,18 +723,37 @@ protected function checkintegrity()
if (isset($aTableName[1]) && ctype_digit($aTableName[1])) {
$iSurveyID = $aTableName[1];
if (!in_array($iSurveyID, $sSurveyIDs)) {
$sDate = (string) date('YmdHis') . rand(1, 1000);
$datestamp = time();
$date = date('YmdHis', $datestamp); //'His' adds 24hours+minutes to name to allow multiple deactiviations in a day
$DBDate = date('Y-m-d H:i:s', $datestamp);
$userID = Yii::app()->user->getId();
// Check if it's really a survey_XXX table mantis #14938
if (empty($aTableName[2])) {
$sOldTable = "survey_{$iSurveyID}";
$sNewTable = "old_survey_{$iSurveyID}_{$sDate}";
$sNewTable = "old_survey_{$iSurveyID}_{$date}";
Yii::app()->db->createCommand()->renameTable("{{{$sOldTable}}}", "{{{$sNewTable}}}");
$archivedTokenSettings = new ArchivedTableSettings();
$archivedTokenSettings->survey_id = $iSurveyID;
$archivedTokenSettings->user_id = $userID;
$archivedTokenSettings->tbl_name = $sNewTable;
$archivedTokenSettings->tbl_type = 'response';
$archivedTokenSettings->created = $DBDate;
$archivedTokenSettings->properties = json_encode(Response::getEncryptedAttributes($iSurveyID));
$archivedTokenSettings->save();
$bDirectlyFixed = true;
}
if (!empty($aTableName[2]) && $aTableName[2] == "timings" && empty($aTableName[3])) {
$sOldTable = "survey_{$iSurveyID}_timings";
$sNewTable = "old_survey_{$iSurveyID}_timings_{$sDate}";
$sNewTable = "old_survey_{$iSurveyID}_timings_{$date}";
Yii::app()->db->createCommand()->renameTable("{{{$sOldTable}}}", "{{{$sNewTable}}}");
$archivedTokenSettings = new ArchivedTableSettings();
$archivedTokenSettings->survey_id = $iSurveyID;
$archivedTokenSettings->user_id = $userID;
$archivedTokenSettings->tbl_name = $sNewTable;
$archivedTokenSettings->tbl_type = 'timings';
$archivedTokenSettings->created = $DBDate;
$archivedTokenSettings->properties = '';
$archivedTokenSettings->save();
$bDirectlyFixed = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion application/helpers/admin/activate_helper.php
Expand Up @@ -338,7 +338,7 @@ function mssql_drop_primary_index($tablename)
* @param string $tablename The table the column should be deleted
* @param string $columnname The column that should be deleted
*/
function mssql_drop_coulmn_with_constraints($tablename, $columnname)
function mssql_drop_column_with_constraints($tablename, $columnname)
{
Yii::app()->loadHelper("database");

Expand Down
5 changes: 4 additions & 1 deletion application/models/SurveyActivator.php
Expand Up @@ -324,6 +324,7 @@ protected function createResponseTable()
// Refresh schema cache just in case the table existed in the past
Yii::app()->db->schema->getTable($sTableName, true);
} catch (Exception $e) {
$this->error = 'surveytablecreation';
if (App()->getConfig('debug')) {
$this->error = $e->getMessage();
} else {
Expand Down Expand Up @@ -371,6 +372,7 @@ protected function showEventMessages($event)
*/
protected function createResponseTableKeys()
{

$iAutoNumberStart = Yii::app()->db->createCommand()
->select('autonumber_start')
->from(Survey::model()->tableName())
Expand All @@ -380,7 +382,8 @@ protected function createResponseTableKeys()
//if there is an autonumber_start field, start auto numbering here
if ($iAutoNumberStart !== false && $iAutoNumberStart > 0) {
if (Yii::app()->db->driverName == 'mssql' || Yii::app()->db->driverName == 'sqlsrv' || Yii::app()->db->driverName == 'dblib') {
mssql_drop_coulmn_with_constraints($this->survey->responsesTableName, 'id');
Yii::app()->loadHelper("admin.activate"); // needed for mssql_drop_column_with_constraints
mssql_drop_column_with_constraints($this->survey->responsesTableName, 'id');
$sQuery = "ALTER TABLE {$this->survey->responsesTableName} ADD [id] int identity({$iAutoNumberStart},1)";
Yii::app()->db->createCommand($sQuery)->execute();
// Add back the primaryKey
Expand Down
@@ -1,36 +1,35 @@
<?php

/**
* View for the message box when survey activation goes wrong.
*/

?>

<div id="pjax-content" class="ls-flex-column align-items-flex-start align-content-center col-11 ls-flex-item transition-animate-width">
<div class="ls-flex-column fill col-12 overflow-enabled">
<div class="row col-12">
<h3 class="pagetitle"><?php eT('Survey activation error'); ?></h3>
<?php if ($result['error'] == 'surveytablecreation'): ?>
<?php
<?php if (App()->getConfig('debug')) : ?>
<p><?php eT('Database error'); ?></p>
<pre>
<?php echo $result['error']; ?>
</pre>
<?php elseif ($result['error'] == 'surveytablecreation' && !App()->getConfig('debug')) :
$this->widget('ext.AlertWidget.AlertWidget', [
'header' => gT("The survey response table could not be created."),
'text' => gT("Usually this is caused by having too many (sub-)questions in your survey. Please try removing questions from your survey."),
'type' => 'warning',
]);
?>
<?php else: ?>
<?php else : ?>
<?php
$this->widget('ext.AlertWidget.AlertWidget', [
'text' => gT("Timings table could not be created."),
'type' => 'warning',
]);
?>
<?php endif; ?>

<?php if (App()->getConfig('debug')): ?>
<p><?php eT('Database error'); ?></p>
<pre>
<?php echo $result['error']; ?>
</pre>
<?php endif; ?>
</div>
</div>
</div>

0 comments on commit 3593c6d

Please sign in to comment.