Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue #19344: Survey activation error using MSSQL #3696

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 24 additions & 5 deletions application/controllers/admin/CheckIntegrity.php
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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')) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not always add $e->getMessage(); ?

$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
Original file line number Diff line number Diff line change
@@ -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>