1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/limesurvey_ynh.git synced 2024-09-03 19:36:32 +02:00

[enh] Update sources with limesurvey205plus-build150520.zip

This commit is contained in:
zamentur 2015-05-31 22:38:30 +02:00
parent f3f9db0088
commit 406e39e8c7
609 changed files with 45003 additions and 72298 deletions

View file

@ -1,11 +0,0 @@
<IfModule mod_rewrite.c>
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
# otherwise forward it to index.php
RewriteRule . index.php
</IfModule>
# General setting to properly handle LimeSurvey paths
# AcceptPathInfo on

View file

@ -1,11 +0,0 @@
filter:
excluded_paths: [framework/*, locale/*, docs/*, fonts/*, third_party/*, application/third_party/*, images/*, styles/*, styles-public/*, templates/*, themes/*, tmp/*, upload/*]
paths: [application/*]
tools:
php_code_sniffer:
config:
standard: "PSR1"
php_pdepend:
command: pdepend
php_cs_fixer:
config: { level: psr1 }

View file

@ -41,9 +41,6 @@
$sql_file = 'mysql'; $sql_file = 'mysql';
break; break;
case 'pgsql': case 'pgsql':
if (version_compare($this->connection->getServerVersion(),'9','>=')) {
$this->connection->createCommand("ALTER DATABASE ". $this->connection->quoteTableName($this->getDBConnectionStringProperty('dbname')) ." SET bytea_output='escape';")->execute();
}
$sql_file = 'pgsql'; $sql_file = 'pgsql';
break; break;
case 'dblib': case 'dblib':
@ -52,7 +49,7 @@
$sql_file = 'mssql'; $sql_file = 'mssql';
break; break;
default: default:
throw new Exception(sprintf('Unkown database type "%s".', $this->connection->driverName)); throw new Exception(sprintf('Unknown database type "%s".', $this->connection->driverName));
} }
$this->_executeSQLFile(dirname(Yii::app()->basePath).'/installer/sql/create-'.$sql_file.'.sql'); $this->_executeSQLFile(dirname(Yii::app()->basePath).'/installer/sql/create-'.$sql_file.'.sql');
$this->connection->createCommand()->insert($this->connection->tablePrefix.'users', array( $this->connection->createCommand()->insert($this->connection->tablePrefix.'users', array(
@ -130,10 +127,12 @@
protected function createDatabase() protected function createDatabase()
{ {
App()->configure(array('components'=>array('db'=>array('autoConnect'=>false)))) ;
$this->connection=App()->db;
App()->configure(array('components'=>array('db'=>array('autoConnect'=>true)))) ;
$connectionString = $this->connection->connectionString; $connectionString = $this->connection->connectionString;
$this->connection->connectionString = preg_replace('/dbname=([^;]*)/', '', $connectionString); $this->connection->connectionString = preg_replace('/dbname=([^;]*)/', '', $connectionString);
try try {
{
$this->connection->active=true; $this->connection->active=true;
} }
catch(Exception $e){ catch(Exception $e){

View file

@ -68,10 +68,8 @@ $config['minrepeatheadings'] = 3; // The minimum number of rem
$config['defaultlang'] = 'en'; // The default language to use - the available languages are the directory names in the /locale dir - for example de = German $config['defaultlang'] = 'en'; // The default language to use - the available languages are the directory names in the /locale dir - for example de = German
$config['timeadjust'] = 0; // Number of hours to adjust between your webserver local time and your own local time (for datestamping responses) $config['timeadjust'] = 0; // Number of hours to adjust between your webserver local time and your own local time (for datestamping responses)
$config['allowexportalldb'] = 1; // 0 will only export prefixed tables when doing a database dump. If set to 1 ALL tables in the database will be exported $config['allowexportalldb'] = 0; // 0 will only export prefixed tables when doing a database dump. If set to 1 ALL tables in the database will be exported
$config['maxdumpdbrecords'] = 500; // The maximum number of records that would be ouputted in a go during a database backup. Reduce this number if you're getting errors while backing up the entire database. $config['maxdumpdbrecords'] = 500; // The maximum number of records that would be ouputted in a go during a database backup. Reduce this number if you're getting errors while backing up the entire database.
$config['allowmandbackwards'] = 1; // Allow moving backwards (ie: << prev) through survey if a mandatory question
// has not been answered. 1=Allow, 0=Deny
$config['deletenonvalues'] = 1; // By default, LimeSurvey does not save responses to conditional questions that haven't been answered/shown. To have LimeSurvey save these responses change this value to 0. $config['deletenonvalues'] = 1; // By default, LimeSurvey does not save responses to conditional questions that haven't been answered/shown. To have LimeSurvey save these responses change this value to 0.
$config['stringcomparizonoperators'] = 0; // By default, LimeSurvey assumes the numrical order for comparizon operators in conditions. If you need string comparizon operators, set this parameter to 1 $config['stringcomparizonoperators'] = 0; // By default, LimeSurvey assumes the numrical order for comparizon operators in conditions. If you need string comparizon operators, set this parameter to 1
$config['shownoanswer'] = 1; // Show 'no answer' for non mandatory questions ( 0 = no , 1 = yes , 2 = survey admin can choose ) $config['shownoanswer'] = 1; // Show 'no answer' for non mandatory questions ( 0 = no , 1 = yes , 2 = survey admin can choose )
@ -84,11 +82,11 @@ $config['allowunblacklist'] = 'N'; // Allow participant to unbl
$config['userideditable'] = 'N'; // Allow editing of user IDs $config['userideditable'] = 'N'; // Allow editing of user IDs
$config['defaulttemplate'] = 'default'; // This setting specifys the default theme used for the 'public list' of surveys $config['defaulttemplate'] = 'default'; // This setting specifys the default theme used for the 'public list' of surveys
$config['allowedtemplateuploads'] = 'gif,ico,jpg,png,css,js'; // File types allowed to be uploaded in the templates section. $config['allowedtemplateuploads'] = 'gif,ico,jpg,png,css,js,map,json,eot,svg,ttf,woff,txt,md'; // File types allowed to be uploaded in the templates section.
$config['allowedresourcesuploads'] = '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,ico,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,xml,zip,pstpl,css,js'; // File types allowed to be uploaded in the resources sections, and with the HTML Editor $config['allowedresourcesuploads'] = '7z,aiff,asf,avi,bmp,csv,doc,docx,fla,flv,gif,gz,gzip,ico,jpeg,jpg,mid,mov,mp3,mp4,mpc,mpeg,mpg,ods,odt,pdf,png,ppt,pxd,qt,ram,rar,rm,rmi,rmvb,rtf,sdc,sitd,swf,sxc,sxw,tar,tgz,tif,tiff,txt,vsd,wav,wma,wmv,xls,xlsx,xml,zip,pstpl,css,js'; // File types allowed to be uploaded in the resources sections, and with the HTML Editor
$config['memory_limit'] = '32'; // This sets how much memory LimeSurvey can access in megabytes. 32 mb is the minimum recommended - if you are using PDF functions up to 64 mb may be needed $config['memory_limit'] = '128'; // This sets how much memory LimeSurvey can access in megabytes. 128 MB is the minimum recommended - if you are using PDF functions up to 256 MB may be needed
$config['showpopups'] = 1; // Show popup messages if mandatory or conditional questions have not been answered correctly. $config['showpopups'] = 1; // Show popup messages if mandatory or conditional questions have not been answered correctly.
// 1=Show popup message, 0=Show message on page instead. // 1=Show popup message, 0=Show message on page instead.
@ -317,6 +315,13 @@ $config['showsgqacode'] = false;
*/ */
$config['showrelevance'] = false; $config['showrelevance'] = false;
/**
* To prevent brute force against forgotten password functionality, there is a random delay
* that prevent attacker from knowing whether username and email address are valid or not.
*/
$config['minforgottenpasswordemaildelay'] = 500000;
$config['maxforgottenpasswordemaildelay'] = 1500000;
/** /**
* PDF Export Settings * PDF Export Settings
* This feature configures PDF export for Export Answers * This feature configures PDF export for Export Answers
@ -334,14 +339,15 @@ $config['alternatepdffontfile']=array(
'ar'=>'dejavusans',// 'dejavusans' work but maybe more characters in aealarabiya or almohanad: but then need a dynamic font size too 'ar'=>'dejavusans',// 'dejavusans' work but maybe more characters in aealarabiya or almohanad: but then need a dynamic font size too
'be'=>'dejavusans', 'be'=>'dejavusans',
'bg'=>'dejavusans', 'bg'=>'dejavusans',
'zh-Hans'=>'chinese', 'zh-Hans'=>'cid0cs',
'zh-Hant-HK'=>'chinese', 'zh-Hant-HK'=>'cid0ct',
'zh-Hant-TW'=>'chinese', 'zh-Hant-TW'=>'cid0ct',
'cs'=>'dejavusans', 'cs'=>'dejavusans',
'cs-informal'=>'dejavusans',// This one not really tested: no translation for Yes/No or Gender 'cs-informal'=>'dejavusans',// This one not really tested: no translation for Yes/No or Gender
'el'=>'dejavusans', 'el'=>'dejavusans',
'he'=>'freesans', 'he'=>'freesans',
'hi'=>'dejavusans', 'hi'=>'dejavusans',
'hr'=>'dejavusans',
'hu'=>'dejavusans', 'hu'=>'dejavusans',
'ja'=>'cid0jp', 'ja'=>'cid0jp',
'ko'=>'cid0kr', 'ko'=>'cid0kr',
@ -367,27 +373,19 @@ $config['notsupportlanguages'] = array(
); );
$config['pdffontsize'] = 9; //Fontsize for normal text; Surveytitle is +4; grouptitle is +2 $config['pdffontsize'] = 9; //Fontsize for normal text; Surveytitle is +4; grouptitle is +2
$config['pdforientation'] = 'P'; // Set L for Landscape or P for portrait format $config['pdforientation'] = 'P'; // Set L for Landscape or P for portrait format
$config['pdfshowheader'] = 'N'; // Show header in pdf answer export
$config['pdflogofile'] = 'logo_pdf.png'; // File name of logo for single answer export. Path is template path, i.e. template/default/logo_pdf.png.
// If not found, resulting pdf doesn't have header. A large image implies slower pdf generation.
$config['pdflogowidth'] = '50'; // Logo width
$config['pdfheadertitle'] = ''; // Header title (bold font). If this config param is empty and header is enabled, site name is used
$config['pdfheaderstring'] = ''; // Header string (under title). If this config param is empty and header is enabled, survey name is used
// QueXML-PDF: If set to true, the printable_help attribute will be visible on the exported PDF questionnaires // QueXML-PDF: If set to true, the printable_help attribute will be visible on the exported PDF questionnaires
// If used, the appearance (font size, justification, etc.) may be adjusted by editing td.questionHelpBefore and $helpBeforeBorderBottom of quexml. // If used, the appearance (font size, justification, etc.) may be adjusted by editing td.questionHelpBefore and $helpBeforeBorderBottom of quexml.
$config['quexmlshowprintablehelp'] = false; $config['quexmlshowprintablehelp'] = false;
// CAS Settings $config['minlengthshortimplode'] = 20; // Min length required to use short_implode instead of standard implode
/** $config['maxstringlengthshortimplode'] = 100; // short_implode: Max length of returned string
* Please note that CAS functionality is very basic and you have to modify the client to your needs.
* At least the hard work is done.
* The Client is deployed in Limesurvey and a file login_check_cas.php does what login_check.php does in normal mode.
*
* $casEnabled determines if CAS should be used or not for Authentication.
* $casAuthServer the servername of the cas Auth Server. Without http://
* $casAuthPort CAS Server listening Port
* $casAuthUri relative uri from $casAuthServer to cas workingdirectory
*/
$config['casEnabled'] = false;
$config['casAuthServer'] = 'localhost';
$config['casAuthPort'] = 8443;
$config['casAuthUri'] = '/cas-server/';
/** /**
* Statistics chart settings * Statistics chart settings

View file

@ -22,10 +22,9 @@
| |
*/ */
return array( return array(
'name' => 'LimeSurvey',
'components' => array( 'components' => array(
'db' => array( 'db' => array(
'connectionString' => 'mysql:host=localhost;port=3306;dbname=limesurvey', 'connectionString' => 'mysql:host=localhost;port=3306;dbname=limesurvey;',
'emulatePrepare' => true, 'emulatePrepare' => true,
'username' => 'root', 'username' => 'root',
'password' => '', 'password' => '',

View file

@ -18,6 +18,7 @@ $route['<_sid:\d+>/lang-<_lang:\w+[-\w]+>/tk-<_token:\w+>/*'] = "survey/index/si
$route['<_sid:\d+>/lang-<_lang:\w+[-\w]+>/*'] = "survey/index/sid/<_sid>/lang/<_lang>"; $route['<_sid:\d+>/lang-<_lang:\w+[-\w]+>/*'] = "survey/index/sid/<_sid>/lang/<_lang>";
$route['<_sid:\d+>/tk-<_token:\w+>/*'] = "survey/index/sid/<_sid>/token/<_token>"; $route['<_sid:\d+>/tk-<_token:\w+>/*'] = "survey/index/sid/<_sid>/token/<_token>";
$route['<_sid:\d+>/*'] = "survey/index/sid/<_sid>"; $route['<_sid:\d+>/*'] = "survey/index/sid/<_sid>";
$route['<sid:\d+>'] = array('survey/index','matchValue'=>true);
//Admin Routes //Admin Routes
$route['admin/index'] = "admin"; $route['admin/index'] = "admin";
@ -28,12 +29,15 @@ $route['admin/<action:\w+>/<sa:\w+>/*'] = 'admin/<action>/sa/<sa>';
$route['admin/labels/<_action:\w+>'] = "admin/labels/index/<_action>"; $route['admin/labels/<_action:\w+>'] = "admin/labels/index/<_action>";
$route['admin/labels/<_action:\w+>/<_lid:\d+>'] = "admin/labels/index/<_action>/<_lid>"; $route['admin/labels/<_action:\w+>/<_lid:\d+>'] = "admin/labels/index/<_action>/<_lid>";
$route['<_controller:\w+>/<_action:\w+>'] = '<_controller>/<_action>';
//Expression Manager tests //Expression Manager tests
$route['admin/expressions'] = "admin/expressions/index"; $route['admin/expressions'] = "admin/expressions/index";
//optout //optout - optin
$route['optout/<_sid:\d+>/(:any)/(:any)'] = "optout/index/<_sid>/$2/$3"; $route['optout/<_sid:\d+>/(:any)/(:any)'] = "optout/index/<_sid>/$2/$3";
$route['optout/tokens/<surveyid:\d+>'] = array('optout/tokens','matchValue'=>true);
$route['optin/tokens/<surveyid:\d+>'] = array('optin/tokens','matchValue'=>true);
$route['statistics_user/<surveyid:\d+>'] = array('statistics_user/action','matchValue'=>true);
$route['<_controller:\w+>/<_action:\w+>'] = '<_controller>/<_action>';
return $route; return $route;

View file

@ -47,7 +47,7 @@
* ADD TRAILING SLASH! * ADD TRAILING SLASH!
***********************************************************/ ***********************************************************/
$tcpdf['base_url'] = ''; $tcpdf['base_url'] = 'dummy'; // If empty and debug === 2, "empty needle" occurs
/************************************************************ /************************************************************
@ -97,15 +97,6 @@
$tcpdf['blank_image'] = $tcpdf['image_directory'].'_blank.png'; $tcpdf['blank_image'] = $tcpdf['image_directory'].'_blank.png';
/************************************************************
* TCPDF language settings file
* ----------------------------------------------------------
* Directory and filename of the language settings file
***********************************************************/
$tcpdf['language_file'] = $tcpdf['base_directory'].'config'.DIRECTORY_SEPARATOR.'lang'.DIRECTORY_SEPARATOR.'eng.php';
/*************************************************************************** /***************************************************************************
* DOCUMENT CONFIGURATION PARAMETERS * DOCUMENT CONFIGURATION PARAMETERS
@ -203,8 +194,11 @@
* HTML <small> font size ratio * HTML <small> font size ratio
***********************************************************/ ***********************************************************/
$tcpdf['page_font'] = 'freemono'; $tcpdf['page_font'] = 'freesans';
$tcpdf['page_font_size'] = 9; $tcpdf['page_font_size'] = 9;
$tcpdf['data_font'] = 'freesans';
$tcpdf['data_font_size'] = 8;
$tcpdf['mono_font'] = 'freemono';
$tcpdf['small_font_ratio'] = 2/3; $tcpdf['small_font_ratio'] = 2/3;

View file

@ -13,8 +13,8 @@
*/ */
$config['versionnumber'] = "2.05+"; $config['versionnumber'] = "2.05+";
$config['dbversionnumber'] = 177; $config['dbversionnumber'] = 178;
$config['buildnumber'] = ''; $config['buildnumber'] = '150520';
$config['updatable'] = true; $config['updatable'] = true;
return $config; return $config;

View file

@ -47,6 +47,7 @@ class InstallerController extends CController {
{ {
self::_checkInstallation(); self::_checkInstallation();
self::_sessioncontrol(); self::_sessioncontrol();
Yii::import('application.helpers.common_helper', true);
switch ($action) { switch ($action) {
@ -237,6 +238,13 @@ class InstallerController extends CController {
$aData['classesForStep'] = array('off','off','off','on','off','off'); $aData['classesForStep'] = array('off','off','off','on','off','off');
$aData['progressValue'] = 40; $aData['progressValue'] = 40;
$aData['model'] = $oModel = new InstallerConfigForm; $aData['model'] = $oModel = new InstallerConfigForm;
if (isset(Yii::app()->session['populateerror']))
{
$oModel->addError('dblocation',Yii::app()->session['populateerror']);
$oModel->addError('dbpwd','');
$oModel->addError('dbuser','');
unset(Yii::app()->session['populateerror']);
}
if(isset($_POST['InstallerConfigForm'])) if(isset($_POST['InstallerConfigForm']))
{ {
@ -461,7 +469,7 @@ class InstallerController extends CController {
$bCreateDB=false; $bCreateDB=false;
} }
break; break;
case 'postgres': case 'pgsql':
try try
{ {
$this->connection->createCommand("CREATE DATABASE \"$sDatabaseName\" ENCODING 'UTF8'")->execute(); $this->connection->createCommand("CREATE DATABASE \"$sDatabaseName\" ENCODING 'UTF8'")->execute();
@ -556,7 +564,7 @@ class InstallerController extends CController {
$sql_file = 'pgsql'; $sql_file = 'pgsql';
break; break;
default: default:
throw new Exception(sprintf('Unkown database type "%s".', $sDatabaseType)); throw new Exception(sprintf('Unknown database type "%s".', $sDatabaseType));
} }
//checking DB Connection //checking DB Connection
@ -575,12 +583,15 @@ class InstallerController extends CController {
} }
else else
{ {
$sConfirmation = $clang->gT('Database was populated but there were errors:').'<p><ul>'; $sConfirmation = $clang->gT('There were errors when trying to populate the database:').'<p><ul>';
foreach ($aErrors as $sError) foreach ($aErrors as $sError)
{ {
$sConfirmation.='<li>'.htmlspecialchars($sError).'</li>'; $sConfirmation.='<li>'.htmlspecialchars($sError).'</li>';
} }
$sConfirmation.='</ul>'; $sConfirmation.='</ul>';
Yii::app()->session['populateerror']=$sConfirmation;
$this->redirect(array('installer/database'));
} }
Yii::app()->session['tablesexist'] = true; Yii::app()->session['tablesexist'] = true;
@ -631,8 +642,16 @@ class InstallerController extends CController {
if ($this->connection->getActive() == true) { if ($this->connection->getActive() == true) {
$sPasswordHash=hash('sha256', $sDefaultAdminPassword); $sPasswordHash=hash('sha256', $sDefaultAdminPassword);
try { try {
if (User::model()->count()>0){
die();
}
// Save user // Save user
$user=new User; $user=new User;
// Fix UserID to 1 for MySQL even if installed in master-master configuration scenario
if (in_array($this->connection->getDriverName(), array('mysql', 'mysqli'))) {
$user->uid=1;
}
$user->users_name=$sDefaultAdminUserName; $user->users_name=$sDefaultAdminUserName;
$user->password=$sPasswordHash; $user->password=$sPasswordHash;
$user->full_name=$sDefaultAdminRealName; $user->full_name=$sDefaultAdminRealName;
@ -835,7 +854,7 @@ class InstallerController extends CController {
if (version_compare(PHP_VERSION, '5.3.0', '<')) if (version_compare(PHP_VERSION, '5.3.0', '<'))
$bProceed = !$aData['verror'] = true; $bProceed = !$aData['verror'] = true;
if ($this->return_bytes(ini_get('memory_limit'))/1024/1024<64 && ini_get('memory_limit')!=-1) if (convertPHPSizeToBytes(ini_get('memory_limit'))/1024/1024<64 && ini_get('memory_limit')!=-1)
$bProceed = !$aData['bMemoryError'] = true; $bProceed = !$aData['bMemoryError'] = true;
@ -904,16 +923,15 @@ class InstallerController extends CController {
function _setup_tables($sFileName, $aDbConfig = array(), $sDatabasePrefix = '') function _setup_tables($sFileName, $aDbConfig = array(), $sDatabasePrefix = '')
{ {
extract(empty($aDbConfig) ? self::_getDatabaseConfig() : $aDbConfig); extract(empty($aDbConfig) ? self::_getDatabaseConfig() : $aDbConfig);
switch ($sDatabaseType) { try{
case 'mysql': switch ($sDatabaseType) {
case 'mysqli': case 'mysql':
$this->connection->createCommand("ALTER DATABASE ". $this->connection->quoteTableName($sDatabaseName) ." DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;")->execute(); case 'mysqli':
break; $this->connection->createCommand("ALTER DATABASE ". $this->connection->quoteTableName($sDatabaseName) ." DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;")->execute();
case 'pgsql': break;
if (version_compare($this->connection->getServerVersion(),'9','>=')) { }
$this->connection->createCommand("ALTER DATABASE ". $this->connection->quoteTableName($sDatabaseName) ." SET bytea_output='escape';")->execute(); } catch(Exception $e) {
} return array($e->getMessage());
break;
} }
return $this->_executeSQLFile($sFileName, $sDatabasePrefix); return $this->_executeSQLFile($sFileName, $sDatabasePrefix);
@ -1238,7 +1256,7 @@ class InstallerController extends CController {
return true; return true;
} catch(Exception $e) { } catch(Exception $e) {
if (!empty($aData['model']) && !empty($aData['clang'])) { if (!empty($aData['model']) && !empty($aData['clang'])) {
$aData['model']->addError('dblocation', $aData['clang']->gT('Try again! Connection with database failed. Reason: ') . $e->message); $aData['model']->addError('dblocation', $aData['clang']->gT('Try again! Connection with database failed. Reason: ') . $e->getMessage());
$this->render('/installer/dbconfig_view', $aData); $this->render('/installer/dbconfig_view', $aData);
} else { } else {
return false; return false;
@ -1246,25 +1264,4 @@ class InstallerController extends CController {
} }
} }
/**
* This function returns the full number from a PHP ini value
*
* @param string $sValue
*/
function return_bytes($sValue) {
$sValue = trim($sValue);
$sLast = strtolower($sValue[strlen($sValue)-1]);
switch($sLast) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$sValue *= 1024;
case 'm':
$sValue *= 1024;
case 'k':
$sValue *= 1024;
}
return $sValue;
}
} }

View file

@ -73,7 +73,7 @@ class OptoutController extends LSYii_Controller {
} }
else else
{ {
if ($oToken->emailstatus == 'OK') if (substr($oToken->emailstatus, 0, strlen('OptOut')) !== 'OptOut')
{ {
$oToken->emailstatus = 'OptOut'; $oToken->emailstatus = 'OptOut';
$oToken->save(); $oToken->save();
@ -148,7 +148,7 @@ class OptoutController extends LSYii_Controller {
} }
else else
{ {
if ($oToken->emailstatus == 'OK') if (substr($oToken->emailstatus, 0, strlen('OptOut')) !== 'OptOut')
{ {
$oToken->emailstatus = 'OptOut'; $oToken->emailstatus = 'OptOut';
$oToken->save(); $oToken->save();
@ -166,7 +166,8 @@ class OptoutController extends LSYii_Controller {
{ {
$sMessage .= "<br />"; $sMessage .= "<br />";
$sMessage .= $clang->gT("You have already been removed from the central participants list for this site"); $sMessage .= $clang->gT("You have already been removed from the central participants list for this site");
} else }
else
{ {
$oParticipant->blacklisted='Y'; $oParticipant->blacklisted='Y';
$oParticipant->save(); $oParticipant->save();

View file

@ -95,15 +95,19 @@ class PluginsController extends LSYii_Controller
$this->forward('plugins/index', true); $this->forward('plugins/index', true);
} }
// Prepare settings to be send to the view.
$aSettings = $oPluginObject->getPluginSettings(); $aSettings = $oPluginObject->getPluginSettings();
if (empty($aSettings)) if (empty($aSettings))
{ {
// And show a message // And show a message
Yii::app()->user->setFlash('pluginmanager', 'This plugin has no settings'); Yii::app()->user->setFlash('pluginmanager', 'This plugin has no settings');
$this->forward('plugins/index', true); $this->forward('plugins/index', true);
} }
$this->render('/plugins/configure', array('settings' => $aSettings, 'plugin' => $arPlugin));
// Send to view plugin porperties: name and description
$aPluginProp = App()->getPluginManager()->getPluginInfo($arPlugin['name']);
$this->render('/plugins/configure', array('settings' => $aSettings, 'plugin' => $arPlugin, 'properties' => $aPluginProp));
} }
public function actionDeactivate($id) public function actionDeactivate($id)

View file

@ -91,87 +91,61 @@
$sSRID = $_SESSION['survey_'.$iSurveyID]['srid']; //I want to see the answers with this id $sSRID = $_SESSION['survey_'.$iSurveyID]['srid']; //I want to see the answers with this id
//Ensure script is not run directly, avoid path disclosure //Ensure script is not run directly, avoid path disclosure
//if (!isset($rootdir) || isset($_REQUEST['$rootdir'])) {die( "browse - Cannot run this script directly");} //if (!isset($rootdir) || isset($_REQUEST['$rootdir'])) {die( "browse - Cannot run this script directly");}
if ($aSurveyInfo['printanswers'] == 'N')
//Ensure Participants printAnswer setting is set to true or that the logged user have read permissions over the responses.
if ($aSurveyInfo['printanswers'] == 'N' && !Permission::model()->hasSurveyPermission($iSurveyID,'responses','read'))
{ {
die(); //Die quietly if print answers is not permitted throw new CHttpException(401, 'You are not allowed to print answers.');
} }
//CHECK IF SURVEY IS ACTIVATED AND EXISTS //CHECK IF SURVEY IS ACTIVATED AND EXISTS
$sSurveyName = $aSurveyInfo['surveyls_title']; $sSurveyName = $aSurveyInfo['surveyls_title'];
$sAnonymized = $aSurveyInfo['anonymized']; $sAnonymized = $aSurveyInfo['anonymized'];
//OK. IF WE GOT THIS FAR, THEN THE SURVEY EXISTS AND IT IS ACTIVE, SO LETS GET TO WORK. //OK. IF WE GOT THIS FAR, THEN THE SURVEY EXISTS AND IT IS ACTIVE, SO LETS GET TO WORK.
//SHOW HEADER //SHOW HEADER
$sOutput = CHtml::form(array("printanswers/view/surveyid/{$iSurveyID}/printableexport/pdf"), 'post') if ($sExportType != 'pdf')
."<center><input type='submit' value='".$clang->gT("PDF export")."'id=\"exportbutton\"/><input type='hidden' name='printableexport' /></center></form>";
if($sExportType == 'pdf')
{ {
//require (Yii::app()->getConfig('rootdir').'/application/config/tcpdf.php'); $sOutput = CHtml::form(array("printanswers/view/surveyid/{$iSurveyID}/printableexport/pdf"), 'post')
Yii::import('application.libraries.admin.pdf', true); ."<center><input type='submit' value='".$clang->gT("PDF export")."'id=\"exportbutton\"/><input type='hidden' name='printableexport' /></center></form>";
Yii::import('application.helpers.pdfHelper'); $sOutput .= "\t<div class='printouttitle'><strong>".$clang->gT("Survey name (ID):")."</strong> $sSurveyName ($iSurveyID)</div><p>&nbsp;\n";
$aPdfLanguageSettings=pdfHelper::getPdfLanguageSettings($clang->langcode); LimeExpressionManager::StartProcessingPage(true); // means that all variables are on the same page
$oPDF = new pdf(); // Since all data are loaded, and don't need JavaScript, pretend all from Group 1
$oPDF->SetTitle($clang->gT("Survey name (ID)",'unescaped').": {$sSurveyName} ({$iSurveyID})"); LimeExpressionManager::StartProcessingGroup(1,($aSurveyInfo['anonymized']!="N"),$iSurveyID);
$oPDF->SetSubject($sSurveyName); $printanswershonorsconditions = Yii::app()->getConfig('printanswershonorsconditions');
$oPDF->SetDisplayMode('fullpage', 'two'); $aFullResponseTable = getFullResponseTable($iSurveyID,$sSRID,$sLanguage,$printanswershonorsconditions);
$oPDF->setLanguageArray($aPdfLanguageSettings['lg']); //Get the fieldmap @TODO: do we need to filter out some fields?
$oPDF->setHeaderFont(Array($aPdfLanguageSettings['pdffont'], '', PDF_FONT_SIZE_MAIN)); if($aSurveyInfo['datestamp']!="Y" || $sAnonymized == 'Y'){
$oPDF->setFooterFont(Array($aPdfLanguageSettings['pdffont'], '', PDF_FONT_SIZE_DATA)); unset ($aFullResponseTable['submitdate']);
$oPDF->SetFont($aPdfLanguageSettings['pdffont'], '', $aPdfLanguageSettings['pdffontsize']); }else{
$oPDF->AddPage(); unset ($aFullResponseTable['id']);
$oPDF->titleintopdf($clang->gT("Survey name (ID)",'unescaped').": {$sSurveyName} ({$iSurveyID})");
}
$sOutput .= "\t<div class='printouttitle'><strong>".$clang->gT("Survey name (ID):")."</strong> $sSurveyName ($iSurveyID)</div><p>&nbsp;\n";
LimeExpressionManager::StartProcessingPage(true); // means that all variables are on the same page
// Since all data are loaded, and don't need JavaScript, pretend all from Group 1
LimeExpressionManager::StartProcessingGroup(1,($aSurveyInfo['anonymized']!="N"),$iSurveyID);
$printanswershonorsconditions = Yii::app()->getConfig('printanswershonorsconditions');
$aFullResponseTable = getFullResponseTable($iSurveyID,$sSRID,$sLanguage,$printanswershonorsconditions);
//Get the fieldmap @TODO: do we need to filter out some fields?
if($aSurveyInfo['datestamp']!="Y" || $sAnonymized == 'Y'){
unset ($aFullResponseTable['submitdate']);
}else{
unset ($aFullResponseTable['id']);
}
unset ($aFullResponseTable['token']);
unset ($aFullResponseTable['lastpage']);
unset ($aFullResponseTable['startlanguage']);
unset ($aFullResponseTable['datestamp']);
unset ($aFullResponseTable['startdate']);
$sOutput .= "<table class='printouttable' >\n";
foreach ($aFullResponseTable as $sFieldname=>$fname)
{
if (substr($sFieldname,0,4) == 'gid_')
{
$sOutput .= "\t<tr class='printanswersgroup'><td colspan='2'>{$fname[0]}</td></tr>\n";
} }
elseif (substr($sFieldname,0,4)=='qid_') unset ($aFullResponseTable['token']);
unset ($aFullResponseTable['lastpage']);
unset ($aFullResponseTable['startlanguage']);
unset ($aFullResponseTable['datestamp']);
unset ($aFullResponseTable['startdate']);
$sOutput .= "<table class='printouttable' >\n";
foreach ($aFullResponseTable as $sFieldname=>$fname)
{ {
$sOutput .= "\t<tr class='printanswersquestionhead'><td colspan='2'>{$fname[0]}</td></tr>\n"; if (substr($sFieldname,0,4) == 'gid_')
}
elseif ($sFieldname=='submitdate')
{
if($sAnonymized != 'Y')
{ {
$sOutput .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]} {$sFieldname}</td><td class='printanswersanswertext'>{$fname[2]}</td></tr>"; $sOutput .= "\t<tr class='printanswersgroup'><td colspan='2'>{$fname[0]}</td></tr>\n";
}
elseif ($sFieldname=='submitdate')
{
if($sAnonymized != 'Y')
{
$sOutput .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]} {$sFieldname}</td><td class='printanswersanswertext'>{$fname[2]}</td></tr>";
}
}
elseif (substr($sFieldname,0,4) != 'qid_') // Question text is already in subquestion text, skipping it
{
$sOutput .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]}</td><td class='printanswersanswertext'>".flattenText($fname[2])."</td></tr>";
} }
} }
else $sOutput .= "</table>\n";
{ $sData['thissurvey']=$aSurveyInfo;
$sOutput .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]}</td><td class='printanswersanswertext'>".flattenText($fname[2])."</td></tr>"; $sOutput=templatereplace($sOutput, array() , $sData, '', $aSurveyInfo['anonymized']=="Y",NULL, array(), true);// Do a static replacement
}
}
$sOutput .= "</table>\n";
if($sExportType == 'pdf')
{
$oPDF->writeHTML($sOutput);
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
$sExportFileName = sanitize_filename($sSurveyName);
$oPDF->Output($sExportFileName."-".$iSurveyID.".pdf","D");
}
else//Display the page with user answers
{
ob_start(function($buffer, $phase) { ob_start(function($buffer, $phase) {
App()->getClientScript()->render($buffer); App()->getClientScript()->render($buffer);
App()->getClientScript()->reset(); App()->getClientScript()->reset();
@ -181,7 +155,6 @@
sendCacheHeaders(); sendCacheHeaders();
doHeader(); doHeader();
$sData['thissurvey']=$aSurveyInfo;
echo templatereplace(file_get_contents(getTemplatePath($sTemplate).'/startpage.pstpl'),array(),$sData); echo templatereplace(file_get_contents(getTemplatePath($sTemplate).'/startpage.pstpl'),array(),$sData);
echo templatereplace(file_get_contents(getTemplatePath($sTemplate).'/printanswers.pstpl'),array('ANSWERTABLE'=>$sOutput),$sData); echo templatereplace(file_get_contents(getTemplatePath($sTemplate).'/printanswers.pstpl'),array('ANSWERTABLE'=>$sOutput),$sData);
echo templatereplace(file_get_contents(getTemplatePath($sTemplate).'/endpage.pstpl'),array(),$sData); echo templatereplace(file_get_contents(getTemplatePath($sTemplate).'/endpage.pstpl'),array(),$sData);
@ -189,6 +162,59 @@
ob_flush(); ob_flush();
} }
if($sExportType == 'pdf')
{
// Get images for TCPDF from template directory
define('K_PATH_IMAGES', getTemplatePath($aSurveyInfo['template']).DIRECTORY_SEPARATOR);
Yii::import('application.libraries.admin.pdf', true);
Yii::import('application.helpers.pdfHelper');
$aPdfLanguageSettings=pdfHelper::getPdfLanguageSettings($clang->langcode);
$oPDF = new pdf();
$sDefaultHeaderString = $sSurveyName." (".$clang->gT("ID",'unescaped').":".$iSurveyID.")";
$oPDF->initAnswerPDF($aSurveyInfo, $aPdfLanguageSettings, Yii::app()->getConfig('sitename'), $sSurveyName, $sDefaultHeaderString);
LimeExpressionManager::StartProcessingPage(true); // means that all variables are on the same page
// Since all data are loaded, and don't need JavaScript, pretend all from Group 1
LimeExpressionManager::StartProcessingGroup(1,($aSurveyInfo['anonymized']!="N"),$iSurveyID);
$printanswershonorsconditions = Yii::app()->getConfig('printanswershonorsconditions');
$aFullResponseTable = getFullResponseTable($iSurveyID,$sSRID,$sLanguage,$printanswershonorsconditions);
//Get the fieldmap @TODO: do we need to filter out some fields?
if($aSurveyInfo['datestamp']!="Y" || $sAnonymized == 'Y'){
unset ($aFullResponseTable['submitdate']);
}else{
unset ($aFullResponseTable['id']);
}
unset ($aFullResponseTable['token']);
unset ($aFullResponseTable['lastpage']);
unset ($aFullResponseTable['startlanguage']);
unset ($aFullResponseTable['datestamp']);
unset ($aFullResponseTable['startdate']);
foreach ($aFullResponseTable as $sFieldname=>$fname)
{
if (substr($sFieldname,0,4) == 'gid_')
{
$oPDF->addGidAnswer($fname[0]);
}
elseif ($sFieldname=='submitdate')
{
if($sAnonymized != 'Y')
{
$oPDF->addAnswer($fname[0]." ".$fname[1], $fname[2]);
}
}
elseif (substr($sFieldname,0,4) != 'qid_') // Question text is already in subquestion text, skipping it
{
$oPDF->addAnswer($fname[0]." ".$fname[1], $fname[2]);
}
}
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
$sExportFileName = sanitize_filename($sSurveyName);
$oPDF->Output($sExportFileName."-".$iSurveyID.".pdf","D");
}
LimeExpressionManager::FinishProcessingGroup(); LimeExpressionManager::FinishProcessingGroup();
LimeExpressionManager::FinishProcessingPage(); LimeExpressionManager::FinishProcessingPage();

View file

@ -27,148 +27,131 @@
class Statistics_userController extends LSYii_Controller { class Statistics_userController extends LSYii_Controller {
public function _remap($method, $params = array()) public function _remap($method, $params = array())
{ {
array_unshift($params, $method); array_unshift($params, $method);
return call_user_func_array(array($this, "action"), $params); return call_user_func_array(array($this, "action"), $params);
} }
function actionAction($surveyid,$language) function actionAction($surveyid,$language=null)
{ {
ob_start(function($buffer, $phase) { $sLanguage=$language;
App()->getClientScript()->render($buffer); ob_start(function($buffer, $phase) {
return $buffer; App()->getClientScript()->render($buffer);
}); App()->getClientScript()->reset();
ob_implicit_flush(false); return $buffer;
$iSurveyID=(int)$surveyid; });
ob_implicit_flush(false);
$iSurveyID=(int)$surveyid;
//$postlang = returnglobal('lang'); //$postlang = returnglobal('lang');
Yii::import('application.libraries.admin.progressbar',true); Yii::import('application.libraries.admin.progressbar',true);
Yii::app()->loadHelper("admin/statistics"); Yii::app()->loadHelper("admin/statistics");
Yii::app()->loadHelper('database'); Yii::app()->loadHelper('database');
Yii::app()->loadHelper('surveytranslator'); Yii::app()->loadHelper('surveytranslator');
App()->getClientScript()->registerPackage('jqueryui');
App()->getClientScript()->registerPackage('jquery-touch-punch');
App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts')."survey_runtime.js");
$data = array(); $data = array();
//XXX enable/disable this for testing if(!isset($iSurveyID))
//$publicgraphs = 1; {
//$showaggregateddata = 1; $iSurveyID=returnGlobal('sid');
}
/*
* List of important settings:
* - publicstatistics: General survey setting which determines if public statistics for this survey
* should be shown at all.
*
* - publicgraphs: General survey setting which determines if public statistics for this survey
* should include graphs or only show a tabular overview.
*
* - public_statistics: Question attribute which has to be applied to each question so that
* its statistics will be shown to the user. If not set no statistics for this question will be shown.
*
* - filterout_incomplete_answers: Setting taken from config-defaults.php which determines if
* not completed answers will be filtered.
*/
if(!isset($iSurveyID))
{
$iSurveyID=returnGlobal('sid');
}
else
{
$iSurveyID = (int) $iSurveyID;
}
if (!$iSurveyID)
{
//This next line ensures that the $iSurveyID value is never anything but a number.
safeDie('You have to provide a valid survey ID.');
}
if ($iSurveyID)
{
$actresult = Survey::model()->findAll('sid = :sid AND active = :active', array(':sid' => $iSurveyID, ':active' => 'Y')); //Checked
if (count($actresult) == 0)
{
safeDie('You have to provide a valid survey ID.');
}
else
{
$surveyinfo = getSurveyInfo($iSurveyID);
// CHANGE JSW_NZ - let's get the survey title for display
$thisSurveyTitle = $surveyinfo["name"];
// CHANGE JSW_NZ - let's get css from individual template.css - so define path
$thisSurveyCssPath = getTemplateURL($surveyinfo["template"]);
if ($surveyinfo['publicstatistics']!='Y')
{
safeDie('The public statistics for this survey are deactivated.');
}
//check if graphs should be shown for this survey
if ($surveyinfo['publicgraphs']=='Y')
{
$publicgraphs = 1;
}
else
{
$publicgraphs = 0;
}
}
}
//we collect all the output within this variable
$statisticsoutput ='';
//for creating graphs we need some more scripts which are included here
//True -> include
//False -> forget about charts
if (isset($publicgraphs) && $publicgraphs == 1)
{
require_once(APPPATH.'third_party/pchart/pchart/pChart.class');
require_once(APPPATH.'third_party/pchart/pchart/pData.class');
require_once(APPPATH.'third_party/pchart/pchart/pCache.class');
$MyCache = new pCache(Yii::app()->getConfig("tempdir").DIRECTORY_SEPARATOR);
//$currentuser is created as prefix for pchart files
if (isset($_SERVER['REDIRECT_REMOTE_USER']))
{
$currentuser=$_SERVER['REDIRECT_REMOTE_USER'];
}
else if (session_id())
{
$currentuser=substr(session_id(), 0, 15);
}
else
{
$currentuser="standard";
}
}
// Set language for questions and labels to base language of this survey
if (isset($postlang) && $postlang != null )
$language = $postlang;
else else
$language = Survey::model()->findByPk($iSurveyID)->language; {
$iSurveyID = (int) $iSurveyID;
}
if (!$iSurveyID)
{
//This next line ensures that the $iSurveyID value is never anything but a number.
safeDie('You have to provide a valid survey ID.');
}
//set survey language for translations if ($iSurveyID)
$clang = SetSurveyLanguage($iSurveyID, $language); {
$actresult = Survey::model()->findAll('sid = :sid AND active = :active', array(':sid' => $iSurveyID, ':active' => 'Y')); //Checked
if (count($actresult) == 0)
{
safeDie('You have to provide a valid survey ID.');
}
else
{
$surveyinfo = getSurveyInfo($iSurveyID);
// CHANGE JSW_NZ - let's get the survey title for display
$thisSurveyTitle = $surveyinfo["name"];
// CHANGE JSW_NZ - let's get css from individual template.css - so define path
$thisSurveyCssPath = getTemplateURL($surveyinfo["template"]);
if ($surveyinfo['publicstatistics']!='Y')
{
safeDie('The public statistics for this survey are deactivated.');
}
//check if graphs should be shown for this survey
if ($surveyinfo['publicgraphs']=='Y')
{
$publicgraphs = 1;
}
else
{
$publicgraphs = 0;
}
}
}
//we collect all the output within this variable
$statisticsoutput ='';
//Create header (fixes bug #3097) //for creating graphs we need some more scripts which are included here
$surveylanguage= $language; //True -> include
sendCacheHeaders(); //False -> forget about charts
$condition = false; if (isset($publicgraphs) && $publicgraphs == 1)
$sitename = Yii::app()->getConfig("sitename"); {
require_once(APPPATH.'third_party/pchart/pchart/pChart.class');
require_once(APPPATH.'third_party/pchart/pchart/pData.class');
require_once(APPPATH.'third_party/pchart/pchart/pCache.class');
$data['surveylanguage'] = $surveylanguage; $MyCache = new pCache(Yii::app()->getConfig("tempdir").DIRECTORY_SEPARATOR);
$data['sitename'] = $sitename; //$currentuser is created as prefix for pchart files
$data['condition'] = $condition; if (isset($_SERVER['REDIRECT_REMOTE_USER']))
$data['thisSurveyCssPath'] = $thisSurveyCssPath; {
$currentuser=$_SERVER['REDIRECT_REMOTE_USER'];
}
else if (session_id())
{
$currentuser=substr(session_id(), 0, 15);
}
else
{
$currentuser="standard";
}
}
// Set language for questions and labels to base language of this survey
if ($sLanguage== null || !in_array($sLanguage,Survey::model()->findByPk($iSurveyID)->getAllLanguages()))
{
$sLanguage = Survey::model()->findByPk($iSurveyID)->language;
}
else
{
$sLanguage=sanitize_languagecode($sLanguage);
}
//set survey language for translations
$clang = SetSurveyLanguage($iSurveyID, $sLanguage);
//Create header
sendCacheHeaders();
$condition = false;
$sitename = Yii::app()->getConfig("sitename");
/* $data['surveylanguage'] = $sLanguage;
* only show questions where question attribute "public_statistics" is set to "1" $data['sitename'] = $sitename;
*/ $data['condition'] = $condition;
$data['thisSurveyCssPath'] = $thisSurveyCssPath;
/*
* only show questions where question attribute "public_statistics" is set to "1"
*/
$query = "SELECT q.* , group_name, group_order FROM {{questions}} q, {{groups}} g, {{question_attributes}} qa $query = "SELECT q.* , group_name, group_order FROM {{questions}} q, {{groups}} g, {{question_attributes}} qa
WHERE g.gid = q.gid AND g.language = :lang1 AND q.language = :lang2 AND q.sid = :surveyid AND q.qid = qa.qid AND q.parent_qid = 0 AND qa.attribute = 'public_statistics'"; WHERE g.gid = q.gid AND g.language = :lang1 AND q.language = :lang2 AND q.sid = :surveyid AND q.qid = qa.qid AND q.parent_qid = 0 AND qa.attribute = 'public_statistics'";
@ -182,185 +165,185 @@ class Statistics_userController extends LSYii_Controller {
$query .=" AND qa.value='1'\n"; $query .=" AND qa.value='1'\n";
} }
//execute query //execute query
$result = Yii::app()->db->createCommand($query)->bindParam(":lang1", $language, PDO::PARAM_STR)->bindParam(":lang2", $language, PDO::PARAM_STR)->bindParam(":surveyid", $iSurveyID, PDO::PARAM_INT)->queryAll(); $result = Yii::app()->db->createCommand($query)->bindParam(":lang1", $sLanguage, PDO::PARAM_STR)->bindParam(":lang2", $sLanguage, PDO::PARAM_STR)->bindParam(":surveyid", $iSurveyID, PDO::PARAM_INT)->queryAll();
//store all the data in $rows //store all the data in $rows
$rows = $result; $rows = $result;
//SORT IN NATURAL ORDER! //SORT IN NATURAL ORDER!
usort($rows, 'groupOrderThenQuestionOrder'); usort($rows, 'groupOrderThenQuestionOrder');
//put the question information into the filter array //put the question information into the filter array
foreach ($rows as $row) foreach ($rows as $row)
{ {
//store some column names in $filters array //store some column names in $filters array
$filters[]=array($row['qid'], $filters[]=array($row['qid'],
$row['gid'], $row['gid'],
$row['type'], $row['type'],
$row['title'], $row['title'],
$row['group_name'], $row['group_name'],
flattenText($row['question'])); flattenText($row['question']));
} }
//number of records for this survey //number of records for this survey
$totalrecords = 0; $totalrecords = 0;
//count number of answers //count number of answers
$query = "SELECT count(*) FROM {{survey_".intval($iSurveyID)."}}"; $query = "SELECT count(*) FROM {{survey_".intval($iSurveyID)."}}";
//if incompleted answers should be filtert submitdate has to be not null //if incompleted answers should be filtert submitdate has to be not null
//this setting is taken from config-defaults.php //this setting is taken from config-defaults.php
if (Yii::app()->getConfig("filterout_incomplete_answers") == true) if (Yii::app()->getConfig("filterout_incomplete_answers") == true)
{ {
$query .= " WHERE {{survey_".intval($iSurveyID)."}}.submitdate is not null"; $query .= " WHERE {{survey_".intval($iSurveyID)."}}.submitdate is not null";
} }
$result = Yii::app()->db->createCommand($query)->queryAll(); $result = Yii::app()->db->createCommand($query)->queryAll();
//$totalrecords = total number of answers //$totalrecords = total number of answers
foreach($result as $row) foreach($result as $row)
{ {
$totalrecords = reset($row); $totalrecords = reset($row);
} }
//this is the array which we need later... //this is the array which we need later...
$summary = array(); $summary = array();
//...while this is the array from copy/paste which we don't want to replace because this is a nasty source of error //...while this is the array from copy/paste which we don't want to replace because this is a nasty source of error
$allfields = array(); $allfields = array();
//---------- CREATE SGQA OF ALL QUESTIONS WHICH USE "PUBLIC_STATISTICS" ---------- //---------- CREATE SGQA OF ALL QUESTIONS WHICH USE "PUBLIC_STATISTICS" ----------
/* /*
* let's go through the filter array which contains * let's go through the filter array which contains
* ['qid'], * ['qid'],
['gid'], ['gid'],
['type'], ['type'],
['title'], ['title'],
['group_name'], ['group_name'],
['question']; ['question'];
*/ */
$currentgroup=''; $currentgroup='';
// use to check if there are any question with public statistics // use to check if there are any question with public statistics
if(isset($filters)){ if(isset($filters)){
foreach ($filters as $flt) foreach ($filters as $flt)
{ {
//SGQ identifier //SGQ identifier
$myfield = "{$iSurveyID}X{$flt[1]}X{$flt[0]}"; $myfield = "{$iSurveyID}X{$flt[1]}X{$flt[0]}";
//let's switch through the question type for each question //let's switch through the question type for each question
switch ($flt[2]) switch ($flt[2])
{ {
case "K": // Multiple Numerical case "K": // Multiple Numerical
case "Q": // Multiple Short Text case "Q": // Multiple Short Text
//get answers //get answers
$query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order"; $query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $language, PDO::PARAM_STR)->queryAll(); $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll();
//go through all the (multiple) answers //go through all the (multiple) answers
foreach($result as $row) foreach($result as $row)
{ {
$myfield2=$flt[2].$myfield.reset($row); $myfield2=$flt[2].$myfield.reset($row);
$allfields[] = $myfield2; $allfields[] = $myfield2;
} }
break; break;
case "A": // ARRAY OF 5 POINT CHOICE QUESTIONS case "A": // ARRAY OF 5 POINT CHOICE QUESTIONS
case "B": // ARRAY OF 10 POINT CHOICE QUESTIONS case "B": // ARRAY OF 10 POINT CHOICE QUESTIONS
case "C": // ARRAY OF YES\No\$clang->gT("Uncertain") QUESTIONS case "C": // ARRAY OF YES\No\$clang->gT("Uncertain") QUESTIONS
case "E": // ARRAY OF Increase/Same/Decrease QUESTIONS case "E": // ARRAY OF Increase/Same/Decrease QUESTIONS
case "F": // FlEXIBLE ARRAY case "F": // FlEXIBLE ARRAY
case "H": // ARRAY (By Column) case "H": // ARRAY (By Column)
//get answers //get answers
$query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order"; $query = "SELECT title as code, question as answer FROM {{questions}} WHERE parent_qid=:flt_0 AND language = :lang ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $language, PDO::PARAM_STR)->queryAll(); $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll();
//go through all the (multiple) answers //go through all the (multiple) answers
foreach($result as $row) foreach($result as $row)
{ {
$myfield2 = $myfield.reset($row); $myfield2 = $myfield.reset($row);
$allfields[]=$myfield2; $allfields[]=$myfield2;
} }
break; break;
// all "free text" types (T, U, S) get the same prefix ("T") // all "free text" types (T, U, S) get the same prefix ("T")
case "T": // Long free text case "T": // Long free text
case "U": // Huge free text case "U": // Huge free text
case "S": // Short free text case "S": // Short free text
$myfield="T$myfield"; $myfield="T$myfield";
$allfields[] = $myfield; $allfields[] = $myfield;
break; break;
case ";": //ARRAY (Multi Flex) (Text) case ";": //ARRAY (Multi Flex) (Text)
case ":": //ARRAY (Multi Flex) (Numbers) case ":": //ARRAY (Multi Flex) (Numbers)
$query = "SELECT title, question FROM {{questions}} WHERE parent_qid=:flt_0 AND language=:lang AND scale_id = 0 ORDER BY question_order"; $query = "SELECT title, question FROM {{questions}} WHERE parent_qid=:flt_0 AND language=:lang AND scale_id = 0 ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $language, PDO::PARAM_STR)->queryAll(); $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll();
foreach($result as $row) foreach($result as $row)
{ {
$fquery = "SELECT * FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang AND scale_id = 1 ORDER BY question_order, title"; $fquery = "SELECT * FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang AND scale_id = 1 ORDER BY question_order, title";
$fresult = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $language, PDO::PARAM_STR)->queryAll(); $fresult = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll();
foreach($fresult as $frow) foreach($fresult as $frow)
{ {
$myfield2 = $myfield . reset($row) . "_" . $frow['title']; $myfield2 = $myfield . reset($row) . "_" . $frow['title'];
$allfields[]=$myfield2; $allfields[]=$myfield2;
} }
} }
break; break;
case "R": //RANKING case "R": //RANKING
//get some answers //get some answers
$query = "SELECT code, answer FROM {{answers}} WHERE qid = :flt_0 AND language = :lang ORDER BY sortorder, answer"; $query = "SELECT code, answer FROM {{answers}} WHERE qid = :flt_0 AND language = :lang ORDER BY sortorder, answer";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $language, PDO::PARAM_STR)->queryAll(); $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll();
//get number of answers //get number of answers
$count = count($result); $count = count($result);
//loop through all answers. if there are 3 items to rate there will be 3 statistics //loop through all answers. if there are 3 items to rate there will be 3 statistics
for ($i=1; $i<=$count; $i++) for ($i=1; $i<=$count; $i++)
{ {
$myfield2 = "R" . $myfield . $i . "-" . strlen($i); $myfield2 = "R" . $myfield . $i . "-" . strlen($i);
$allfields[]=$myfield2; $allfields[]=$myfield2;
} }
break; break;
//Boilerplate questions are only used to put some text between other questions -> no analysis needed //Boilerplate questions are only used to put some text between other questions -> no analysis needed
case "X": //This is a boilerplate question and it has no business in this script case "X": //This is a boilerplate question and it has no business in this script
break; break;
case "1": // MULTI SCALE case "1": // MULTI SCALE
//get answers //get answers
$query = "SELECT title, question FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang ORDER BY question_order"; $query = "SELECT title, question FROM {{questions}} WHERE parent_qid = :flt_0 AND language = :lang ORDER BY question_order";
$result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $language, PDO::PARAM_STR)->queryAll(); $result = Yii::app()->db->createCommand($query)->bindParam(":flt_0", $flt[0], PDO::PARAM_INT)->bindParam(":lang", $sLanguage, PDO::PARAM_STR)->queryAll();
//loop through answers //loop through answers
foreach($result as $row) foreach($result as $row)
{ {
//----------------- LABEL 1 --------------------- //----------------- LABEL 1 ---------------------
$myfield2 = $myfield . $row['title']."#0"; $myfield2 = $myfield . $row['title']."#0";
$allfields[]=$myfield2; $allfields[]=$myfield2;
//----------------- LABEL 2 --------------------- //----------------- LABEL 2 ---------------------
$myfield2 = $myfield . $row['title']."#1"; $myfield2 = $myfield . $row['title']."#1";
$allfields[]=$myfield2; $allfields[]=$myfield2;
} //end WHILE -> loop through all answers } //end WHILE -> loop through all answers
break; break;
case "P": //P - Multiple choice with comments case "P": //P - Multiple choice with comments
case "M": //M - Multiple choice case "M": //M - Multiple choice
case "N": //N - Numerical input case "N": //N - Numerical input
case "D": //D - Date case "D": //D - Date
$myfield2 = $flt[2].$myfield; $myfield2 = $flt[2].$myfield;
$allfields[]=$myfield2; $allfields[]=$myfield2;
break; break;
default: //Default settings default: //Default settings
$allfields[] = $myfield; $allfields[] = $myfield;
break; break;
} //end switch -> check question types and create filter forms } //end switch -> check question types and create filter forms
} }
//end foreach -> loop through all questions with "public_statistics" enabled //end foreach -> loop through all questions with "public_statistics" enabled
}// end if -> for removing the error message in case there are no filters }// end if -> for removing the error message in case there are no filters
$summary = $allfields; $summary = $allfields;
// Get the survey inforamtion // Get the survey inforamtion
$thissurvey = getSurveyInfo($surveyid,$language); $thissurvey = getSurveyInfo($surveyid,$sLanguage);
//SET THE TEMPLATE DIRECTORY //SET THE TEMPLATE DIRECTORY
if (!isset($thissurvey['templatedir']) || !$thissurvey['templatedir']) if (!isset($thissurvey['templatedir']) || !$thissurvey['templatedir'])
@ -373,96 +356,96 @@ class Statistics_userController extends LSYii_Controller {
} }
//---------- CREATE STATISTICS ---------- //---------- CREATE STATISTICS ----------
$redata = compact(array_keys(get_defined_vars())); $redata = compact(array_keys(get_defined_vars()));
doHeader(); doHeader();
echo templatereplace(file_get_contents(getTemplatePath(validateTemplateDir($data['sTemplatePath'])).DIRECTORY_SEPARATOR."startpage.pstpl"),array(), $redata); echo templatereplace(file_get_contents(getTemplatePath(validateTemplateDir($data['sTemplatePath'])).DIRECTORY_SEPARATOR."startpage.pstpl"),array(), $redata);
//some progress bar stuff //some progress bar stuff
// Create progress bar which is shown while creating the results // Create progress bar which is shown while creating the results
$prb = new ProgressBar(); $prb = new ProgressBar();
$prb->pedding = 2; // Bar Pedding $prb->pedding = 2; // Bar Pedding
$prb->brd_color = "#404040 #dfdfdf #dfdfdf #404040"; // Bar Border Color $prb->brd_color = "#404040 #dfdfdf #dfdfdf #404040"; // Bar Border Color
$prb->setFrame(); // set ProgressBar Frame $prb->setFrame(); // set ProgressBar Frame
$prb->frame['left'] = 50; // Frame position from left $prb->frame['left'] = 50; // Frame position from left
$prb->frame['top'] = 80; // Frame position from top $prb->frame['top'] = 80; // Frame position from top
$prb->addLabel('text','txt1',$clang->gT("Please wait ...")); // add Text as Label 'txt1' and value 'Please wait' $prb->addLabel('text','txt1',$clang->gT("Please wait ...")); // add Text as Label 'txt1' and value 'Please wait'
$prb->addLabel('percent','pct1'); // add Percent as Label 'pct1' $prb->addLabel('percent','pct1'); // add Percent as Label 'pct1'
$prb->addButton('btn1',$clang->gT('Go back'),'?action=statistics&amp;sid='.$iSurveyID); // add Button as Label 'btn1' and action '?restart=1' $prb->addButton('btn1',$clang->gT('Go back'),'?action=statistics&amp;sid='.$iSurveyID); // add Button as Label 'btn1' and action '?restart=1'
//progress bar starts with 35% //progress bar starts with 35%
$process_status = 35; $process_status = 35;
$prb->show(); // show the ProgressBar $prb->show(); // show the ProgressBar
// 1: Get list of questions with answers chosen // 1: Get list of questions with answers chosen
//"Getting Questions and Answer ..." is shown above the bar //"Getting Questions and Answer ..." is shown above the bar
$prb->setLabelValue('txt1',$clang->gT('Getting questions and answers ...')); $prb->setLabelValue('txt1',$clang->gT('Getting questions and answers ...'));
$prb->moveStep(5); $prb->moveStep(5);
// creates array of post variable names // creates array of post variable names
for (reset($_POST); $key=key($_POST); next($_POST)) for (reset($_POST); $key=key($_POST); next($_POST))
{ {
$postvars[]=$key; $postvars[]=$key;
} }
$data['thisSurveyTitle'] = $thisSurveyTitle; $data['thisSurveyTitle'] = $thisSurveyTitle;
$data['totalrecords'] = $totalrecords; $data['totalrecords'] = $totalrecords;
$data['clang'] = $clang; $data['clang'] = $clang;
$data['summary'] = $summary; $data['summary'] = $summary;
//show some main data at the beginnung //show some main data at the beginnung
// CHANGE JSW_NZ - let's allow html formatted questions to show // CHANGE JSW_NZ - let's allow html formatted questions to show
//push progress bar from 35 to 40 //push progress bar from 35 to 40
$process_status = 40; $process_status = 40;
//Show Summary results //Show Summary results
if (isset($summary) && $summary) if (isset($summary) && $summary)
{ {
//"Generating Summaries ..." is shown above the progress bar //"Generating Summaries ..." is shown above the progress bar
$prb->setLabelValue('txt1',$clang->gT('Generating summaries ...')); $prb->setLabelValue('txt1',$clang->gT('Generating summaries ...'));
$prb->moveStep($process_status); $prb->moveStep($process_status);
//let's run through the survey // Fixed bug 3053 with array_unique //let's run through the survey // Fixed bug 3053 with array_unique
$runthrough=array_unique($summary); $runthrough=array_unique($summary);
//loop through all selected questions //loop through all selected questions
foreach ($runthrough as $rt) foreach ($runthrough as $rt)
{ {
//update progress bar //update progress bar
if ($process_status < 100) $process_status++; if ($process_status < 100) $process_status++;
$prb->moveStep($process_status); $prb->moveStep($process_status);
} // end foreach -> loop through all questions } // end foreach -> loop through all questions
$helper = new statistics_helper(); $helper = new statistics_helper();
$statisticsoutput .= $helper->generate_statistics($iSurveyID, $summary, $summary, $publicgraphs, 'html', null,$language,false); $statisticsoutput .= $helper->generate_statistics($iSurveyID, $summary, $summary, $publicgraphs, 'html', null,$sLanguage,false);
} //end if -> show summary results } //end if -> show summary results
$data['statisticsoutput']=$statisticsoutput; $data['statisticsoutput']=$statisticsoutput;
//done! set progress bar to 100% //done! set progress bar to 100%
if (isset($prb)) if (isset($prb))
{ {
$prb->setLabelValue('txt1',$clang->gT('Completed')); $prb->setLabelValue('txt1',$clang->gT('Completed'));
$prb->moveStep(100); $prb->moveStep(100);
$prb->hide(); $prb->hide();
} }
$redata = compact(array_keys(get_defined_vars())); $redata = compact(array_keys(get_defined_vars()));
$data['redata'] = $redata; $data['redata'] = $redata;
Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts') . 'statistics_user.js'); Yii::app()->getClientScript()->registerScriptFile(Yii::app()->getConfig('generalscripts') . 'statistics_user.js');
$this->renderPartial('/statistics_user_view',$data); $this->renderPartial('/statistics_user_view',$data);
//output footer //output footer
echo getFooter(); echo getFooter();
//Delete all Session Data //Delete all Session Data
Yii::app()->session['finished'] = true; Yii::app()->session['finished'] = true;
} }
} }

View file

@ -46,8 +46,8 @@ class UploaderController extends SurveyController {
// Validate and filter and throw error if problems // Validate and filter and throw error if problems
// Using 'futmp_'.randomChars(15).'_'.$pathinfo['extension'] for filename, then remove all other characters // Using 'futmp_'.randomChars(15).'_'.$pathinfo['extension'] for filename, then remove all other characters
$sFileGetContentFiltered=preg_replace('/[^a-z0-9_]/', '', $sFileGetContent); $sFileGetContentFiltered=preg_replace('/[^a-zA-Z0-9_]/', '', $sFileGetContent);
$sFileNameFiltered = preg_replace('/[^a-z0-9_]/', '',$sFileName); $sFileNameFiltered = preg_replace('/[^a-zA-Z0-9_]/', '',$sFileName);
$sFieldNameFiltered=preg_replace('/[^X0-9]/', '', $sFieldName); $sFieldNameFiltered=preg_replace('/[^X0-9]/', '', $sFieldName);
if($sFileGetContent!=$sFileGetContentFiltered || $sFileName!=$sFileNameFiltered || $sFieldName!=$sFieldNameFiltered) if($sFileGetContent!=$sFileGetContentFiltered || $sFileName!=$sFileNameFiltered || $sFieldName!=$sFieldNameFiltered)
{// If one seems to be a hack: Bad request {// If one seems to be a hack: Bad request

View file

@ -79,15 +79,23 @@ class Authentication extends Survey_Common_Action
// Now authenticate // Now authenticate
if ($identity->authenticate()) if ($identity->authenticate())
{ {
FailedLoginAttempt::model()->deleteAttempts(); FailedLoginAttempt::model()->deleteAttempts();
App()->user->setState('plugin', $authMethod); App()->user->setState('plugin', $authMethod);
$this->getController()->_GetSessionUserRights(Yii::app()->session['loginID']); $this->getController()->_GetSessionUserRights(Yii::app()->session['loginID']);
Yii::app()->session['just_logged_in'] = true; Yii::app()->session['just_logged_in'] = true;
Yii::app()->session['loginsummary'] = $this->_getSummary(); Yii::app()->session['loginsummary'] = $this->_getSummary();
$event = new PluginEvent('afterSuccessfulLogin');
App()->getPluginManager()->dispatchEvent($event);
$this->_doRedirect(); $this->_doRedirect();
} else { } else {
// Failed // Failed
$event = new PluginEvent('afterFailedLoginAttempt');
$event->set('identity', $identity);
App()->getPluginManager()->dispatchEvent($event);
$message = $identity->errorMessage; $message = $identity->errorMessage;
if (empty($message)) { if (empty($message)) {
// If no message, return a default message // If no message, return a default message
@ -105,19 +113,16 @@ class Authentication extends Survey_Common_Action
*/ */
public function logout() public function logout()
{ {
// Fetch the current user
$plugin = App()->user->getState('plugin', null); // Save for afterLogout, current user will be destroyed by then
/* Adding beforeLogout event */ /* Adding beforeLogout event */
$beforeLogout = new PluginEvent('beforeLogout'); $beforeLogout = new PluginEvent('beforeLogout');
App()->getPluginManager()->dispatchEvent($beforeLogout, array($plugin)); App()->getPluginManager()->dispatchEvent($beforeLogout);
App()->user->logout(); App()->user->logout();
App()->user->setFlash('loginmessage', gT('Logout successful.')); App()->user->setFlash('loginmessage', gT('Logout successful.'));
/* Adding afterLogout event */ /* Adding afterLogout event */
$event = new PluginEvent('afterLogout'); $event = new PluginEvent('afterLogout');
App()->getPluginManager()->dispatchEvent($event, array($plugin)); App()->getPluginManager()->dispatchEvent($event);
$this->getController()->redirect(array('/admin/authentication/sa/login')); $this->getController()->redirect(array('/admin/authentication/sa/login'));
} }
@ -140,18 +145,19 @@ class Authentication extends Survey_Common_Action
$aFields = User::model()->findAllByAttributes(array('users_name' => $sUserName, 'email' => $sEmailAddr)); $aFields = User::model()->findAllByAttributes(array('users_name' => $sUserName, 'email' => $sEmailAddr));
// Preventing attacker from easily knowing whether the user and email address are valid or not (and slowing down brute force attacks)
usleep(rand(Yii::app()->getConfig("minforgottenpasswordemaildelay"),Yii::app()->getConfig("maxforgottenpasswordemaildelay")));
if (count($aFields) < 1) if (count($aFields) < 1)
{ {
// wrong or unknown username and/or email // wrong or unknown username and/or email
$aData['errormsg'] = $this->getController()->lang->gT('User name and/or email not found!'); $aData['message'] = '<br>'.gT('If username and email that you specified are valid, a new password has been sent to you').'<br>';
$aData['maxattempts'] = '';
$this->_renderWrappedTemplate('authentication', 'error', $aData);
} }
else else
{ {
$aData['message'] = $this->_sendPasswordEmail($sEmailAddr, $aFields); $aData['message'] = '<br>'.$this->_sendPasswordEmail($sEmailAddr, $aFields).'</br>';
$this->_renderWrappedTemplate('authentication', 'message', $aData);
} }
$this->_renderWrappedTemplate('authentication', 'message', $aData);
} }
} }
@ -184,12 +190,11 @@ class Authentication extends Survey_Common_Action
if (SendEmailMessage($body, $sSubject, $sTo, $sFrom, $sSiteName, false, $sSiteAdminBounce)) if (SendEmailMessage($body, $sSubject, $sTo, $sFrom, $sSiteName, false, $sSiteAdminBounce))
{ {
User::model()->updatePassword($aFields[0]['uid'], $sNewPass); User::model()->updatePassword($aFields[0]['uid'], $sNewPass);
$sMessage = $username . '<br />' . $email . '<br /><br />' . $clang->gT('An email with your login data was sent to you.'); $sMessage = gT('If username and email that you specified are valid, a new password has been sent to you');
} }
else else
{ {
$sTmp = str_replace("{NAME}", '<strong>' . $aFields[0]['users_name'] . '</strong>', $clang->gT("Email to {NAME} ({EMAIL}) failed.")); $sMessage = gT("Email failed.");
$sMessage = str_replace("{EMAIL}", $sEmailAddr, $sTmp) . '<br />';
} }
return $sMessage; return $sMessage;

View file

@ -237,23 +237,15 @@ class CheckIntegrity extends Survey_Common_Action
private function _deleteQuotaMembers(array $aData, Limesurvey_lang $clang) private function _deleteQuotaMembers(array $aData, Limesurvey_lang $clang)
{ {
$quota_ids = array(); $oCriteria = new CDbCriteria;
$quotas = Quota::model()->findAll(); $oCriteria->join = 'LEFT JOIN {{questions}} q ON t.qid=q.qid LEFT JOIN {{surveys}} s ON t.sid=s.sid';
foreach ($quotas as $quota) $quota_ids[] = $quota['id']; $oCriteria->condition = '(q.qid IS NULL) OR (s.sid IS NULL)';
$criteria = new CDbCriteria;
$criteria->addNotInCondition('quota_id', $quota_ids);
$qids = array(); $aRecords=QuotaMember::model()->findAll($oCriteria);
$questions = Question::model()->findAll(); foreach ($aRecords as $aRecord)
foreach ($questions as $question) $qids[] = $question['qid']; {
$criteria->addNotInCondition('qid', $qids, 'OR'); QuotaMember::model()->deleteAllByAttributes($aRecord);
}
$sids = array();
$surveys = Survey::model()->findAll();
foreach ($surveys as $survey) $sids[] = $survey['sid'];
$criteria->addNotInCondition('sid', $sids, 'OR');
QuotaMember::model()->deleteAll($criteria);
if (QuotaLanguageSetting::model()->hasErrors()) safeDie(QuotaLanguageSetting::model()->getError()); if (QuotaLanguageSetting::model()->hasErrors()) safeDie(QuotaLanguageSetting::model()->getError());
$aData['messages'][] = $clang->gT('Deleting orphaned quota members.'); $aData['messages'][] = $clang->gT('Deleting orphaned quota members.');
return $aData; return $aData;
@ -286,14 +278,15 @@ class CheckIntegrity extends Survey_Common_Action
private function _deleteDefaultValues(array $aData, Limesurvey_lang $clang) private function _deleteDefaultValues(array $aData, Limesurvey_lang $clang)
{ {
$qids = array();
$questions = Question::model()->findAll();
foreach ($questions as $question) $qids[] = $question['qid'];
$criteria = new CDbCriteria; $criteria = new CDbCriteria;
$criteria->addNotInCondition('qid', $qids); $criteria->join = 'LEFT JOIN {{questions}} q ON t.qid=q.qid';
$criteria->condition = 'q.qid IS NULL';
DefaultValue::model()->deleteAll($criteria); $aRecords=DefaultValue::model()->findAll($criteria);
if (DefaultValue::model()->hasErrors()) safeDie(DefaultValue::model()->getError()); foreach ($aRecords as $aRecord)
{
DefaultValue::model()->deleteAllByAttributes($aRecord);
}
$aData['messages'][] = $clang->gT('Deleting orphaned default values.'); $aData['messages'][] = $clang->gT('Deleting orphaned default values.');
return $aData; return $aData;
} }
@ -336,16 +329,16 @@ class CheckIntegrity extends Survey_Common_Action
$users = User::model()->findAll(); $users = User::model()->findAll();
$uids = array(); $uids = array();
foreach ($users as $user) $uids[] = $user['uid']; foreach ($users as $user) $uids[] = $user['uid'];
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->addNotInCondition('uid', $uids, 'OR'); $oCriteria->addNotInCondition('uid', $uids, 'OR');
$surveys = Survey::model()->findAll(); $surveys = Survey::model()->findAll();
$sids = array(); $sids = array();
foreach ($surveys as $survey) $sids[] = $survey['sid']; foreach ($surveys as $survey) $sids[] = $survey['sid'];
$criteria->addNotInCondition('entity_id', $sids, 'OR'); $oCriteria->addNotInCondition('entity_id', $sids, 'OR');
$criteria->addCondition("entity='survey'"); $oCriteria->addCondition("entity='survey'");
Permission::model()->deleteAll($criteria); Permission::model()->deleteAll($oCriteria);
// Deactivate surveys that have a missing response table // Deactivate surveys that have a missing response table
@ -356,6 +349,7 @@ class CheckIntegrity extends Survey_Common_Action
Survey::model()->updateByPk($survey['sid'],array('active'=>'N')); Survey::model()->updateByPk($survey['sid'],array('active'=>'N'));
} }
} }
unset($surveys);
@ -365,7 +359,7 @@ class CheckIntegrity extends Survey_Common_Action
/*** Check for active survey tables with missing survey entry and rename them ***/ /*** Check for active survey tables with missing survey entry and rename them ***/
$sDBPrefix = Yii::app()->db->tablePrefix; $sDBPrefix = Yii::app()->db->tablePrefix;
$sQuery = dbSelectTablesLike('{{survey}}\_%'); $sQuery = dbSelectTablesLike('{{survey}}\_%');
$aResult = dbQueryOrFalse($sQuery) or safeDie("Couldn't get list of conditions from database<br />{$sQuery}<br />"); $aResult = dbQueryOrFalse($sQuery);
foreach ($aResult->readAll() as $aRow) foreach ($aResult->readAll() as $aRow)
{ {
$sTableName = substr(reset($aRow), strlen($sDBPrefix)); $sTableName = substr(reset($aRow), strlen($sDBPrefix));
@ -388,7 +382,7 @@ class CheckIntegrity extends Survey_Common_Action
} }
/*** Check for active token tables with missing survey entry ***/ /*** Check for active token tables with missing survey entry ***/
$aResult = dbQueryOrFalse(dbSelectTablesLike('{{tokens}}\_%')) or safeDie("Couldn't get list of conditions from database<br />{$sQuery}<br />"); $aResult = dbQueryOrFalse(dbSelectTablesLike('{{tokens}}\_%'));
foreach ($aResult->readAll() as $aRow) foreach ($aResult->readAll() as $aRow)
{ {
$sTableName = substr(reset($aRow), strlen($sDBPrefix)); $sTableName = substr(reset($aRow), strlen($sDBPrefix));
@ -408,11 +402,10 @@ class CheckIntegrity extends Survey_Common_Action
/**********************************************************************/ /**********************************************************************/
/* Check conditions */ /* Check conditions */
/**********************************************************************/ /**********************************************************************/
// TMSW Condition->Relevance: Replace this with analysis of relevance
$conditions = Condition::model()->findAll();
if (Condition::model()->hasErrors()) safeDie(Condition::model()->getError());
$okQuestion = array(); $okQuestion = array();
foreach ($conditions as $condition) $sQuery = 'SELECT cqid,cid,cfieldname FROM {{conditions}}';
$aConditions = Yii::app()->db->createCommand($sQuery)->queryAll();
foreach ($aConditions as $condition)
{ {
if ($condition['cqid'] != 0) { // skip case with cqid=0 for codnitions on {TOKEN:EMAIL} for instance if ($condition['cqid'] != 0) { // skip case with cqid=0 for codnitions on {TOKEN:EMAIL} for instance
if (!array_key_exists($condition['cqid'], $okQuestion)) { if (!array_key_exists($condition['cqid'], $okQuestion)) {
@ -439,7 +432,8 @@ class CheckIntegrity extends Survey_Common_Action
$aDelete['conditions'][] = array('cid' => $condition['cid'], 'reason' => $clang->gT('No CFIELDNAME field set!') . " ({$condition['cfieldname']})"); $aDelete['conditions'][] = array('cid' => $condition['cid'], 'reason' => $clang->gT('No CFIELDNAME field set!') . " ({$condition['cfieldname']})");
} }
} }
unset($okQuestion);
unset($aConditions);
/**********************************************************************/ /**********************************************************************/
/* Check question attributes */ /* Check question attributes */
/**********************************************************************/ /**********************************************************************/
@ -454,14 +448,11 @@ class CheckIntegrity extends Survey_Common_Action
/**********************************************************************/ /**********************************************************************/
/* Check default values */ /* Check default values */
/**********************************************************************/ /**********************************************************************/
$questions = Question::model()->findAll(); $oCriteria = new CDbCriteria;
if (Question::model()->hasErrors()) safeDie(Question::model()->getError()); $oCriteria->join = 'LEFT JOIN {{questions}} q ON t.qid=q.qid';
$qids = array(); $oCriteria->condition = 'q.qid IS NULL';
foreach ($questions as $question) $qids[] = $question['qid']; $aRecords=DefaultValue::model()->findAll($oCriteria);
$criteria = new CDbCriteria; $aDelete['defaultvalues'] = count($aRecords);
$criteria->addNotInCondition('qid', $qids);
$aDelete['defaultvalues'] = count(DefaultValue::model()->findAll($criteria));
if (DefaultValue::model()->hasErrors()) safeDie(DefaultValue::model()->getError()); if (DefaultValue::model()->hasErrors()) safeDie(DefaultValue::model()->getError());
/**********************************************************************/ /**********************************************************************/
@ -471,10 +462,10 @@ class CheckIntegrity extends Survey_Common_Action
if (Survey::model()->hasErrors()) safeDie(Survey::model()->getError()); if (Survey::model()->hasErrors()) safeDie(Survey::model()->getError());
$sids = array(); $sids = array();
foreach ($surveys as $survey) $sids[] = $survey['sid']; foreach ($surveys as $survey) $sids[] = $survey['sid'];
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->addNotInCondition('sid', $sids); $oCriteria->addNotInCondition('sid', $sids);
$aDelete['quotas'] = count(Quota::model()->findAll($criteria)); $aDelete['quotas'] = count(Quota::model()->findAll($oCriteria));
if (Quota::model()->hasErrors()) safeDie(Quota::model()->getError()); if (Quota::model()->hasErrors()) safeDie(Quota::model()->getError());
/**********************************************************************/ /**********************************************************************/
@ -484,40 +475,28 @@ class CheckIntegrity extends Survey_Common_Action
if (Quota::model()->hasErrors()) safeDie(Quota::model()->getError()); if (Quota::model()->hasErrors()) safeDie(Quota::model()->getError());
$ids = array(); $ids = array();
foreach ($quotas as $quota) $ids[] = $quota['id']; foreach ($quotas as $quota) $ids[] = $quota['id'];
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->addNotInCondition('quotals_quota_id', $ids); $oCriteria->addNotInCondition('quotals_quota_id', $ids);
$aDelete['quotals'] = count(QuotaLanguageSetting::model()->findAll($criteria)); $aDelete['quotals'] = count(QuotaLanguageSetting::model()->findAll($oCriteria));
if (QuotaLanguageSetting::model()->hasErrors()) safeDie(QuotaLanguageSetting::model()->getError()); if (QuotaLanguageSetting::model()->hasErrors()) safeDie(QuotaLanguageSetting::model()->getError());
/**********************************************************************/ /**********************************************************************/
/* Check quota members */ /* Check quota members */
/**********************************************************************/ /**********************************************************************/
$quotas = Quota::model()->findAll(); $oCriteria = new CDbCriteria;
$quota_ids = array(); $oCriteria->join = 'LEFT JOIN {{questions}} q ON t.qid=q.qid LEFT JOIN {{surveys}} s ON t.sid=s.sid';
foreach ($quotas as $quota) $quota_ids[] = $quota['id']; $oCriteria->condition = '(q.qid IS NULL) OR (s.sid IS NULL)';
$criteria = new CDbCriteria;
$criteria->addNotInCondition('quota_id', $quota_ids);
$questions = Question::model()->findAll(); $aDelete['quotamembers'] = count(QuotaMember::model()->findAll($oCriteria));
$qids = array();
foreach ($questions as $question) $qids[] = $question['qid'];
$criteria->addNotInCondition('qid', $qids, 'OR');
$surveys = Survey::model()->findAll();
$sids = array();
foreach ($surveys as $survey) $sids[] = $survey['sid'];
$criteria->addNotInCondition('sid', $sids, 'OR');
$aDelete['quotamembers'] = count(QuotaMember::model()->findAll($criteria));
if (QuotaMember::model()->hasErrors()) safeDie(QuotaMember::model()->getError()); if (QuotaMember::model()->hasErrors()) safeDie(QuotaMember::model()->getError());
/**********************************************************************/ /**********************************************************************/
/* Check assessments */ /* Check assessments */
/**********************************************************************/ /**********************************************************************/
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->compare('scope', 'T'); $oCriteria->compare('scope', 'T');
$assessments = Assessment::model()->findAll($criteria); $assessments = Assessment::model()->findAll($oCriteria);
if (Assessment::model()->hasErrors()) safeDie(Assessment::model()->getError()); if (Assessment::model()->hasErrors()) safeDie(Assessment::model()->getError());
foreach ($assessments as $assessment) foreach ($assessments as $assessment)
{ {
@ -528,9 +507,9 @@ class CheckIntegrity extends Survey_Common_Action
} }
} }
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->compare('scope', 'G'); $oCriteria->compare('scope', 'G');
$assessments = Assessment::model()->findAll($criteria); $assessments = Assessment::model()->findAll($oCriteria);
if (Assessment::model()->hasErrors()) safeDie(Assessment::model()->getError()); if (Assessment::model()->hasErrors()) safeDie(Assessment::model()->getError());
foreach ($assessments as $assessment) foreach ($assessments as $assessment)
{ {
@ -540,25 +519,19 @@ class CheckIntegrity extends Survey_Common_Action
$aDelete['assessments'][] = array('id' => $assessment['id'], 'assessment' => $assessment['name'], 'reason' => $clang->gT('No matching group')); $aDelete['assessments'][] = array('id' => $assessment['id'], 'assessment' => $assessment['name'], 'reason' => $clang->gT('No matching group'));
} }
} }
unset($assessments);
/**********************************************************************/ /**********************************************************************/
/* Check answers */ /* Check answers */
/**********************************************************************/ /**********************************************************************/
$answers = Answer::model()->findAll(); $oCriteria = new CDbCriteria;
if (Answer::model()->hasErrors()) safeDie(Answer::model()->getError()); $oCriteria->join = 'LEFT JOIN {{questions}} q ON t.qid=q.qid';
$okQuestion = array(); $oCriteria->condition = '(q.qid IS NULL)';
$answers = Answer::model()->findAll($oCriteria);
foreach ($answers as $answer) foreach ($answers as $answer)
{ {
if (!array_key_exists($answer['qid'], $okQuestion)) { $aDelete['answers'][] = array('qid' => $answer['qid'], 'code' => $answer['code'], 'reason' => $clang->gT('No matching question'));
$iAnswerCount = Question::model()->countByAttributes(array('qid' => $answer['qid']));
if (Question::model()->hasErrors()) safeDie(Question::model()->getError());
if (!$iAnswerCount) {
$aDelete['answers'][] = array('qid' => $answer['qid'], 'code' => $answer['code'], 'reason' => $clang->gT('No matching question'));
} else {
$okQuestion[$answer['qid']] = $answer['qid'];
}
}
} }
/***************************************************************************/ /***************************************************************************/
/* Check survey languagesettings and restore them if they don't exist */ /* Check survey languagesettings and restore them if they don't exist */
/***************************************************************************/ /***************************************************************************/
@ -599,9 +572,9 @@ class CheckIntegrity extends Survey_Common_Action
if (Survey::model()->hasErrors()) safeDie(Survey::model()->getError()); if (Survey::model()->hasErrors()) safeDie(Survey::model()->getError());
$sids = array(); $sids = array();
foreach ($surveys as $survey) $sids[] = $survey['sid']; foreach ($surveys as $survey) $sids[] = $survey['sid'];
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->addNotInCondition('surveyls_survey_id', $sids); $oCriteria->addNotInCondition('surveyls_survey_id', $sids);
$surveys_languagesettings = SurveyLanguageSetting::model()->findAll($criteria); $surveys_languagesettings = SurveyLanguageSetting::model()->findAll($oCriteria);
if (SurveyLanguageSetting::model()->hasErrors()) safeDie(SurveyLanguageSetting::model()->getError()); if (SurveyLanguageSetting::model()->hasErrors()) safeDie(SurveyLanguageSetting::model()->getError());
foreach ($surveys_languagesettings as $surveys_languagesetting) foreach ($surveys_languagesettings as $surveys_languagesetting)
@ -612,23 +585,14 @@ class CheckIntegrity extends Survey_Common_Action
/**********************************************************************/ /**********************************************************************/
/* Check questions */ /* Check questions */
/**********************************************************************/ /**********************************************************************/
$questions = Question::model()->findAll(); $oCriteria = new CDbCriteria;
$oCriteria->join = 'LEFT JOIN {{surveys}} s ON t.sid=s.sid LEFT JOIN {{groups}} g ON t.gid=g.gid';
$oCriteria->condition = '(g.gid IS NULL) OR (s.sid IS NULL)';
$questions = Question::model()->findAll($oCriteria);
if (Question::model()->hasErrors()) safeDie(Question::model()->getError()); if (Question::model()->hasErrors()) safeDie(Question::model()->getError());
$groups = QuestionGroup::model()->findAll();
if (QuestionGroup::model()->hasErrors()) safeDie(QuestionGroup::model()->getError());
$gids = array();
foreach ($groups as $group) $gids[] = $group['gid'];
foreach ($questions as $question) foreach ($questions as $question)
{ {
//Make sure the group exists $aDelete['questions'][] = array('qid' => $question['qid'], 'reason' => $clang->gT('No matching group') . " ({$question['gid']})");
if (!in_array($question['gid'], $gids)) {
$aDelete['questions'][] = array('qid' => $question['qid'], 'reason' => $clang->gT('No matching group') . " ({$question['gid']})");
}
//Make sure survey exists
if (!in_array($question['sid'], $sids)) {
$aDelete['questions'][] = array('qid' => $question['qid'], 'reason' => $clang->gT('There is no matching survey.') . " ({$question['sid']})");
}
} }
/**********************************************************************/ /**********************************************************************/
@ -638,9 +602,9 @@ class CheckIntegrity extends Survey_Common_Action
if (Survey::model()->hasErrors()) safeDie(Survey::model()->getError()); if (Survey::model()->hasErrors()) safeDie(Survey::model()->getError());
$sids = array(); $sids = array();
foreach ($surveys as $survey) $sids[] = $survey['sid']; foreach ($surveys as $survey) $sids[] = $survey['sid'];
$criteria = new CDbCriteria; $oCriteria = new CDbCriteria;
$criteria->addNotInCondition('sid', $sids); $oCriteria->addNotInCondition('sid', $sids);
$groups = QuestionGroup::model()->findAll($criteria); $groups = QuestionGroup::model()->findAll($oCriteria);
foreach ($groups as $group) foreach ($groups as $group)
{ {
$aDelete['groups'][] = array('gid' => $group['gid'], 'reason' => $clang->gT('There is no matching survey.') . ' SID:' . $group['sid']); $aDelete['groups'][] = array('gid' => $group['gid'], 'reason' => $clang->gT('There is no matching survey.') . ' SID:' . $group['sid']);
@ -653,14 +617,12 @@ class CheckIntegrity extends Survey_Common_Action
//2: Check if that survey id still exists //2: Check if that survey id still exists
//3: If it doesn't offer it for deletion //3: If it doesn't offer it for deletion
$sQuery = dbSelectTablesLike('{{old_survey}}%'); $sQuery = dbSelectTablesLike('{{old_survey}}%');
$aResult = dbQueryOrFalse($sQuery) or safeDie("Couldn't get list of conditions from database<br />$sQuery<br />"); $aTables = Yii::app()->db->createCommand($sQuery)->queryColumn();
$aTables = $aResult->readAll();
$aOldSIDs = array(); $aOldSIDs = array();
$aSIDs = array(); $aSIDs = array();
foreach ($aTables as $sTable) foreach ($aTables as $sTable)
{ {
$sTable = reset($sTable);
list($sOldText, $SurveyText, $iSurveyID, $sDate) = explode('_', substr($sTable, strlen($sDBPrefix))); list($sOldText, $SurveyText, $iSurveyID, $sDate) = explode('_', substr($sTable, strlen($sDBPrefix)));
$aOldSIDs[] = $iSurveyID; $aOldSIDs[] = $iSurveyID;
$aFullOldSIDs[$iSurveyID][] = $sTable; $aFullOldSIDs[$iSurveyID][] = $sTable;
@ -724,8 +686,8 @@ class CheckIntegrity extends Survey_Common_Action
//1: Get list of 'old_token' tables and extract the survey id //1: Get list of 'old_token' tables and extract the survey id
//2: Check if that survey id still exists //2: Check if that survey id still exists
//3: If it doesn't offer it for deletion //3: If it doesn't offer it for deletion
$aResult = dbQueryOrFalse(dbSelectTablesLike('{{old_token}}%')) or safeDie("Couldn't get list of conditions from database<br />$sQuery<br />"); $sQuery = dbSelectTablesLike('{{old_token}}%');
$aTables = $aResult->readAll(); $aTables = Yii::app()->db->createCommand($sQuery)->queryColumn();
$aOldTokenSIDs = array(); $aOldTokenSIDs = array();
$aTokenSIDs = array(); $aTokenSIDs = array();
@ -733,8 +695,6 @@ class CheckIntegrity extends Survey_Common_Action
foreach ($aTables as $sTable) foreach ($aTables as $sTable)
{ {
$sTable = reset($sTable);
list($sOldText, $SurveyText, $iSurveyID, $sDateTime) = explode('_', substr($sTable, strlen($sDBPrefix))); list($sOldText, $SurveyText, $iSurveyID, $sDateTime) = explode('_', substr($sTable, strlen($sDBPrefix)));
$aTokenSIDs[] = $iSurveyID; $aTokenSIDs[] = $iSurveyID;
$aFullOldTokenSIDs[$iSurveyID][] = $sTable; $aFullOldTokenSIDs[$iSurveyID][] = $sTable;

View file

@ -515,6 +515,7 @@ class conditionsaction extends Survey_Common_Action {
//BEGIN: GATHER INFORMATION //BEGIN: GATHER INFORMATION
// 1: Get information for this question // 1: Get information for this question
// @todo : use viewHelper::getFieldText and getFieldCode for 2.06 for string show to user
if (!isset($qid)) { $qid = returnGlobal('qid'); } if (!isset($qid)) { $qid = returnGlobal('qid'); }
if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); } if (!isset($iSurveyID)) { $iSurveyID = returnGlobal('sid'); }
$thissurvey = getSurveyInfo($iSurveyID); $thissurvey = getSurveyInfo($iSurveyID);
@ -814,8 +815,10 @@ class conditionsaction extends Survey_Common_Action {
foreach ($aresult as $arows) foreach ($aresult as $arows)
{ {
$attr = getQuestionAttributeValues($rows['qid']); $attr = getQuestionAttributeValues($rows['qid']);
$label1 = isset($attr['dualscale_headerA']) ? $attr['dualscale_headerA'] : 'Label1'; $sLanguage=Survey::model()->findByPk($iSurveyID)->language;
$label2 = isset($attr['dualscale_headerB']) ? $attr['dualscale_headerB'] : 'Label2'; // dualscale_header are allways set, but can be empty
$label1 = empty($attr['dualscale_headerA'][$sLanguage]) ? gt('Scale 1') : $attr['dualscale_headerA'][$sLanguage];
$label2 = empty($attr['dualscale_headerB'][$sLanguage]) ? gt('Scale 2') : $attr['dualscale_headerB'][$sLanguage];
$shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "][$label1]"; $shortanswer = "{$arows['title']}: [" . strip_tags($arows['question']) . "][$label1]";
$shortquestion = $rows['title'].":$shortanswer ".strip_tags($rows['question']); $shortquestion = $rows['title'].":$shortanswer ".strip_tags($rows['question']);
$cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'].$X.$rows['gid'].$X.$rows['qid'].$arows['title']."#0"); $cquestions[] = array($shortquestion, $rows['qid'], $rows['type'], $rows['sid'].$X.$rows['gid'].$X.$rows['qid'].$arows['title']."#0");
@ -1341,19 +1344,17 @@ class conditionsaction extends Survey_Common_Action {
$markcidstyle="editedrow"; $markcidstyle="editedrow";
} }
if (isset($currentfield) && $currentfield != $rows['cfieldname']) if (isset($currentfield) && $currentfield != $rows['cfieldname'] )
{ {
$aViewUrls['output'] .= "<tr class='evenrow'>\n" $aViewUrls['output'] .= "<tr class='evenrow'>\n"
."\t<td colspan='2'>\n" ."\t<td colspan='2' class='operator'>\n"
."<span><strong>" .$clang->gT("and")."</td></tr>";
.$clang->gT("and")."</strong></span></td></tr>";
} }
elseif (isset($currentfield)) elseif (isset($currentfield))
{ {
$aViewUrls['output'] .= "<tr class='evenrow'>\n" $aViewUrls['output'] .= "<tr class='evenrow'>\n"
."\t<td colspan='2'>\n" ."\t<td colspan='2' class='operator'>\n"
."<span><strong>" .$clang->gT("or")."</td></tr>";
.$clang->gT("or")."</strong></span></td></tr>";
} }
$aViewUrls['output'] .= "\t<tr class='{$markcidstyle}'>\n" $aViewUrls['output'] .= "\t<tr class='{$markcidstyle}'>\n"
@ -1378,14 +1379,23 @@ class conditionsaction extends Survey_Common_Action {
{ {
$leftOperandType = 'tokenattr'; $leftOperandType = 'tokenattr';
$aTokenAttrNames=getTokenFieldsAndNames($iSurveyID); $aTokenAttrNames=getTokenFieldsAndNames($iSurveyID);
if (count($aTokenAttrNames) != 0) if(isset($aTokenAttrNames[strtolower($extractedTokenAttr[1])]))
{ {
$thisAttrName=HTMLEscape($aTokenAttrNames[strtolower($extractedTokenAttr[1])]['description'])." [".$clang->gT("From token table")."]"; $thisAttrName=HTMLEscape($aTokenAttrNames[strtolower($extractedTokenAttr[1])]['description']);
} }
else else
{ {
$thisAttrName=HTMLEscape($extractedTokenAttr[1])." [".$clang->gT("Inexistant token table")."]"; $thisAttrName=HTMLEscape($extractedTokenAttr[1]);
} }
if(tableExists("{{tokens_$iSurveyID}}"))
{
$thisAttrName.= " [".$clang->gT("From token table")."]";
}
else
{
$thisAttrName.= " [".$clang->gT("Inexistant token table")."]";
}
$aViewUrls['output'] .= "\t$thisAttrName\n"; $aViewUrls['output'] .= "\t$thisAttrName\n";
// TIBO not sure this is used anymore !! // TIBO not sure this is used anymore !!
$conditionsList[]=array("cid"=>$rows['cid'], $conditionsList[]=array("cid"=>$rows['cid'],
@ -1473,7 +1483,7 @@ class conditionsaction extends Survey_Common_Action {
} }
} }
} }
// if $rightOperandType is still unkown then it is a simple constant // if $rightOperandType is still unknown then it is a simple constant
if ($rightOperandType == 'unknown') if ($rightOperandType == 'unknown')
{ {
$rightOperandType = 'constantVal'; $rightOperandType = 'constantVal';
@ -1524,7 +1534,7 @@ class conditionsaction extends Survey_Common_Action {
// now set the corresponding hidden input field // now set the corresponding hidden input field
// depending on the rightOperandType // depending on the rightOperandType
// This is used when Editting a condition // This is used when editing a condition
if ($rightOperandType == 'predefinedAnsw') if ($rightOperandType == 'predefinedAnsw')
{ {
$aViewUrls['output'] .= CHtml::hiddenField('EDITcanswers[]', HTMLEscape($rows['value']), array( $aViewUrls['output'] .= CHtml::hiddenField('EDITcanswers[]', HTMLEscape($rows['value']), array(

View file

@ -95,11 +95,30 @@ class database extends Survey_Common_Action
{ {
foreach ($aSurveyLanguages as $sLanguage) foreach ($aSurveyLanguages as $sLanguage)
{ {
if (!is_null(Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage.'_0'))) // Qick and dirty insert for yes/no defaul value
{ // write the the selectbox option, or if "EM" is slected, this value to table
$this->_updateDefaultValues($iQuestionID,0,0,'',$sLanguage,Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage.'_0'),true); if ($sQuestionType == 'Y'){
/// value for all langs
if (Yii::app()->request->getPost('samedefault') == 1){
$sLanguage = $aSurveyLanguages[0]; // turn
}else{
$sCurrentLang = $sLanguage; // edit the next lines
}
if ( Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage) == 'EM') { // Case EM, write expression to database
$this->_updateDefaultValues($iQuestionID,0,0,'',$sLanguage,Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage.'_EM'),true);
}
else{
// Case "other", write list value to database
$this->_updateDefaultValues($iQuestionID,0,0,'',$sLanguage,Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage),true);
}
///// end yes/no
}else{
if (!is_null(Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage.'_0')))
{
$this->_updateDefaultValues($iQuestionID,0,0,'',$sLanguage,Yii::app()->request->getPost('defaultanswerscale_0_'.$sLanguage.'_0'),true);
}
} }
} }
} }
Yii::app()->session['flashmessage'] = $clang->gT("Default value settings were successfully saved."); Yii::app()->session['flashmessage'] = $clang->gT("Default value settings were successfully saved.");
LimeExpressionManager::SetDirtyFlag(); LimeExpressionManager::SetDirtyFlag();
@ -135,12 +154,6 @@ class database extends Survey_Common_Action
for ($iSortOrderID=1;$iSortOrderID<$iMaxCount;$iSortOrderID++) for ($iSortOrderID=1;$iSortOrderID<$iMaxCount;$iSortOrderID++)
{ {
$sCode=sanitize_paranoid_string(Yii::app()->request->getPost('code_'.$iSortOrderID.'_'.$iScaleID)); $sCode=sanitize_paranoid_string(Yii::app()->request->getPost('code_'.$iSortOrderID.'_'.$iScaleID));
if (Yii::app()->request->getPost('oldcode_'.$iSortOrderID.'_'.$iScaleID)) {
$sOldCode=sanitize_paranoid_string(Yii::app()->request->getPost('oldcode_'.$iSortOrderID.'_'.$iScaleID));
if($sCode !== $sOldCode) {
Condition::model()->updateAll(array('value'=>$sCode), 'cqid=:cqid AND value=:value', array(':cqid'=>$iQuestionID, ':value'=>$sOldCode));
}
}
$iAssessmentValue=(int) Yii::app()->request->getPost('assessment_'.$iSortOrderID.'_'.$iScaleID); $iAssessmentValue=(int) Yii::app()->request->getPost('assessment_'.$iSortOrderID.'_'.$iScaleID);
foreach ($aSurveyLanguages as $sLanguage) foreach ($aSurveyLanguages as $sLanguage)
@ -161,8 +174,11 @@ class database extends Survey_Common_Action
{ {
Yii::app()->setFlashMessage($clang->gT("Failed to update answers"),'error'); Yii::app()->setFlashMessage($clang->gT("Failed to update answers"),'error');
} }
} // foreach ($alllanguages as $language) }
if(isset($sOldCode) && $sCode !== $sOldCode) { // Updating code (oldcode!==null) => update condition with the new code
$sOldCode=Yii::app()->request->getPost('oldcode_'.$iSortOrderID.'_'.$iScaleID);
if(isset($sOldCode) && $sCode !== $sOldCode)
{
Condition::model()->updateAll(array('value'=>$sCode), 'cqid=:cqid AND value=:value', array(':cqid'=>$iQuestionID, ':value'=>$sOldCode)); Condition::model()->updateAll(array('value'=>$sCode), 'cqid=:cqid AND value=:value', array(':cqid'=>$iQuestionID, ':value'=>$sOldCode));
} }
} // for ($sortorderid=0;$sortorderid<$maxcount;$sortorderid++) } // for ($sortorderid=0;$sortorderid<$maxcount;$sortorderid++)
@ -283,7 +299,14 @@ class database extends Survey_Common_Action
$oSubQuestion->scale_id=$iScaleID; $oSubQuestion->scale_id=$iScaleID;
} }
} }
$bSubQuestionResult=$oSubQuestion->save(); if ($oSubQuestion->qid) {
switchMSSQLIdentityInsert('questions',true);
$bSubQuestionResult=$oSubQuestion->save();
switchMSSQLIdentityInsert('questions',false);
}else
{
$bSubQuestionResult=$oSubQuestion->save();
}
if($bSubQuestionResult) if($bSubQuestionResult)
{ {
if(substr($subquestionkey,0,3)!='new' && isset($aOldCodes[$iScaleID][$iPosition]) && $aCodes[$iScaleID][$iPosition] !== $aOldCodes[$iScaleID][$iPosition]) if(substr($subquestionkey,0,3)!='new' && isset($aOldCodes[$iScaleID][$iPosition]) && $aCodes[$iScaleID][$iPosition] !== $aOldCodes[$iScaleID][$iPosition])
@ -894,10 +917,6 @@ class database extends Survey_Common_Action
$url = Yii::app()->request->getPost('url_'.$langname); $url = Yii::app()->request->getPost('url_'.$langname);
if ($url == 'http://') {$url="";} if ($url == 'http://') {$url="";}
$short_title = html_entity_decode(Yii::app()->request->getPost('short_title_'.$langname), ENT_QUOTES, "UTF-8");
$description = html_entity_decode(Yii::app()->request->getPost('description_'.$langname), ENT_QUOTES, "UTF-8");
$welcome = html_entity_decode(Yii::app()->request->getPost('welcome_'.$langname), ENT_QUOTES, "UTF-8");
$endtext = html_entity_decode(Yii::app()->request->getPost('endtext_'.$langname), ENT_QUOTES, "UTF-8");
$sURLDescription = html_entity_decode(Yii::app()->request->getPost('urldescrip_'.$langname), ENT_QUOTES, "UTF-8"); $sURLDescription = html_entity_decode(Yii::app()->request->getPost('urldescrip_'.$langname), ENT_QUOTES, "UTF-8");
$sURL = html_entity_decode(Yii::app()->request->getPost('url_'.$langname), ENT_QUOTES, "UTF-8"); $sURL = html_entity_decode(Yii::app()->request->getPost('url_'.$langname), ENT_QUOTES, "UTF-8");

View file

@ -297,6 +297,7 @@ class dataentry extends Survey_Common_Action
} }
else else
{ {
$aSRIDConversions=array();
$targetSchema = SurveyDynamic::model($iSurveyId)->getTableSchema(); $targetSchema = SurveyDynamic::model($iSurveyId)->getTableSchema();
$sourceTable = PluginDynamic::model($_POST['table']); $sourceTable = PluginDynamic::model($_POST['table']);
$sourceSchema = $sourceTable->getTableSchema(); $sourceSchema = $sourceTable->getTableSchema();
@ -332,7 +333,7 @@ class dataentry extends Survey_Common_Action
$sourceResponses = new CDataProviderIterator(new CActiveDataProvider($sourceTable), 500); $sourceResponses = new CDataProviderIterator(new CActiveDataProvider($sourceTable), 500);
foreach ($sourceResponses as $sourceResponse) foreach ($sourceResponses as $sourceResponse)
{ {
$iOldID=$sourceResponse->id;
// Using plugindynamic model because I dont trust surveydynamic. // Using plugindynamic model because I dont trust surveydynamic.
$targetResponse = new PluginDynamic("{{survey_$iSurveyId}}"); $targetResponse = new PluginDynamic("{{survey_$iSurveyId}}");
@ -342,37 +343,36 @@ class dataentry extends Survey_Common_Action
} }
$imported++; $imported++;
$targetResponse->save(); $targetResponse->save();
$aSRIDConversions[$iOldID]=$targetResponse->id;
unset($targetResponse); unset($targetResponse);
} }
Yii::app()->session['flashmessage'] = sprintf(gT("%s old response(s) were successfully imported."), $imported); Yii::app()->session['flashmessage'] = sprintf(gT("%s old response(s) were successfully imported."), $imported);
$sOldTimingsTable=substr($sourceTable->tableName(),0,strrpos($sourceTable->tableName(),'_')).'_timings'.substr($sourceTable->tableName(),strrpos($sourceTable->tableName(),'_')); $sOldTimingsTable=substr(substr($sourceTable->tableName(),0,strrpos($sourceTable->tableName(),'_')).'_timings'.substr($sourceTable->tableName(),strrpos($sourceTable->tableName(),'_')),strlen(Yii::app()->db->tablePrefix));
$sNewTimingsTable = "{{{$surveyid}_timings}}"; $sNewTimingsTable = "survey_{$surveyid}_timings";
if (isset($_POST['timings']) && $_POST['timings'] == 1 && tableExists($sOldTimingsTable) && tableExists($sNewTimingsTable)) if (isset($_POST['timings']) && $_POST['timings'] == 1 && tableExists($sOldTimingsTable) && tableExists($sNewTimingsTable))
{ {
// Import timings // Import timings
$aFieldsOldTimingTable=array_values($schema->getTable($sOldTimingsTable)->columnNames); $arDestination=SurveyTimingDynamic::model($surveyid);
$aFieldsNewTimingTable=array_values($schema->getTable($sNewTimingsTable)->columnNames); $aFieldsOldTimingTable=array_values(Yii::app()->db->schema->getTable('{{'.$sOldTimingsTable.'}}')->columnNames);
$aFieldsNewTimingTable=array_values(Yii::app()->db->schema->getTable('{{'.$sNewTimingsTable.'}}')->columnNames);
$aValidTimingFields=array_intersect($aFieldsOldTimingTable,$aFieldsNewTimingTable); $aValidTimingFields=array_intersect($aFieldsOldTimingTable,$aFieldsNewTimingTable);
$queryOldValues = "SELECT ".implode(", ",$aValidTimingFields)." FROM {$sOldTimingsTable} "; $sQueryOldValues = "SELECT ".implode(", ",$aValidTimingFields)." FROM {{{$sOldTimingsTable}}} ";
$resultOldValues = dbExecuteAssoc($queryOldValues) or show_error("Error:<br />$queryOldValues<br />"); $aQueryOldValues = Yii::app()->db->createCommand($sQueryOldValues)->query()->readAll(); //Checked
$iRecordCountT=0; $iRecordCountT=0;
$aSRIDConversions=array(); foreach ($aQueryOldValues as $sRecord)
foreach ($resultOldValues->readAll() as $sTable)
{ {
if (isset($aSRIDConversions[$sTable['id']])) if (isset($aSRIDConversions[$sRecord['id']]))
{ {
$sTable['id']=$aSRIDConversions[$sTable['id']]; $sRecord['id']=$aSRIDConversions[$sRecord['id']];
} }
else continue; else continue;
//$sInsertSQL=Yii::app()->db->GetInsertSQL($sNewTimingsTable,$row); Yii::app()->db->createCommand()->insert("{{{$sNewTimingsTable}}}",$sRecord);
$sInsertSQL="INSERT into {$sNewTimingsTable} (".implode(",", array_map("dbQuoteID", array_keys($sTable))).") VALUES (".implode(",", array_map("dbQuoteAll", array_values($sTable))).")";
$aTables = dbExecuteAssoc($sInsertSQL) or show_error("Error:<br />$sInsertSQL<br />");
$iRecordCountT++; $iRecordCountT++;
} }
Yii::app()->session['flashmessage'] = sprintf(gT("%s old response(s) and according timings were successfully imported."),$imported,$iRecordCountT); Yii::app()->session['flashmessage'] = sprintf(gT("%s old response(s) and according timings were successfully imported."),$imported,$iRecordCountT);

View file

@ -87,9 +87,9 @@ class emailtemplates extends Survey_Common_Action {
$uploadUrl = Yii::app()->getBaseUrl(true) . substr(Yii::app()->getConfig('uploadurl'),strlen(Yii::app()->getConfig('publicurl'))-1); $uploadUrl = Yii::app()->getBaseUrl(true) . substr(Yii::app()->getConfig('uploadurl'),strlen(Yii::app()->getConfig('publicurl'))-1);
// We need the real path since we check that the resolved file name starts with this path. // We need the real path since we check that the resolved file name starts with this path.
$uploadDir = realpath(Yii::app()->getConfig('uploaddir')); $uploadDir = realpath(Yii::app()->getConfig('uploaddir'));
$save=Yii::app()->request->getPost('save',''); $sSaveMethod=Yii::app()->request->getPost('save','');
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
if (Permission::model()->hasSurveyPermission($iSurveyId, 'surveylocale','update')) if (Permission::model()->hasSurveyPermission($iSurveyId, 'surveylocale','update') && $sSaveMethod!='')
{ {
$languagelist = Survey::model()->findByPk($iSurveyId)->additionalLanguages; $languagelist = Survey::model()->findByPk($iSurveyId)->additionalLanguages;
$languagelist[] = Survey::model()->findByPk($iSurveyId)->language; $languagelist[] = Survey::model()->findByPk($iSurveyId)->language;
@ -147,8 +147,9 @@ class emailtemplates extends Survey_Common_Action {
$usquery = SurveyLanguageSetting::model()->updateAll($attributes,'surveyls_survey_id = :ssid AND surveyls_language = :sl', array(':ssid' => $iSurveyId, ':sl' => $langname)); $usquery = SurveyLanguageSetting::model()->updateAll($attributes,'surveyls_survey_id = :ssid AND surveyls_language = :sl', array(':ssid' => $iSurveyId, ':sl' => $langname));
} }
Yii::app()->session['flashmessage'] = $clang->gT("Email templates successfully saved."); Yii::app()->session['flashmessage'] = $clang->gT("Email templates successfully saved.");
$this->getController()->redirect(array('admin/emailtemplates/sa/index/surveyid/'.$iSurveyId));
} }
if($save=='saveclose') if($sSaveMethod=='saveclose')
$this->getController()->redirect(array('admin/survey/sa/view/surveyid/'.$iSurveyId)); $this->getController()->redirect(array('admin/survey/sa/view/surveyid/'.$iSurveyId));
else else
self::index($iSurveyId); self::index($iSurveyId);
@ -163,7 +164,7 @@ class emailtemplates extends Survey_Common_Action {
* @param array $aData Data to be passed on. Optional. * @param array $aData Data to be passed on. Optional.
*/ */
protected function _renderWrappedTemplate($sAction = 'emailtemplates', $aViewUrls = array(), $aData = array()) protected function _renderWrappedTemplate($sAction = 'emailtemplates', $aViewUrls = array(), $aData = array())
{ {
App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . 'emailtemplates.js'); App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . 'emailtemplates.js');
$aData['display']['menu_bars']['surveysummary'] = 'editemailtemplates'; $aData['display']['menu_bars']['surveysummary'] = 'editemailtemplates';

View file

@ -190,6 +190,7 @@ class export extends Survey_Common_Action {
{ {
$sCode=viewHelper::getFieldCode($fieldinfo); $sCode=viewHelper::getFieldCode($fieldinfo);
$aFields[$sFieldName]=$sCode.' - '.htmlspecialchars(ellipsize(html_entity_decode(viewHelper::getFieldText($fieldinfo)),30,.6,'...')); $aFields[$sFieldName]=$sCode.' - '.htmlspecialchars(ellipsize(html_entity_decode(viewHelper::getFieldText($fieldinfo)),30,.6,'...'));
$aFieldsOptions[$sFieldName]=array('title'=>viewHelper::getFieldText($fieldinfo),'data-fieldname'=>$fieldinfo['fieldname'],'data-emcode'=>viewHelper::getFieldCode($fieldinfo,array('LEMcompat'=>true))); // No need to filter title : Yii do it (remove all tag)
} }
$data['SingleResponse']=(int)returnGlobal('id'); $data['SingleResponse']=(int)returnGlobal('id');
@ -198,7 +199,7 @@ class export extends Survey_Common_Action {
$data['selectinc'] = $selectinc; $data['selectinc'] = $selectinc;
$data['afieldcount'] = $iFieldCount; $data['afieldcount'] = $iFieldCount;
$data['aFields'] = $aFields; $data['aFields'] = $aFields;
$data['aFieldsOptions'] = $aFieldsOptions;
//get max number of datasets //get max number of datasets
$iMaximum = SurveyDynamic::model($iSurveyID)->getMaxId(); $iMaximum = SurveyDynamic::model($iSurveyID)->getMaxId();
@ -427,40 +428,33 @@ class export extends Survey_Common_Action {
//Now get the query string with all fields to export //Now get the query string with all fields to export
$query = SPSSGetQuery($iSurveyID, 500, 0); // Sample first 500 responses for adjusting fieldmap $query = SPSSGetQuery($iSurveyID, 500, 0); // Sample first 500 responses for adjusting fieldmap
$result = $query->query(); $result = $query->queryAll();
$num_fields = 0; $num_fields = 0;
//Now we check if we need to adjust the size of the field or the type of the field //Now we check if we need to adjust the size of the field or the type of the field
foreach ( $result as $row ) foreach ( $result as $row )
{ {
if($num_fields==0) {
$num_fields = count($row);
}
$row = array_values($row);
$fieldno = 0;
while ( $fieldno < $num_fields ) foreach ( $fields as $iIndex=>$aField )
{ {
//Performance improvement, don't recheck fields that have valuelabels //Performance improvement, don't recheck fields that have valuelabels
if ( ! isset($fields[$fieldno]['answers']) ) if ( ! isset($aField['answers']) )
{ {
$strTmp = mb_substr(stripTagsFull($row[$fieldno]), 0, $iLength); $strTmp = mb_substr(stripTagsFull($row[$aField['sql_name']]), 0, $iLength);
$len = mb_strlen($strTmp); $len = mb_strlen($strTmp);
if ( $len > $fields[$fieldno]['size'] ) $fields[$fieldno]['size'] = $len; if ( $len > $fields[$iIndex]['size'] ) $fields[$iIndex]['size'] = $len;
if ( trim($strTmp) != '' ) if ( trim($strTmp) != '' )
{ {
if ( $fields[$fieldno]['SPSStype'] == 'F' && (isNumericExtended($strTmp) === FALSE || $fields[$fieldno]['size'] > 16) ) if ( $fields[$iIndex]['SPSStype'] == 'F' && (isNumericExtended($strTmp) === FALSE || $fields[$iIndex]['size'] > 16) )
{ {
$fields[$fieldno]['SPSStype'] = 'A'; $fields[$iIndex]['SPSStype'] = 'A';
} }
} }
} }
$fieldno++;
} }
} }
$result->close();
/** /**
* End of DATA print out * End of DATA print out
@ -872,6 +866,7 @@ class export extends Survey_Common_Action {
public function dumplabel() public function dumplabel()
{ {
if (!Permission::model()->hasGlobalPermission('labelsets','export')) die ('No permission.');
$lid = sanitize_int(Yii::app()->request->getParam('lid')); $lid = sanitize_int(Yii::app()->request->getParam('lid'));
// DUMP THE RELATED DATA FOR A SINGLE QUESTION INTO A SQL FILE FOR IMPORTING LATER ON OR // DUMP THE RELATED DATA FOR A SINGLE QUESTION INTO A SQL FILE FOR IMPORTING LATER ON OR
// ON ANOTHER SURVEY SETUP DUMP ALL DATA WITH RELATED QID FROM THE FOLLOWING TABLES // ON ANOTHER SURVEY SETUP DUMP ALL DATA WITH RELATED QID FROM THE FOLLOWING TABLES
@ -895,7 +890,7 @@ class export extends Survey_Common_Action {
$fn = "limesurvey_labelset_" . implode('_', $lids) . ".lsl"; $fn = "limesurvey_labelset_" . implode('_', $lids) . ".lsl";
$xml = getXMLWriter(); $xml = getXMLWriter();
$this->_addHeaders($fn, "text/html/force-download", "Mon, 26 Jul 1997 05:00:00 GMT", "cache"); $this->_addHeaders($fn, "application/force-download", "Mon, 26 Jul 1997 05:00:00 GMT", "cache");
$xml->openURI('php://output'); $xml->openURI('php://output');
@ -948,27 +943,21 @@ class export extends Survey_Common_Action {
if ( $aSurveyInfo['active'] == 'Y' ) if ( $aSurveyInfo['active'] == 'Y' )
{ {
getXMLDataSingleTable($iSurveyID, 'survey_' . $iSurveyID, 'Responses', 'responses', $sLSRFileName, FALSE); getXMLDataSingleTable($iSurveyID, 'survey_' . $iSurveyID, 'Responses', 'responses', $sLSRFileName, FALSE);
$this->_addToZip($zip, $sLSRFileName, 'survey_' . $iSurveyID . '_responses.lsr'); $this->_addToZip($zip, $sLSRFileName, 'survey_' . $iSurveyID . '_responses.lsr');
unlink($sLSRFileName); unlink($sLSRFileName);
} }
if ( Yii::app()->db->schema->getTable('{{tokens_' . $iSurveyID . '}}') ) if ( tableExists('{{tokens_' . $iSurveyID . '}}') )
{ {
getXMLDataSingleTable($iSurveyID, 'tokens_' . $iSurveyID, 'Tokens', 'tokens', $sLSTFileName); getXMLDataSingleTable($iSurveyID, 'tokens_' . $iSurveyID, 'Tokens', 'tokens', $sLSTFileName);
$this->_addToZip($zip, $sLSTFileName, 'survey_' . $iSurveyID . '_tokens.lst'); $this->_addToZip($zip, $sLSTFileName, 'survey_' . $iSurveyID . '_tokens.lst');
unlink($sLSTFileName); unlink($sLSTFileName);
} }
if ( Yii::app()->db->schema->getTable('{{survey_' . $iSurveyID . '_timings}}') ) if ( tableExists('{{survey_' . $iSurveyID . '_timings}}') )
{ {
getXMLDataSingleTable($iSurveyID, 'survey_' . $iSurveyID . '_timings', 'Timings', 'timings', $sLSIFileName); getXMLDataSingleTable($iSurveyID, 'survey_' . $iSurveyID . '_timings', 'Timings', 'timings', $sLSIFileName);
$this->_addToZip($zip, $sLSIFileName, 'survey_' . $iSurveyID . '_timings.lsi'); $this->_addToZip($zip, $sLSIFileName, 'survey_' . $iSurveyID . '_timings.lsi');
unlink($sLSIFileName); unlink($sLSIFileName);
} }

View file

@ -67,11 +67,9 @@ class GlobalSettings extends Survey_Common_Action
// Some URLs are not to be allowed to refered back to. // Some URLs are not to be allowed to refered back to.
// These exceptions can be added to the $aReplacements array // These exceptions can be added to the $aReplacements array
$aReplacements=array('admin/user/adduser'=>'admin/user/index', $aReplacements=array('admin/update/sa/step4b'=>'admin/sa/index',
'admin/user/sa/adduser'=>'admin/user/sa/index', 'admin/user/sa/adduser'=>'admin/user/sa/index',
'admin/user/sa/setusertemplates'=>'admin/user/sa/index', 'admin/user/sa/setusertemplates'=>'admin/user/sa/index'
'admin/user/setusertemplates'=>'admin/user/sa/index'
); );
$refurl= str_replace(array_keys($aReplacements),array_values($aReplacements),$refurl); $refurl= str_replace(array_keys($aReplacements),array_values($aReplacements),$refurl);
Yii::app()->session['refurl'] = htmlspecialchars($refurl); //just to be safe! Yii::app()->session['refurl'] = htmlspecialchars($refurl); //just to be safe!
@ -122,6 +120,18 @@ class GlobalSettings extends Survey_Common_Action
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
Yii::app()->loadHelper('surveytranslator'); Yii::app()->loadHelper('surveytranslator');
$iPDFFontSize = sanitize_int($_POST['pdffontsize']);
if ($iPDFFontSize < 1)
{
$iPDFFontSize = 9;
}
$iPDFLogoWidth = sanitize_int($_POST['pdflogowidth']);
if ($iPDFLogoWidth < 1)
{
$iPDFLogoWidth = 50;
}
$maxemails = $_POST['maxemails']; $maxemails = $_POST['maxemails'];
if (sanitize_int($_POST['maxemails']) < 1) { if (sanitize_int($_POST['maxemails']) < 1) {
$maxemails = 1; $maxemails = 1;
@ -148,7 +158,12 @@ class GlobalSettings extends Survey_Common_Action
setGlobalSetting('defaulttemplateeditormode', sanitize_paranoid_string($_POST['defaulttemplateeditormode'])); setGlobalSetting('defaulttemplateeditormode', sanitize_paranoid_string($_POST['defaulttemplateeditormode']));
if (!Yii::app()->getConfig('demoMode')) if (!Yii::app()->getConfig('demoMode'))
{ {
setGlobalSetting('defaulttemplate', sanitize_paranoid_string($_POST['defaulttemplate'])); $sTemplate=Yii::app()->getRequest()->getPost("defaulttemplate");
if(array_key_exists($sTemplate,getTemplateList()))// Filter template name
{
setGlobalSetting('defaulttemplate', $sTemplate);
}
} }
setGlobalSetting('admintheme', sanitize_paranoid_string($_POST['admintheme'])); setGlobalSetting('admintheme', sanitize_paranoid_string($_POST['admintheme']));
setGlobalSetting('adminthemeiconsize', trim(file_get_contents(Yii::app()->getConfig("styledir").DIRECTORY_SEPARATOR.sanitize_paranoid_string($_POST['admintheme']).DIRECTORY_SEPARATOR.'iconsize'))); setGlobalSetting('adminthemeiconsize', trim(file_get_contents(Yii::app()->getConfig("styledir").DIRECTORY_SEPARATOR.sanitize_paranoid_string($_POST['admintheme']).DIRECTORY_SEPARATOR.'iconsize')));
@ -196,6 +211,11 @@ class GlobalSettings extends Survey_Common_Action
if ($iSessionExpirationTime == 0) $iSessionExpirationTime = 7200; if ($iSessionExpirationTime == 0) $iSessionExpirationTime = 7200;
setGlobalSetting('iSessionExpirationTime', $iSessionExpirationTime); setGlobalSetting('iSessionExpirationTime', $iSessionExpirationTime);
setGlobalSetting('ipInfoDbAPIKey', $_POST['ipInfoDbAPIKey']); setGlobalSetting('ipInfoDbAPIKey', $_POST['ipInfoDbAPIKey']);
setGlobalSetting('pdffontsize', $iPDFFontSize);
setGlobalSetting('pdfshowheader', $_POST['pdfshowheader']);
setGlobalSetting('pdflogowidth', $iPDFLogoWidth);
setGlobalSetting('pdfheadertitle', $_POST['pdfheadertitle']);
setGlobalSetting('pdfheaderstring', $_POST['pdfheaderstring']);
setGlobalSetting('googleMapsAPIKey', $_POST['googleMapsAPIKey']); setGlobalSetting('googleMapsAPIKey', $_POST['googleMapsAPIKey']);
setGlobalSetting('googleanalyticsapikey',$_POST['googleanalyticsapikey']); setGlobalSetting('googleanalyticsapikey',$_POST['googleanalyticsapikey']);
setGlobalSetting('googletranslateapikey',$_POST['googletranslateapikey']); setGlobalSetting('googletranslateapikey',$_POST['googletranslateapikey']);

View file

@ -319,37 +319,31 @@ class labels extends Survey_Common_Action
*/ */
public function process() public function process()
{ {
if ( Permission::model()->hasGlobalPermission('labelsets','update'))
{
if (isset($_POST['method']) && get_magic_quotes_gpc())
$_POST['method'] = stripslashes($_POST['method']);
$action = returnGlobal('action'); $action = returnGlobal('action');
Yii::app()->loadHelper('admin/label'); Yii::app()->loadHelper('admin/label');
$lid = returnGlobal('lid'); $lid = returnGlobal('lid');
if ($action == "updateset") if ($action == "updateset" && Permission::model()->hasGlobalPermission('labelsets','update'))
{ {
updateset($lid); updateset($lid);
Yii::app()->session['flashmessage'] = Yii::app()->lang->gT("Label set properties sucessfully updated."); Yii::app()->setFlashMessage(Yii::app()->lang->gT("Label set properties sucessfully updated."),'success');
} }
if ($action == "insertlabelset") if ($action == "insertlabelset" && Permission::model()->hasGlobalPermission('labelsets','create'))
$lid = insertlabelset(); $lid = insertlabelset();
if (($action == "modlabelsetanswers") || ($action == "ajaxmodlabelsetanswers")) if (($action == "modlabelsetanswers" || ($action == "ajaxmodlabelsetanswers")) && Permission::model()->hasGlobalPermission('labelsets','update'))
modlabelsetanswers($lid); modlabelsetanswers($lid);
if ($action == "deletelabelset") if ($action == "deletelabelset" && Permission::model()->hasGlobalPermission('labelsets','delete'))
{
if (deletelabelset($lid)) if (deletelabelset($lid))
{ {
Yii::app()->session['flashmessage'] = Yii::app()->lang->gT("Label set sucessfully deleted."); Yii::app()->setFlashMessage(Yii::app()->lang->gT("Label set sucessfully deleted."),'success');
$lid = 0; $lid = 0;
} }
}
if ($lid) if ($lid)
$this->getController()->redirect(array("admin/labels/sa/view/lid/" . $lid)); $this->getController()->redirect(array("admin/labels/sa/view/lid/" . $lid));
else else
$this->getController()->redirect(array("admin/labels/sa/view")); $this->getController()->redirect(array("admin/labels/sa/view"));
}
} }
/** /**
@ -360,8 +354,11 @@ class labels extends Survey_Common_Action
*/ */
public function exportmulti() public function exportmulti()
{ {
App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . 'labels.js'); if (Permission::model()->hasGlobalPermission('labelsets','export'))
$this->_renderWrappedTemplate('labels', 'exportmulti_view'); {
App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . 'labels.js');
$this->_renderWrappedTemplate('labels', 'exportmulti_view');
}
} }
public function getAllSets() public function getAllSets()
@ -372,9 +369,9 @@ class labels extends Survey_Common_Action
foreach($results as $row) foreach($results as $row)
{ {
$output[$row->lid] = $row->getAttribute('label_name'); $output[$row->lid] = flattenText($row->getAttribute('label_name'));
} }
header('Content-type: application/json');
echo ls_json_encode($output); echo ls_json_encode($output);
} }
@ -383,6 +380,7 @@ class labels extends Survey_Common_Action
$lid = Yii::app()->getRequest()->getPost('lid'); $lid = Yii::app()->getRequest()->getPost('lid');
$answers = Yii::app()->getRequest()->getPost('answers'); $answers = Yii::app()->getRequest()->getPost('answers');
$code = Yii::app()->getRequest()->getPost('code'); $code = Yii::app()->getRequest()->getPost('code');
$aAssessmentValues = Yii::app()->getRequest()->getPost('assessmentvalues',array());
//Create new label set //Create new label set
$language = ""; $language = "";
foreach ($answers as $lang => $answer) { foreach ($answers as $lang => $answer) {
@ -412,6 +410,7 @@ class labels extends Survey_Common_Action
$label->title = $ans; $label->title = $ans;
$label->sortorder = $key; $label->sortorder = $key;
$label->language = $lang; $label->language = $lang;
$label->assessment_value = isset($aAssessmentValues[$key])?$aAssessmentValues[$key]:0;
if(!$label->save()) if(!$label->save())
$res = 'fail'; $res = 'fail';
} }

View file

@ -101,7 +101,7 @@ class participantsaction extends Survey_Common_Action
} else { } else {
$iUserID = Yii::app()->session['loginID']; $iUserID = Yii::app()->session['loginID'];
} }
$aAttributeIDs=array_combine($aAttributeIDs,$aAttributeIDs);
$query = Participant::model()->getParticipants(0, 0, $aAttributeIDs, null, $search, $iUserID); $query = Participant::model()->getParticipants(0, 0, $aAttributeIDs, null, $search, $iUserID);
if (!$query) if (!$query)
return false; return false;
@ -128,8 +128,8 @@ class participantsaction extends Survey_Common_Action
} }
} }
$fieldNeededKeys=array_fill_keys($fields, '');
$fieldKeys = array_flip($fields); $fieldKeys = array_flip($fields);
$fieldNeededKeys=array_fill_keys($outputarray[0], '');
foreach ($query as $field => $aData) foreach ($query as $field => $aData)
{ {
$outputarray[] = array_merge($fieldNeededKeys,array_intersect_key($aData, $fieldKeys)); $outputarray[] = array_merge($fieldNeededKeys,array_intersect_key($aData, $fieldKeys));
@ -400,9 +400,9 @@ class participantsaction extends Survey_Common_Action
$aData->total = ceil(ParticipantAttributeName::model()->getCPDBAttributes(true) / $limit); $aData->total = ceil(ParticipantAttributeName::model()->getCPDBAttributes(true) / $limit);
$i = 0; $i = 0;
foreach($records as $row) { //Iterate through each attribute foreach($records as $row) { //Iterate through each attribute
$sAttributeCaption=$row->defaultname; //Choose the first item by default $sAttributeCaption=htmlspecialchars($row->defaultname); //Choose the first item by default
foreach($row->participant_attribute_names_lang as $names) { //Iterate through each language version of this attribute foreach($row->participant_attribute_names_lang as $names) { //Iterate through each language version of this attribute
if($names->lang == Yii::app()->session['adminlang']) {$sAttributeCaption= $sAttributeCaption." ({$names->attribute_name})";} //Override the default with the admin language version if found if($names->lang == Yii::app()->session['adminlang']) {$sAttributeCaption= $sAttributeCaption.htmlspecialchars(" ({$names->attribute_name})");} //Override the default with the admin language version if found
} }
$aData->rows[$i]['id'] = $row->attribute_id; $aData->rows[$i]['id'] = $row->attribute_id;
$aData->rows[$i]['cell'] = array('', $sAttributeCaption, $attribute_types[$row->attribute_type], $row->visible); $aData->rows[$i]['cell'] = array('', $sAttributeCaption, $attribute_types[$row->attribute_type], $row->visible);
@ -763,22 +763,23 @@ class participantsaction extends Survey_Common_Action
*/ */
function getParticipants_json($search = null) function getParticipants_json($search = null)
{ {
$page = Yii::app()->request->getPost('page'); $page = (int) Yii::app()->request->getPost('page');
$limit = Yii::app()->request->getPost('rows'); $limit = (int) Yii::app()->request->getPost('rows');
$limit = isset($limit) ? $limit : 50; //Stop division by zero errors $limit = empty($limit) ? 50:$limit; //Stop division by zero errors
$attid = ParticipantAttributeName::model()->getVisibleAttributes(); $attid = ParticipantAttributeName::model()->getVisibleAttributes();
$participantfields = array('participant_id', 'can_edit', 'firstname', 'lastname', 'email', 'blacklisted', 'survey', 'language', 'owner_uid'); $participantfields = array('participant_id', 'can_edit', 'firstname', 'lastname', 'email', 'blacklisted', 'survey', 'language', 'owner_uid');
foreach ($attid as $key => $value) foreach ($attid as $key => $value)
{ {
array_push($participantfields, $value['attribute_id']); array_push($participantfields, 'a'.$value['attribute_id']);
} }
$sidx = Yii::app()->request->getPost('sidx'); $sidx = Yii::app()->request->getPost('sidx');
$sidx = !empty($sidx) ? $sidx : "lastname"; $sidx = in_array($sidx,$participantfields) ? $sidx : "lastname";
$sord = Yii::app()->request->getPost('sord'); $sord = Yii::app()->request->getPost('sord');
$sord = !empty($sord) ? $sord : "asc"; $sord = ($sord=='desc') ? 'desc' : 'asc';
$order = $sidx. " ". $sord; $order = $sidx. " ". $sord;
$aData = new stdClass; $aData = new stdClass;
//If super admin all the participants will be visible //If super admin all the participants will be visible
@ -834,7 +835,7 @@ class participantsaction extends Survey_Common_Action
*/ */
function getAttribute_json() function getAttribute_json()
{ {
$iParticipantId = Yii::app()->request->getQuery('pid'); $iParticipantId = strip_tags(Yii::app()->request->getQuery('pid'));
$records = ParticipantAttributeName::model()->getParticipantVisibleAttribute($iParticipantId); $records = ParticipantAttributeName::model()->getParticipantVisibleAttribute($iParticipantId);
$records = subval_sort($records, "attribute_name", "asc"); $records = subval_sort($records, "attribute_name", "asc");
@ -1095,10 +1096,20 @@ class participantsaction extends Survey_Common_Action
$sFileName = $_FILES['the_file']['name']; $sFileName = $_FILES['the_file']['name'];
$regularfields = array('firstname', 'participant_id', 'lastname', 'email', 'language', 'blacklisted', 'owner_uid'); $regularfields = array('firstname', 'participant_id', 'lastname', 'email', 'language', 'blacklisted', 'owner_uid');
$csvread = fopen($sFilePath, 'r'); $oCSVFile = fopen($sFilePath, 'r');
$aFirstLine = fgets($oCSVFile);
rewind($oCSVFile);
$separator = Yii::app()->request->getPost('separatorused'); $sSeparator = Yii::app()->request->getPost('separatorused');
$firstline = fgetcsv($csvread, 1000, ','); if ($sSeparator=='auto')
{
$aCount[',']=substr_count($aFirstLine,',');
$aCount[';']=substr_count($aFirstLine,';');
$aCount['|']=substr_count($aFirstLine,'|');
$aResult = array_keys($aCount, max($aCount));
$sSeparator=$aResult[0];
}
$firstline = fgetcsv($oCSVFile, 1000, $sSeparator[0]);
$selectedcsvfields = array(); $selectedcsvfields = array();
foreach ($firstline as $key => $value) foreach ($firstline as $key => $value)
{ {
@ -1242,7 +1253,7 @@ class participantsaction extends Survey_Common_Action
$separator = ';'; else $separator = ';'; else
$separator = ','; $separator = ',';
} }
$firstline = convertCSVRowToArray($buffer, $separator, '"'); $firstline = str_getcsv($buffer, $separator, '"');
$firstline = array_map('trim', $firstline); $firstline = array_map('trim', $firstline);
$ignoredcolumns = array(); $ignoredcolumns = array();
//now check the first line for invalid fields //now check the first line for invalid fields
@ -1264,7 +1275,7 @@ class participantsaction extends Survey_Common_Action
} }
} else { } else {
// After looking at the first line, we now import the actual values // After looking at the first line, we now import the actual values
$line = convertCSVRowToArray($buffer, $separator, '"'); $line = str_getcsv($buffer, $separator, '"');
// Discard lines where the number of fields do not match // Discard lines where the number of fields do not match
if (count($firstline) != count($line)) if (count($firstline) != count($line))
{ {
@ -1512,30 +1523,6 @@ class participantsaction extends Survey_Common_Action
} }
} }
/*
* Responsible for adding the participant to the specified survey
*/
function addToToken()
{
$response = Participant::model()->copytoSurvey(Yii::app()->request
->getPost('participantid'),
Yii::app()->request
->getPost('surveyid'), Yii::app()
->request->getPost('attributeid')
);
$clang = $this->getController()->lang;
printf($clang->gT("%s participants have been copied to the survey token table"), $response['success']);
if($response['duplicate']>0) {
echo "\r\n";
printf($clang->gT("%s entries were not copied because they already existed"), $response['duplicate']);
}
if($response['overwrite']=="true") {
echo "\r\n";
$clang->eT("Attribute values for existing participants have been updated from the participants records");
}
}
/* /*
* Responsible for adding the participant to the specified survey with attribute mapping * Responsible for adding the participant to the specified survey with attribute mapping
*/ */

View file

@ -31,25 +31,26 @@ class printablesurvey extends Survey_Common_Action
$surveyid = sanitize_int($surveyid); $surveyid = sanitize_int($surveyid);
if(!Permission::model()->hasSurveyPermission($surveyid,'surveycontent','read')) if(!Permission::model()->hasSurveyPermission($surveyid,'surveycontent','read'))
{ {
$clang = $this->getController()->lang;
$aData['surveyid'] = $surveyid; $aData['surveyid'] = $surveyid;
App()->getClientScript()->registerPackage('jquery-superfish'); App()->getClientScript()->registerPackage('jquery-superfish');
$message['title']= $clang->gT('Access denied!'); $message['title']= gT('Access denied!');
$message['message']= $clang->gT('You do not have sufficient rights to access this page.'); $message['message']= gT('You do not have sufficient rights to access this page.');
$message['class']= "error"; $message['class']= "error";
$this->_renderWrappedTemplate('survey', array("message"=>$message), $aData); $this->_renderWrappedTemplate('survey', array("message"=>$message), $aData);
} }
else else
{ {
$aSurveyInfo=getSurveyInfo($surveyid,$lang); $oSurvey=Survey::model()->findByPk($surveyid);
if (!($aSurveyInfo)) if (!$oSurvey)
$this->getController()->error('Invalid survey ID'); $this->getController()->error('Invalid survey ID');
// Be sure to have a valid language //Language
$surveyprintlang=$aSurveyInfo['surveyls_language']; if(!in_array($lang,$oSurvey->getAllLanguages()))
$lang=$oSurvey->language;
// Setting the selected language for printout // Start EM fore expression
$clang = new limesurvey_lang($surveyprintlang); LimeExpressionManager::SetSurveyId($surveyid);
SetSurveyLanguage($surveyid,$lang);
$aSurveyInfo=getSurveyInfo($surveyid,$lang);
$templatename = validateTemplateDir($aSurveyInfo['templatedir']); $templatename = validateTemplateDir($aSurveyInfo['templatedir']);
$welcome = $aSurveyInfo['surveyls_welcometext']; $welcome = $aSurveyInfo['surveyls_welcometext'];
$end = $aSurveyInfo['surveyls_endtext']; $end = $aSurveyInfo['surveyls_endtext'];
@ -77,7 +78,7 @@ class printablesurvey extends Survey_Common_Action
{ {
$surveyexpirydate .= ' &ndash; '.$expirytimeofday_h.':'.$expirytimeofday_m; $surveyexpirydate .= ' &ndash; '.$expirytimeofday_h.':'.$expirytimeofday_m;
}; };
sprintf($clang->gT("Please submit by %s"), $surveyexpirydate); sprintf(gT("Please submit by %s"), $surveyexpirydate);
} }
else else
{ {
@ -104,7 +105,7 @@ class printablesurvey extends Survey_Common_Action
LimeExpressionManager::StartSurvey($surveyid, 'survey',NULL,false,LEM_PRETTY_PRINT_ALL_SYNTAX); LimeExpressionManager::StartSurvey($surveyid, 'survey',NULL,false,LEM_PRETTY_PRINT_ALL_SYNTAX);
$moveResult = LimeExpressionManager::NavigateForwards(); $moveResult = LimeExpressionManager::NavigateForwards();
$condition = "sid = '{$surveyid}' AND language = '{$surveyprintlang}'"; $condition = "sid = '{$surveyid}' AND language = '{$lang}'";
$degresult = QuestionGroup::model()->getAllGroups($condition, array('group_order')); //xiao, $degresult = QuestionGroup::model()->getAllGroups($condition, array('group_order')); //xiao,
if (!isset($surveyfaxto) || !$surveyfaxto and isset($surveyfaxnumber)) if (!isset($surveyfaxto) || !$surveyfaxto and isset($surveyfaxnumber))
@ -119,7 +120,7 @@ class printablesurvey extends Survey_Common_Action
$showsgqacode = Yii::app()->getConfig("showsgqacode"); $showsgqacode = Yii::app()->getConfig("showsgqacode");
if(isset($showsgqacode) && $showsgqacode == true) if(isset($showsgqacode) && $showsgqacode == true)
{ {
$surveyname = $surveyname."<br />[".$clang->gT('Database')." ".$clang->gT('table').": $surveytable]"; $surveyname = $surveyname."<br />[".gT('Database')." ".gT('table').": $surveytable]";
} }
else else
{ {
@ -133,9 +134,9 @@ class printablesurvey extends Survey_Common_Action
,'WELCOME' => $welcome ,'WELCOME' => $welcome
,'END' => $end ,'END' => $end
,'THEREAREXQUESTIONS' => 0 ,'THEREAREXQUESTIONS' => 0
,'SUBMIT_TEXT' => $clang->gT("Submit Your Survey.") ,'SUBMIT_TEXT' => gT("Submit Your Survey.")
,'SUBMIT_BY' => $surveyexpirydate ,'SUBMIT_BY' => $surveyexpirydate
,'THANKS' => $clang->gT("Thank you for completing this survey.") ,'THANKS' => gT("Thank you for completing this survey.")
,'HEADELEMENTS' => $headelements ,'HEADELEMENTS' => $headelements
,'TEMPLATEURL' => PRINT_TEMPLATE_URL ,'TEMPLATEURL' => PRINT_TEMPLATE_URL
,'FAXTO' => $surveyfaxto ,'FAXTO' => $surveyfaxto
@ -146,7 +147,7 @@ class printablesurvey extends Survey_Common_Action
$survey_output['FAX_TO'] =''; $survey_output['FAX_TO'] ='';
if(!empty($surveyfaxto) && $surveyfaxto != '000-00000000') //If no fax number exists, don't display faxing information! if(!empty($surveyfaxto) && $surveyfaxto != '000-00000000') //If no fax number exists, don't display faxing information!
{ {
$survey_output['FAX_TO'] = $clang->gT("Please fax your completed survey to:")." $surveyfaxto"; $survey_output['FAX_TO'] = gT("Please fax your completed survey to:")." $surveyfaxto";
} }
@ -154,7 +155,7 @@ class printablesurvey extends Survey_Common_Action
$mapquestionsNumbers=Array(); $mapquestionsNumbers=Array();
$answertext = ''; // otherwise can throw an error on line 1617 $answertext = ''; // otherwise can throw an error on line 1617
$fieldmap = createFieldMap($surveyid,'full',false,false,$surveyprintlang); $fieldmap = createFieldMap($surveyid,'full',false,false,$lang);
// ========================================================= // =========================================================
// START doin the business: // START doin the business:
@ -162,7 +163,7 @@ class printablesurvey extends Survey_Common_Action
{ {
// --------------------------------------------------- // ---------------------------------------------------
// START doing groups // START doing groups
$deqresult=Question::model()->getQuestions($surveyid, $degrow['gid'], $surveyprintlang, 0, '"I"'); $deqresult=Question::model()->getQuestions($surveyid, $degrow['gid'], $lang, 0, '"I"');
$deqrows = array(); //Create an empty array in case FetchRow does not return any rows $deqrows = array(); //Create an empty array in case FetchRow does not return any rows
foreach ($deqresult->readAll() as $deqrow) {$deqrows[] = $deqrow;} // Get table output into array foreach ($deqresult->readAll() as $deqrow) {$deqrows[] = $deqrow;} // Get table output into array
@ -228,7 +229,7 @@ class printablesurvey extends Survey_Common_Action
} }
if($s > 0) if($s > 0)
{ {
$sExplanation .= '<p class="scenario">'.' -------- '.$clang->gT("or")." Scenario {$scenariorow['scenario']} --------</p>\n\n"; $sExplanation .= '<p class="scenario">'.' -------- '.gT("or")." Scenario {$scenariorow['scenario']} --------</p>\n\n";
} }
$x=0; $x=0;
@ -239,12 +240,12 @@ class printablesurvey extends Survey_Common_Action
//Loop through each condition for a particular scenario. //Loop through each condition for a particular scenario.
foreach ($distinctresult->readAll() as $distinctrow) foreach ($distinctresult->readAll() as $distinctrow)
{ {
$condition = "qid = '{$distinctrow['cqid']}' AND parent_qid = 0 AND language = '{$surveyprintlang}'"; $condition = "qid = '{$distinctrow['cqid']}' AND parent_qid = 0 AND language = '{$lang}'";
$subresult=Question::model()->find($condition); $subresult=Question::model()->find($condition);
if($x > 0) if($x > 0)
{ {
$sExplanation .= ' <em class="scenario-and-separator">'.$clang->gT('and').'</em> '; $sExplanation .= ' <em class="scenario-and-separator">'.gT('and').'</em> ';
} }
if(trim($distinctrow['method'])=='') //If there is no method chosen assume "equals" if(trim($distinctrow['method'])=='') //If there is no method chosen assume "equals"
{ {
@ -254,35 +255,35 @@ class printablesurvey extends Survey_Common_Action
if($distinctrow['cqid']){ // cqid != 0 ==> previous answer match if($distinctrow['cqid']){ // cqid != 0 ==> previous answer match
if($distinctrow['method']=='==') if($distinctrow['method']=='==')
{ {
$sExplanation .= $clang->gT("Answer was")." "; $sExplanation .= gT("Answer was")." ";
} }
elseif($distinctrow['method']=='!=') elseif($distinctrow['method']=='!=')
{ {
$sExplanation .= $clang->gT("Answer was NOT")." "; $sExplanation .= gT("Answer was NOT")." ";
} }
elseif($distinctrow['method']=='<') elseif($distinctrow['method']=='<')
{ {
$sExplanation .= $clang->gT("Answer was less than")." "; $sExplanation .= gT("Answer was less than")." ";
} }
elseif($distinctrow['method']=='<=') elseif($distinctrow['method']=='<=')
{ {
$sExplanation .= $clang->gT("Answer was less than or equal to")." "; $sExplanation .= gT("Answer was less than or equal to")." ";
} }
elseif($distinctrow['method']=='>=') elseif($distinctrow['method']=='>=')
{ {
$sExplanation .= $clang->gT("Answer was greater than or equal to")." "; $sExplanation .= gT("Answer was greater than or equal to")." ";
} }
elseif($distinctrow['method']=='>') elseif($distinctrow['method']=='>')
{ {
$sExplanation .= $clang->gT("Answer was greater than")." "; $sExplanation .= gT("Answer was greater than")." ";
} }
elseif($distinctrow['method']=='RX') elseif($distinctrow['method']=='RX')
{ {
$sExplanation .= $clang->gT("Answer matched (regexp)")." "; $sExplanation .= gT("Answer matched (regexp)")." ";
} }
else else
{ {
$sExplanation .= $clang->gT("Answer was")." "; $sExplanation .= gT("Answer was")." ";
} }
} }
if(!$distinctrow['cqid']) { // cqid == 0 ==> token attribute match if(!$distinctrow['cqid']) { // cqid == 0 ==> token attribute match
@ -291,40 +292,40 @@ class printablesurvey extends Survey_Common_Action
$sExplanation .= "Your ".$tokenData[strtolower($extractedTokenAttr[1])]['description']." "; $sExplanation .= "Your ".$tokenData[strtolower($extractedTokenAttr[1])]['description']." ";
if($distinctrow['method']=='==') if($distinctrow['method']=='==')
{ {
$sExplanation .= $clang->gT("is")." "; $sExplanation .= gT("is")." ";
} }
elseif($distinctrow['method']=='!=') elseif($distinctrow['method']=='!=')
{ {
$sExplanation .= $clang->gT("is NOT")." "; $sExplanation .= gT("is NOT")." ";
} }
elseif($distinctrow['method']=='<') elseif($distinctrow['method']=='<')
{ {
$sExplanation .= $clang->gT("is less than")." "; $sExplanation .= gT("is less than")." ";
} }
elseif($distinctrow['method']=='<=') elseif($distinctrow['method']=='<=')
{ {
$sExplanation .= $clang->gT("is less than or equal to")." "; $sExplanation .= gT("is less than or equal to")." ";
} }
elseif($distinctrow['method']=='>=') elseif($distinctrow['method']=='>=')
{ {
$sExplanation .= $clang->gT("is greater than or equal to")." "; $sExplanation .= gT("is greater than or equal to")." ";
} }
elseif($distinctrow['method']=='>') elseif($distinctrow['method']=='>')
{ {
$sExplanation .= $clang->gT("is greater than")." "; $sExplanation .= gT("is greater than")." ";
} }
elseif($distinctrow['method']=='RX') elseif($distinctrow['method']=='RX')
{ {
$sExplanation .= $clang->gT("is matched (regexp)")." "; $sExplanation .= gT("is matched (regexp)")." ";
} }
else else
{ {
$sExplanation .= $clang->gT("is")." "; $sExplanation .= gT("is")." ";
} }
$answer_section = ' '.$distinctrow['value'].' '; $answer_section = ' '.$distinctrow['value'].' ';
} }
$conresult=Condition::model()->getConditionsQuestions($distinctrow['cqid'],$deqrow['qid'],$scenariorow['scenario'],$surveyprintlang); $conresult=Condition::model()->getConditionsQuestions($distinctrow['cqid'],$deqrow['qid'],$scenariorow['scenario'],$lang);
$conditions=array(); $conditions=array();
foreach ($conresult->readAll() as $conrow) foreach ($conresult->readAll() as $conrow)
@ -337,15 +338,15 @@ class printablesurvey extends Survey_Common_Action
case "Y": case "Y":
switch ($conrow['value']) switch ($conrow['value'])
{ {
case "Y": $conditions[]=$clang->gT("Yes"); break; case "Y": $conditions[]=gT("Yes"); break;
case "N": $conditions[]=$clang->gT("No"); break; case "N": $conditions[]=gT("No"); break;
} }
break; break;
case "G": case "G":
switch($conrow['value']) switch($conrow['value'])
{ {
case "M": $conditions[]=$clang->gT("Male"); break; case "M": $conditions[]=gT("Male"); break;
case "F": $conditions[]=$clang->gT("Female"); break; case "F": $conditions[]=gT("Female"); break;
} // switch } // switch
break; break;
case "A": case "A":
@ -358,24 +359,24 @@ class printablesurvey extends Survey_Common_Action
case "C": case "C":
switch($conrow['value']) switch($conrow['value'])
{ {
case "Y": $conditions[]=$clang->gT("Yes"); break; case "Y": $conditions[]=gT("Yes"); break;
case "U": $conditions[]=$clang->gT("Uncertain"); break; case "U": $conditions[]=gT("Uncertain"); break;
case "N": $conditions[]=$clang->gT("No"); break; case "N": $conditions[]=gT("No"); break;
} // switch } // switch
break; break;
case "E": case "E":
switch($conrow['value']) switch($conrow['value'])
{ {
case "I": $conditions[]=$clang->gT("Increase"); break; case "I": $conditions[]=gT("Increase"); break;
case "D": $conditions[]=$clang->gT("Decrease"); break; case "D": $conditions[]=gT("Decrease"); break;
case "S": $conditions[]=$clang->gT("Same"); break; case "S": $conditions[]=gT("Same"); break;
} }
case "1": case "1":
$labelIndex=preg_match("/^[^#]+#([01]{1})$/",$conrow['cfieldname']); $labelIndex=preg_match("/^[^#]+#([01]{1})$/",$conrow['cfieldname']);
if ($labelIndex == 0) if ($labelIndex == 0)
{ // TIBO { // TIBO
$condition="qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND scale_id=0 AND language='{$surveyprintlang}'"; $condition="qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND scale_id=0 AND language='{$lang}'";
$fresult=Answer::model()->getAllRecords($condition); $fresult=Answer::model()->getAllRecords($condition);
foreach($fresult->readAll() as $frow) foreach($fresult->readAll() as $frow)
@ -387,7 +388,7 @@ class printablesurvey extends Survey_Common_Action
elseif ($labelIndex == 1) elseif ($labelIndex == 1)
{ {
$condition="qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND scale_id=1 AND language='{$surveyprintlang}'"; $condition="qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND scale_id=1 AND language='{$lang}'";
$fresult=Answer::model()->getAllRecords($condition); $fresult=Answer::model()->getAllRecords($condition);
foreach($fresult->readAll() as $frow) foreach($fresult->readAll() as $frow)
{ {
@ -400,7 +401,7 @@ class printablesurvey extends Survey_Common_Action
case "!": case "!":
case "O": case "O":
case "R": case "R":
$condition="qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND language='{$surveyprintlang}'"; $condition="qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND language='{$lang}'";
$ansresult=Answer::model()->findAll($condition); $ansresult=Answer::model()->findAll($condition);
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
@ -408,13 +409,13 @@ class printablesurvey extends Survey_Common_Action
$conditions[]=$ansrow['answer']; $conditions[]=$ansrow['answer'];
} }
if($conrow['value'] == "-oth-") { if($conrow['value'] == "-oth-") {
$conditions[]=$clang->gT("Other"); $conditions[]=gT("Other");
} }
$conditions = array_unique($conditions); $conditions = array_unique($conditions);
break; break;
case "M": case "M":
case "P": case "P":
$condition=" parent_qid='{$conrow['cqid']}' AND title='{$conrow['value']}' AND language='{$surveyprintlang}'"; $condition=" parent_qid='{$conrow['cqid']}' AND title='{$conrow['value']}' AND language='{$lang}'";
$ansresult=Question::model()->findAll($condition); $ansresult=Question::model()->findAll($condition);
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
{ {
@ -431,7 +432,7 @@ class printablesurvey extends Survey_Common_Action
default: default:
$value=substr($conrow['cfieldname'], strpos($conrow['cfieldname'], "X".$conrow['cqid'])+strlen("X".$conrow['cqid']), strlen($conrow['cfieldname'])); $value=substr($conrow['cfieldname'], strpos($conrow['cfieldname'], "X".$conrow['cqid'])+strlen("X".$conrow['cqid']), strlen($conrow['cfieldname']));
$condition=" qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND language='{$surveyprintlang}'"; $condition=" qid='{$conrow['cqid']}' AND code='{$conrow['value']}' AND language='{$lang}'";
$fresult=Answer::model()->getAllRecords($condition); $fresult=Answer::model()->getAllRecords($condition);
foreach ($fresult->readAll() as $frow) foreach ($fresult->readAll() as $frow)
@ -454,7 +455,7 @@ class printablesurvey extends Survey_Common_Action
case "H": case "H":
case "K": case "K":
$thiscquestion=$fieldmap[$conrow['cfieldname']]; $thiscquestion=$fieldmap[$conrow['cfieldname']];
$condition="parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$surveyprintlang}'"; $condition="parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$lang}'";
$ansresult= Question::model()->findAll($condition); $ansresult= Question::model()->findAll($condition);
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
@ -466,39 +467,39 @@ class printablesurvey extends Survey_Common_Action
case "1": // dual: (Label 1), (Label 2) case "1": // dual: (Label 1), (Label 2)
$labelIndex=substr($conrow['cfieldname'],-1); $labelIndex=substr($conrow['cfieldname'],-1);
$thiscquestion=$fieldmap[$conrow['cfieldname']]; $thiscquestion=$fieldmap[$conrow['cfieldname']];
$condition="parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$surveyprintlang}'"; $condition="parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$lang}'";
$ansresult= Question::model()->findAll($condition); $ansresult= Question::model()->findAll($condition);
$cqidattributes = getQuestionAttributeValues($conrow['cqid'], $conrow['type']); $cqidattributes = getQuestionAttributeValues($conrow['cqid'], $conrow['type']);
if ($labelIndex == 0) if ($labelIndex == 0)
{ {
if (trim($cqidattributes['dualscale_headerA'][$surveyprintlang]) != '') { if (trim($cqidattributes['dualscale_headerA'][$lang]) != '') {
$header = $clang->gT($cqidattributes['dualscale_headerA'][$surveyprintlang]); $header = gT($cqidattributes['dualscale_headerA'][$lang]);
} else { } else {
$header = '1'; $header = '1';
} }
} }
elseif ($labelIndex == 1) elseif ($labelIndex == 1)
{ {
if (trim($cqidattributes['dualscale_headerB'][$surveyprintlang]) != '') { if (trim($cqidattributes['dualscale_headerB'][$lang]) != '') {
$header = $clang->gT($cqidattributes['dualscale_headerB'][$surveyprintlang]); $header = gT($cqidattributes['dualscale_headerB'][$lang]);
} else { } else {
$header = '2'; $header = '2';
} }
} }
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
{ {
$answer_section=" (".$ansrow->question." ".sprintf($clang->gT("Label %s"),$header).")"; $answer_section=" (".$ansrow->question." ".sprintf(gT("Label %s"),$header).")";
} }
break; break;
case ":": case ":":
case ";": //multi flexi: ( answer [label] ) case ";": //multi flexi: ( answer [label] )
$thiscquestion=$fieldmap[$conrow['cfieldname']]; $thiscquestion=$fieldmap[$conrow['cfieldname']];
$condition="parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$surveyprintlang}'"; $condition="parent_qid='{$conrow['cqid']}' AND title='{$thiscquestion['aid']}' AND language='{$lang}'";
$ansresult= Question::model()->findAll($condition); $ansresult= Question::model()->findAll($condition);
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
{ {
$condition = "qid = '{$conrow['cqid']}' AND code = '{$conrow['value']}' AND language= '{$surveyprintlang}'"; $condition = "qid = '{$conrow['cqid']}' AND code = '{$conrow['value']}' AND language= '{$lang}'";
$fresult= Answer::model()->findAll($condition); $fresult= Answer::model()->findAll($condition);
foreach ($fresult as $frow) foreach ($fresult as $frow)
{ {
@ -510,7 +511,7 @@ class printablesurvey extends Survey_Common_Action
case "R": // (Rank 1), (Rank 2)... TIBO case "R": // (Rank 1), (Rank 2)... TIBO
$thiscquestion=$fieldmap[$conrow['cfieldname']]; $thiscquestion=$fieldmap[$conrow['cfieldname']];
$rankid=$thiscquestion['aid']; $rankid=$thiscquestion['aid'];
$answer_section=" (".$clang->gT("RANK")." $rankid)"; $answer_section=" (".gT("RANK")." $rankid)";
break; break;
default: // nothing to add default: // nothing to add
break; break;
@ -519,7 +520,7 @@ class printablesurvey extends Survey_Common_Action
if (count($conditions) > 1) if (count($conditions) > 1)
{ {
$sExplanation .= "'".implode("' <em class='scenario-or-separator'>".$clang->gT("or")."</em> '", $conditions)."'"; $sExplanation .= "'".implode("' <em class='scenario-or-separator'>".gT("or")."</em> '", $conditions)."'";
} }
elseif (count($conditions) == 1) elseif (count($conditions) == 1)
{ {
@ -527,9 +528,9 @@ class printablesurvey extends Survey_Common_Action
} }
unset($conditions); unset($conditions);
// Following line commented out because answer_section was lost, but is required for some question types // Following line commented out because answer_section was lost, but is required for some question types
//$explanation .= " ".$clang->gT("to question")." '".$mapquestionsNumbers[$distinctrow['cqid']]."' $answer_section "; //$explanation .= " ".gT("to question")." '".$mapquestionsNumbers[$distinctrow['cqid']]."' $answer_section ";
if($distinctrow['cqid']){ if($distinctrow['cqid']){
$sExplanation .= " <span class='scenario-at-separator'>".$clang->gT("at question")."</span> '".$mapquestionsNumbers[$distinctrow['cqid']]." [".$subresult['title']."]' (".strip_tags($subresult['question'])."$answer_section)" ; $sExplanation .= " <span class='scenario-at-separator'>".gT("at question")."</span> '".$mapquestionsNumbers[$distinctrow['cqid']]." [".$subresult['title']."]' (".strip_tags($subresult['question'])."$answer_section)" ;
} }
else{ else{
$sExplanation .= " ".$distinctrow['value'] ; $sExplanation .= " ".$distinctrow['value'] ;
@ -546,16 +547,16 @@ class printablesurvey extends Survey_Common_Action
if (trim($relevance) != '' && trim($relevance) != '1') if (trim($relevance) != '' && trim($relevance) != '1')
{ {
if (isset($qidattributes['printable_help'][$surveyprintlang]) && $qidattributes['printable_help'][$surveyprintlang]!='') if (isset($qidattributes['printable_help'][$lang]) && $qidattributes['printable_help'][$lang]!='')
{ {
$sExplanation=$qidattributes['printable_help'][$surveyprintlang]; $sExplanation=$qidattributes['printable_help'][$lang];
} }
elseif ($sExplanation=='') // There is only a relevance equation without conditions elseif ($sExplanation=='') // There is only a relevance equation without conditions
{ {
$sExplanation=$sEquation; $sExplanation=$sEquation;
$sEquation='&nbsp;'; // No need to show it twice $sEquation='&nbsp;'; // No need to show it twice
} }
$sExplanation = "<b>".$clang->gT('Only answer this question if the following conditions are met:')."</b><br/> ".$sExplanation; $sExplanation = "<b>".gT('Only answer this question if the following conditions are met:')."</b><br/> ".$sExplanation;
if (Yii::app()->getConfig('showrelevance')) if (Yii::app()->getConfig('showrelevance'))
{ {
$sExplanation.="<span class='printable_equation'><br>".$sEquation."</span>"; $sExplanation.="<span class='printable_equation'><br>".$sEquation."</span>";
@ -577,8 +578,8 @@ class printablesurvey extends Survey_Common_Action
if(isset($showsgqacode) && $showsgqacode == true) if(isset($showsgqacode) && $showsgqacode == true)
{ {
$deqrow['question'] = $deqrow['question']."<br />".$clang->gT("ID:")." $fieldname <br />". $deqrow['question'] = $deqrow['question']."<br />".gT("ID:")." $fieldname <br />".
$clang->gT("Question code:")." ".$deqrow['title']; gT("Question code:")." ".$deqrow['title'];
} }
$question = array( $question = array(
@ -613,7 +614,7 @@ class printablesurvey extends Survey_Common_Action
if ($deqrow['mandatory'] == 'Y') if ($deqrow['mandatory'] == 'Y')
{ {
$question['QUESTION_MANDATORY'] = $clang->gT('*'); $question['QUESTION_MANDATORY'] = gT('*');
$question['QUESTION_CLASS'] .= ' mandatory'; $question['QUESTION_CLASS'] .= ' mandatory';
} }
@ -639,7 +640,7 @@ class printablesurvey extends Survey_Common_Action
{ {
// ================================================================== // ==================================================================
case "5": //5 POINT CHOICE case "5": //5 POINT CHOICE
$question['QUESTION_TYPE_HELP'] .= $clang->gT('Please choose *only one* of the following:'); $question['QUESTION_TYPE_HELP'] .= gT('Please choose *only one* of the following:');
$question['ANSWER'] .= "\n\t<ul>\n"; $question['ANSWER'] .= "\n\t<ul>\n";
for ($i=1; $i<=5; $i++) for ($i=1; $i<=5; $i++)
{ {
@ -651,17 +652,17 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "D": //DATE case "D": //DATE
$question['QUESTION_TYPE_HELP'] .= $clang->gT('Please enter a date:'); $question['QUESTION_TYPE_HELP'] .= gT('Please enter a date:');
$question['ANSWER'] .= "\t".self::_input_type_image('text',$question['QUESTION_TYPE_HELP'],30,1); $question['ANSWER'] .= "\t".self::_input_type_image('text',$question['QUESTION_TYPE_HELP'],30,1);
break; break;
// ================================================================== // ==================================================================
case "G": //GENDER case "G": //GENDER
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose *only one* of the following:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:");
$question['ANSWER'] .= "\n\t<ul>\n"; $question['ANSWER'] .= "\n\t<ul>\n";
$question['ANSWER'] .= "\t\t<li>\n\t\t\t".self::_input_type_image('radio',$clang->gT("Female"))."\n\t\t\t".$clang->gT("Female")." ".self::_addsgqacode("(F)")."\n\t\t</li>\n"; $question['ANSWER'] .= "\t\t<li>\n\t\t\t".self::_input_type_image('radio',gT("Female"))."\n\t\t\t".gT("Female")." ".self::_addsgqacode("(F)")."\n\t\t</li>\n";
$question['ANSWER'] .= "\t\t<li>\n\t\t\t".self::_input_type_image('radio',$clang->gT("Male"))."\n\t\t\t".$clang->gT("Male")." ".self::_addsgqacode("(M)")."\n\t\t</li>\n"; $question['ANSWER'] .= "\t\t<li>\n\t\t\t".self::_input_type_image('radio',gT("Male"))."\n\t\t\t".gT("Male")." ".self::_addsgqacode("(M)")."\n\t\t</li>\n";
$question['ANSWER'] .= "\t</ul>\n"; $question['ANSWER'] .= "\t</ul>\n";
break; break;
@ -686,10 +687,10 @@ class printablesurvey extends Survey_Common_Action
unset($optCategorySeparator); unset($optCategorySeparator);
} }
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose *only one* of the following:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$dearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' ", array('sortorder','answer')); $dearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$lang}' ", array('sortorder','answer'));
$dearesult=$dearesult->readAll(); $dearesult=$dearesult->readAll();
$deacount=count($dearesult); $deacount=count($dearesult);
if ($deqrow['other'] == "Y") {$deacount++;} if ($deqrow['other'] == "Y") {$deacount++;}
@ -737,10 +738,10 @@ class printablesurvey extends Survey_Common_Action
} }
if ($deqrow['other'] == 'Y') if ($deqrow['other'] == 'Y')
{ {
if(trim($qidattributes["other_replace_text"][$surveyprintlang])=='') if(trim($qidattributes["other_replace_text"][$lang])=='')
{$qidattributes["other_replace_text"][$surveyprintlang]="Other";} {$qidattributes["other_replace_text"][$lang]="Other";}
// $printablesurveyoutput .="\t".$wrapper['item-start']."\t\t".self::_input_type_image('radio' , $clang->gT("Other"))."\n\t\t\t".$clang->gT("Other")."\n\t\t\t<input type='text' size='30' readonly='readonly' />\n".$wrapper['item-end']; // $printablesurveyoutput .="\t".$wrapper['item-start']."\t\t".self::_input_type_image('radio' , gT("Other"))."\n\t\t\t".gT("Other")."\n\t\t\t<input type='text' size='30' readonly='readonly' />\n".$wrapper['item-end'];
$question['ANSWER'] .= $wrapper['item-start-other'].self::_input_type_image('radio',$clang->gT($qidattributes["other_replace_text"][$surveyprintlang])).' '.$clang->gT($qidattributes["other_replace_text"][$surveyprintlang]).self::_addsgqacode(" (-oth-)")."\n\t\t\t".self::_input_type_image('other').self::_addsgqacode(" (".$deqrow['sid']."X".$deqrow['gid']."X".$deqrow['qid']."other)")."\n".$wrapper['item-end']; $question['ANSWER'] .= $wrapper['item-start-other'].self::_input_type_image('radio',gT($qidattributes["other_replace_text"][$lang])).' '.gT($qidattributes["other_replace_text"][$lang]).self::_addsgqacode(" (-oth-)")."\n\t\t\t".self::_input_type_image('other').self::_addsgqacode(" (".$deqrow['sid']."X".$deqrow['gid']."X".$deqrow['qid']."other)")."\n".$wrapper['item-end'];
} }
$question['ANSWER'] .= $wrapper['whole-end']; $question['ANSWER'] .= $wrapper['whole-end'];
//Let's break the presentation into columns. //Let's break the presentation into columns.
@ -748,8 +749,8 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "O": //LIST WITH COMMENT case "O": //LIST WITH COMMENT
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose *only one* of the following:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:");
$dearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$surveyprintlang}'", array('sortorder', 'answer') ); $dearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$lang}'", array('sortorder', 'answer') );
$question['ANSWER'] = "\t<ul>\n"; $question['ANSWER'] = "\t<ul>\n";
foreach ($dearesult->readAll() as $dearow) foreach ($dearesult->readAll() as $dearow)
@ -758,17 +759,17 @@ class printablesurvey extends Survey_Common_Action
} }
$question['ANSWER'] .= "\t</ul>\n"; $question['ANSWER'] .= "\t</ul>\n";
$question['ANSWER'] .= "\t<p class=\"comment\">\n\t\t".$clang->gT("Make a comment on your choice here:")."\n"; $question['ANSWER'] .= "\t<p class=\"comment\">\n\t\t".gT("Make a comment on your choice here:")."\n";
$question['ANSWER'] .= "\t\t".self::_input_type_image('textarea',$clang->gT("Make a comment on your choice here:"),50,8).self::_addsgqacode(" (".$deqrow['sid']."X".$deqrow['gid']."X".$deqrow['qid']."comment)")."\n\t</p>\n"; $question['ANSWER'] .= "\t\t".self::_input_type_image('textarea',gT("Make a comment on your choice here:"),50,8).self::_addsgqacode(" (".$deqrow['sid']."X".$deqrow['gid']."X".$deqrow['qid']."comment)")."\n\t</p>\n";
break; break;
// ================================================================== // ==================================================================
case "R": //RANKING Type Question case "R": //RANKING Type Question
$rearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$surveyprintlang}'", array('sortorder', 'answer')); $rearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$lang}'", array('sortorder', 'answer'));
$rearesult = $rearesult->readAll(); $rearesult = $rearesult->readAll();
$reacount = count($rearesult); $reacount = count($rearesult);
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please number each box in order of preference from 1 to")." $reacount"; $question['QUESTION_TYPE_HELP'] .= gT("Please number each box in order of preference from 1 to")." $reacount";
$question['QUESTION_TYPE_HELP'] .= self::_min_max_answers_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_min_max_answers_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] = "\n<ul>\n"; $question['ANSWER'] = "\n<ul>\n";
foreach ($rearesult as $rearow) foreach ($rearesult as $rearow)
{ {
@ -788,10 +789,10 @@ class printablesurvey extends Survey_Common_Action
{ {
$dcols=0; $dcols=0;
} }
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose *all* that apply:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose *all* that apply:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' ", array('question_order')); $mearesult = Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$lang}' ", array('question_order'));
$mearesult = $mearesult->readAll(); $mearesult = $mearesult->readAll();
$meacount = count($mearesult); $meacount = count($mearesult);
if ($deqrow['other'] == 'Y') {$meacount++;} if ($deqrow['other'] == 'Y') {$meacount++;}
@ -822,12 +823,12 @@ class printablesurvey extends Survey_Common_Action
} }
if ($deqrow['other'] == "Y") if ($deqrow['other'] == "Y")
{ {
if (trim($qidattributes['other_replace_text'][$surveyprintlang])=='') if (trim($qidattributes['other_replace_text'][$lang])=='')
{ {
$qidattributes["other_replace_text"][$surveyprintlang]="Other"; $qidattributes["other_replace_text"][$lang]="Other";
} }
if(!isset($mearow['answer'])) $mearow['answer']=""; if(!isset($mearow['answer'])) $mearow['answer']="";
$question['ANSWER'] .= $wrapper['item-start-other'].self::_input_type_image('checkbox',$mearow['answer']).$clang->gT($qidattributes["other_replace_text"][$surveyprintlang]).":\n\t\t".self::_input_type_image('other').self::_addsgqacode(" (".$fieldname."other) ").$wrapper['item-end']; $question['ANSWER'] .= $wrapper['item-start-other'].self::_input_type_image('checkbox',$mearow['answer']).gT($qidattributes["other_replace_text"][$lang]).":\n\t\t".self::_input_type_image('other').self::_addsgqacode(" (".$fieldname."other) ").$wrapper['item-end'];
} }
$question['ANSWER'] .= $wrapper['whole-end']; $question['ANSWER'] .= $wrapper['whole-end'];
// } // }
@ -835,11 +836,11 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "P": //Multiple choice with comments case "P": //Multiple choice with comments
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose all that apply and provide a comment:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose all that apply and provide a comment:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$mearesult=Question::model()->getAllRecords("parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}'", array('question_order')); $mearesult=Question::model()->getAllRecords("parent_qid='{$deqrow['qid']}' AND language='{$lang}'", array('question_order'));
// $printablesurveyoutput .="\t\t\t<u>".$clang->gT("Please choose all that apply and provide a comment:")."</u><br />\n"; // $printablesurveyoutput .="\t\t\t<u>".gT("Please choose all that apply and provide a comment:")."</u><br />\n";
$j=0; $j=0;
$longest_string = 0; $longest_string = 0;
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
@ -850,7 +851,7 @@ class printablesurvey extends Survey_Common_Action
} }
if ($deqrow['other'] == "Y") if ($deqrow['other'] == "Y")
{ {
$question['ANSWER'] .= "\t<li class=\"other\">\n\t\t<div class=\"other-replacetext\">".$clang->gT('Other:').self::_input_type_image('other','',1)."</div>".self::_input_type_image('othercomment','comment box',50).self::_addsgqacode(" (".$fieldname."other) ")."\n\t</li>\n"; $question['ANSWER'] .= "\t<li class=\"other\">\n\t\t<div class=\"other-replacetext\">".gT('Other:').self::_input_type_image('other','',1)."</div>".self::_input_type_image('othercomment','comment box',50).self::_addsgqacode(" (".$fieldname."other) ")."\n\t</li>\n";
$j++; $j++;
} }
@ -869,22 +870,22 @@ class printablesurvey extends Survey_Common_Action
// if (!empty($qidattributes['equals_num_value'])) // if (!empty($qidattributes['equals_num_value']))
// { // {
// $question['QUESTION_TYPE_HELP'] .= "* ".sprintf($clang->gT('Total of all entries must equal %d'),$qidattributes['equals_num_value'])."<br />\n"; // $question['QUESTION_TYPE_HELP'] .= "* ".sprintf(gT('Total of all entries must equal %d'),$qidattributes['equals_num_value'])."<br />\n";
// } // }
// if (!empty($qidattributes['max_num_value'])) // if (!empty($qidattributes['max_num_value']))
// { // {
// $question['QUESTION_TYPE_HELP'] .= sprintf($clang->gT('Total of all entries must not exceed %d'), $qidattributes['max_num_value'])."<br />\n"; // $question['QUESTION_TYPE_HELP'] .= sprintf(gT('Total of all entries must not exceed %d'), $qidattributes['max_num_value'])."<br />\n";
// } // }
// if (!empty($qidattributes['min_num_value'])) // if (!empty($qidattributes['min_num_value']))
// { // {
// $question['QUESTION_TYPE_HELP'] .= sprintf($clang->gT('Total of all entries must be at least %s'),$qidattributes['min_num_value'])."<br />\n"; // $question['QUESTION_TYPE_HELP'] .= sprintf(gT('Total of all entries must be at least %s'),$qidattributes['min_num_value'])."<br />\n";
// } // }
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please write your answer(s) here:"); $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer(s) here:");
$longest_string = 0; $longest_string = 0;
$mearesult=Question::model()->getAllRecords("parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}'", array('question_order')); $mearesult=Question::model()->getAllRecords("parent_qid='{$deqrow['qid']}' AND language='{$lang}'", array('question_order'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
$longest_string = longestString($mearow['question'] , $longest_string ); $longest_string = longestString($mearow['question'] , $longest_string );
@ -901,21 +902,21 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "S": //SHORT TEXT case "S": //SHORT TEXT
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please write your answer here:"); $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:");
$question['ANSWER'] = self::_input_type_image('text',$question['QUESTION_TYPE_HELP'], 50); $question['ANSWER'] = self::_input_type_image('text',$question['QUESTION_TYPE_HELP'], 50);
break; break;
// ================================================================== // ==================================================================
case "T": //LONG TEXT case "T": //LONG TEXT
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please write your answer here:"); $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:");
$question['ANSWER'] = self::_input_type_image('textarea',$question['QUESTION_TYPE_HELP'], '100%' , 8); $question['ANSWER'] = self::_input_type_image('textarea',$question['QUESTION_TYPE_HELP'], '100%' , 8);
break; break;
// ================================================================== // ==================================================================
case "U": //HUGE TEXT case "U": //HUGE TEXT
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please write your answer here:"); $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:");
$question['ANSWER'] = self::_input_type_image('textarea',$question['QUESTION_TYPE_HELP'], '100%' , 30); $question['ANSWER'] = self::_input_type_image('textarea',$question['QUESTION_TYPE_HELP'], '100%' , 30);
break; break;
@ -924,29 +925,29 @@ class printablesurvey extends Survey_Common_Action
case "N": //NUMERICAL case "N": //NUMERICAL
$prefix=""; $prefix="";
$suffix=""; $suffix="";
if($qidattributes['prefix'][$surveyprintlang] != "") { if($qidattributes['prefix'][$lang] != "") {
$prefix=$qidattributes['prefix'][$surveyprintlang]; $prefix=$qidattributes['prefix'][$lang];
} }
if($qidattributes['suffix'][$surveyprintlang] != "") { if($qidattributes['suffix'][$lang] != "") {
$suffix=$qidattributes['suffix'][$surveyprintlang]; $suffix=$qidattributes['suffix'][$lang];
} }
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please write your answer here:"); $question['QUESTION_TYPE_HELP'] .= gT("Please write your answer here:");
$question['ANSWER'] = "<ul>\n\t<li>\n\t\t<span>$prefix</span>\n\t\t".self::_input_type_image('text',$question['QUESTION_TYPE_HELP'],20)."\n\t\t<span>$suffix</span>\n\t\t</li>\n\t</ul>"; $question['ANSWER'] = "<ul>\n\t<li>\n\t\t<span>$prefix</span>\n\t\t".self::_input_type_image('text',$question['QUESTION_TYPE_HELP'],20)."\n\t\t<span>$suffix</span>\n\t\t</li>\n\t</ul>";
break; break;
// ================================================================== // ==================================================================
case "Y": //YES/NO case "Y": //YES/NO
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose *only one* of the following:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose *only one* of the following:");
$question['ANSWER'] = "\n<ul>\n\t<li>\n\t\t".self::_input_type_image('radio',$clang->gT('Yes'))."\n\t\t".$clang->gT('Yes').self::_addsgqacode(" (Y)")."\n\t</li>\n"; $question['ANSWER'] = "\n<ul>\n\t<li>\n\t\t".self::_input_type_image('radio',gT('Yes'))."\n\t\t".gT('Yes').self::_addsgqacode(" (Y)")."\n\t</li>\n";
$question['ANSWER'] .= "\n\t<li>\n\t\t".self::_input_type_image('radio',$clang->gT('No'))."\n\t\t".$clang->gT('No').self::_addsgqacode(" (N)")."\n\t</li>\n</ul>\n"; $question['ANSWER'] .= "\n\t<li>\n\t\t".self::_input_type_image('radio',gT('No'))."\n\t\t".gT('No').self::_addsgqacode(" (N)")."\n\t</li>\n</ul>\n";
break; break;
// ================================================================== // ==================================================================
case "A": //ARRAY (5 POINT CHOICE) case "A": //ARRAY (5 POINT CHOICE)
$condition = "parent_qid = '{$deqrow['qid']}' AND language= '{$surveyprintlang}'"; $condition = "parent_qid = '{$deqrow['qid']}' AND language= '{$lang}'";
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] = " $question['ANSWER'] = "
<table> <table>
@ -1003,8 +1004,8 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "B": //ARRAY (10 POINT CHOICE) case "B": //ARRAY (10 POINT CHOICE)
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n"; $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n";
for ($i=1; $i<=10; $i++) for ($i=1; $i<=10; $i++)
@ -1014,7 +1015,7 @@ class printablesurvey extends Survey_Common_Action
$question['ANSWER'] .= "\t</thead>\n\n\t<tbody>\n"; $question['ANSWER'] .= "\t</thead>\n\n\t<tbody>\n";
$j=0; $j=0;
$rowclass = 'array1'; $rowclass = 'array1';
$mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$lang}' ", array('question_order'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
@ -1034,17 +1035,17 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "C": //ARRAY (YES/UNCERTAIN/NO) case "C": //ARRAY (YES/UNCERTAIN/NO)
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] = ' $question['ANSWER'] = '
<table> <table>
<thead> <thead>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<th>'.$clang->gT("Yes").self::_addsgqacode(" (Y)").'</th> <th>'.gT("Yes").self::_addsgqacode(" (Y)").'</th>
<th>'.$clang->gT("Uncertain").self::_addsgqacode(" (U)").'</th> <th>'.gT("Uncertain").self::_addsgqacode(" (U)").'</th>
<th>'.$clang->gT("No").self::_addsgqacode(" (N)").'</th> <th>'.gT("No").self::_addsgqacode(" (N)").'</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -1053,14 +1054,14 @@ class printablesurvey extends Survey_Common_Action
$rowclass = 'array1'; $rowclass = 'array1';
$mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$lang}' ", array('question_order'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
$question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n"; $question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n";
$question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['question']}".self::_addsgqacode(" (".$fieldname.$mearow['title'].")")."</th>\n"; $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['question']}".self::_addsgqacode(" (".$fieldname.$mearow['title'].")")."</th>\n";
$question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',$clang->gT("Yes"))."</td>\n"; $question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',gT("Yes"))."</td>\n";
$question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',$clang->gT("Uncertain"))."</td>\n"; $question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',gT("Uncertain"))."</td>\n";
$question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',$clang->gT("No"))."</td>\n"; $question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',gT("No"))."</td>\n";
$question['ANSWER'] .= "\t\t</tr>\n"; $question['ANSWER'] .= "\t\t</tr>\n";
$j++; $j++;
@ -1070,17 +1071,17 @@ class printablesurvey extends Survey_Common_Action
break; break;
case "E": //ARRAY (Increase/Same/Decrease) case "E": //ARRAY (Increase/Same/Decrease)
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] = ' $question['ANSWER'] = '
<table> <table>
<thead> <thead>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<th>'.$clang->gT("Increase").self::_addsgqacode(" (I)").'</th> <th>'.gT("Increase").self::_addsgqacode(" (I)").'</th>
<th>'.$clang->gT("Same").self::_addsgqacode(" (S)").'</th> <th>'.gT("Same").self::_addsgqacode(" (S)").'</th>
<th>'.$clang->gT("Decrease").self::_addsgqacode(" (D)").'</th> <th>'.gT("Decrease").self::_addsgqacode(" (D)").'</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -1088,14 +1089,14 @@ class printablesurvey extends Survey_Common_Action
$j=0; $j=0;
$rowclass = 'array1'; $rowclass = 'array1';
$mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$lang}' ", array('question_order'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
$question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n"; $question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n";
$question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['question']}".self::_addsgqacode(" (".$fieldname.$mearow['title'].")")."</th>\n"; $question['ANSWER'] .= "\t\t\t<th class=\"answertext\">{$mearow['question']}".self::_addsgqacode(" (".$fieldname.$mearow['title'].")")."</th>\n";
$question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',$clang->gT("Increase"))."</td>\n"; $question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',gT("Increase"))."</td>\n";
$question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',$clang->gT("Same"))."</td>\n"; $question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',gT("Same"))."</td>\n";
$question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',$clang->gT("Decrease"))."</td>\n"; $question['ANSWER'] .= "\t\t\t<td>".self::_input_type_image('radio',gT("Decrease"))."</td>\n";
$question['ANSWER'] .= "\t\t</tr>\n"; $question['ANSWER'] .= "\t\t</tr>\n";
$j++; $j++;
$rowclass = alternation($rowclass,'row'); $rowclass = alternation($rowclass,'row');
@ -1138,10 +1139,10 @@ class printablesurvey extends Survey_Common_Action
$checkboxlayout=false; $checkboxlayout=false;
} }
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n"; $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n";
$fresult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' and scale_id=1 AND language='{$surveyprintlang}' ", array('question_order')); $fresult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' and scale_id=1 AND language='{$lang}' ", array('question_order'));
$fresult = $fresult->readAll(); $fresult = $fresult->readAll();
$fcount = count($fresult); $fcount = count($fresult);
$fwidth = "120"; $fwidth = "120";
@ -1161,7 +1162,7 @@ class printablesurvey extends Survey_Common_Action
$a=1; //Counter for pdfoutput $a=1; //Counter for pdfoutput
$rowclass = 'array1'; $rowclass = 'array1';
$mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' and scale_id=0 AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' and scale_id=0 AND language='{$lang}' ", array('question_order'));
$result = $mearesult->readAll(); $result = $mearesult->readAll();
foreach ($result as $frow) foreach ($result as $frow)
{ {
@ -1201,13 +1202,13 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case ";": //ARRAY (Multi Flexible) (text) case ";": //ARRAY (Multi Flexible) (text)
$headstyle="style='padding-left: 20px; padding-right: 7px'"; $headstyle="style='padding-left: 20px; padding-right: 7px'";
$mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND scale_id=0 AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND scale_id=0 AND language='{$lang}' ", array('question_order'));
$mearesult=$mearesult->readAll(); $mearesult=$mearesult->readAll();
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n"; $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n";
$fresult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND scale_id=1 AND language='{$surveyprintlang}' ", array('question_order')); $fresult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND scale_id=1 AND language='{$lang}' ", array('question_order'));
$fresult = $fresult->readAll(); $fresult = $fresult->readAll();
$fcount = count($fresult); $fcount = count($fresult);
$fwidth = "120"; $fwidth = "120";
@ -1254,10 +1255,10 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "F": //ARRAY (Flexible Labels) case "F": //ARRAY (Flexible Labels)
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$fresult=Answer::model()->getAllRecords(" scale_id=0 AND qid='{$deqrow['qid']}' AND language='{$surveyprintlang}'", array('sortorder','code')); $fresult=Answer::model()->getAllRecords(" scale_id=0 AND qid='{$deqrow['qid']}' AND language='{$lang}'", array('sortorder','code'));
$fresult = $fresult->readAll(); $fresult = $fresult->readAll();
$fcount = count($fresult); $fcount = count($fresult);
$fwidth = "120"; $fwidth = "120";
@ -1295,7 +1296,7 @@ class printablesurvey extends Survey_Common_Action
$counter = 1; $counter = 1;
$rowclass = 'array1'; $rowclass = 'array1';
$mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid='{$deqrow['qid']}' AND language='{$lang}' ", array('question_order'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
$question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n"; $question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n";
@ -1345,17 +1346,17 @@ class printablesurvey extends Survey_Common_Action
// ================================================================== // ==================================================================
case "1": //ARRAY (Flexible Labels) multi scale case "1": //ARRAY (Flexible Labels) multi scale
$leftheader= $qidattributes['dualscale_headerA'][$surveyprintlang]; $leftheader= $qidattributes['dualscale_headerA'][$lang];
$rightheader= $qidattributes['dualscale_headerB'][$surveyprintlang]; $rightheader= $qidattributes['dualscale_headerB'][$lang];
$headstyle = 'style="padding-left: 20px; padding-right: 7px"'; $headstyle = 'style="padding-left: 20px; padding-right: 7px"';
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $surveyprintlang, $surveyid); $question['QUESTION_TYPE_HELP'] .= self::_array_filter_help($qidattributes, $lang, $surveyid);
$question['ANSWER'] .= "\n<table>\n\t<thead>\n"; $question['ANSWER'] .= "\n<table>\n\t<thead>\n";
$condition = "qid= '{$deqrow['qid']}' AND language= '{$surveyprintlang}' AND scale_id=0"; $condition = "qid= '{$deqrow['qid']}' AND language= '{$lang}' AND scale_id=0";
$fresult= Answer::model()->getAllRecords( $condition, array('sortorder', 'code')); $fresult= Answer::model()->getAllRecords( $condition, array('sortorder', 'code'));
$fresult = $fresult->readAll(); $fresult = $fresult->readAll();
$fcount = count($fresult); $fcount = count($fresult);
@ -1372,9 +1373,9 @@ class printablesurvey extends Survey_Common_Action
} }
// second scale // second scale
$printablesurveyoutput2 .="\t\t\t<td>&nbsp;</td>\n"; $printablesurveyoutput2 .="\t\t\t<td>&nbsp;</td>\n";
//$fquery1 = "SELECT * FROM {{answers}} WHERE qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' AND scale_id=1 ORDER BY sortorder, code"; //$fquery1 = "SELECT * FROM {{answers}} WHERE qid='{$deqrow['qid']}' AND language='{$lang}' AND scale_id=1 ORDER BY sortorder, code";
// $fresult1 = Yii::app()->db->createCommand($fquery1)->query(); // $fresult1 = Yii::app()->db->createCommand($fquery1)->query();
$fresult1 = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$surveyprintlang}' AND scale_id=1 ", array('sortorder','code')); $fresult1 = Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND language='{$lang}' AND scale_id=1 ", array('sortorder','code'));
$fresult1 = $fresult1->readAll(); $fresult1 = $fresult1->readAll();
$fcount1 = count ($fresult1); $fcount1 = count ($fresult1);
$fwidth = "120"; $fwidth = "120";
@ -1418,7 +1419,7 @@ class printablesurvey extends Survey_Common_Action
//counter for each subquestion //counter for each subquestion
$sqcounter = 0; $sqcounter = 0;
$mearesult=Question::model()->getAllRecords(" parent_qid={$deqrow['qid']} AND language='{$surveyprintlang}' ", array('question_order')); $mearesult=Question::model()->getAllRecords(" parent_qid={$deqrow['qid']} AND language='{$lang}' ", array('question_order'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
$question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n"; $question['ANSWER'] .= "\t\t<tr class=\"$rowclass\">\n";
@ -1455,10 +1456,10 @@ class printablesurvey extends Survey_Common_Action
//$headstyle="style='border-left-style: solid; border-left-width: 1px; border-left-color: #AAAAAA'"; //$headstyle="style='border-left-style: solid; border-left-width: 1px; border-left-color: #AAAAAA'";
$headstyle="style='padding-left: 20px; padding-right: 7px'"; $headstyle="style='padding-left: 20px; padding-right: 7px'";
$condition = "parent_qid= '{$deqrow['qid']}' AND language= '{$surveyprintlang}'"; $condition = "parent_qid= '{$deqrow['qid']}' AND language= '{$lang}'";
$fresult= Question::model()->getAllRecords( $condition, array('question_order', 'title')); $fresult= Question::model()->getAllRecords( $condition, array('question_order', 'title'));
$fresult = $fresult->readAll(); $fresult = $fresult->readAll();
$question['QUESTION_TYPE_HELP'] .= $clang->gT("Please choose the appropriate response for each item:"); $question['QUESTION_TYPE_HELP'] .= gT("Please choose the appropriate response for each item:");
$question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n"; $question['ANSWER'] .= "\n<table>\n\t<thead>\n\t\t<tr>\n\t\t\t<td>&nbsp;</td>\n";
$fcount = count($fresult); $fcount = count($fresult);
@ -1473,7 +1474,7 @@ class printablesurvey extends Survey_Common_Action
$a=1; $a=1;
$rowclass = 'array1'; $rowclass = 'array1';
$mearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND scale_id=0 AND language='{$surveyprintlang}' ", array('sortorder','code')); $mearesult=Answer::model()->getAllRecords(" qid='{$deqrow['qid']}' AND scale_id=0 AND language='{$lang}' ", array('sortorder','code'));
foreach ($mearesult->readAll() as $mearow) foreach ($mearesult->readAll() as $mearow)
{ {
//$_POST['type']=$type; //$_POST['type']=$type;
@ -1508,7 +1509,7 @@ class printablesurvey extends Survey_Common_Action
} }
} }
$survey_output['THEREAREXQUESTIONS'] = str_replace( '{NUMBEROFQUESTIONS}' , $total_questions , $clang->gT('There are {NUMBEROFQUESTIONS} questions in this survey')); $survey_output['THEREAREXQUESTIONS'] = str_replace( '{NUMBEROFQUESTIONS}' , $total_questions , gT('There are {NUMBEROFQUESTIONS} questions in this survey'));
// START recursive tag stripping. // START recursive tag stripping.
// PHP 5.1.0 introduced the count parameter for preg_replace() and thus allows this procedure to run with only one regular expression. // PHP 5.1.0 introduced the count parameter for preg_replace() and thus allows this procedure to run with only one regular expression.
@ -1653,14 +1654,14 @@ class printablesurvey extends Survey_Common_Action
} }
} }
private function _min_max_answers_help($qidattributes, $surveyprintlang, $surveyid) { private function _min_max_answers_help($qidattributes, $lang, $surveyid) {
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$output = ""; $output = "";
if(!empty($qidattributes['min_answers'])) { if(!empty($qidattributes['min_answers'])) {
$output .= "\n<p class='extrahelp'>".sprintf($clang->gT("Please choose at least %s items."), $qidattributes['min_answers'])."</p>\n"; $output .= "\n<p class='extrahelp'>".sprintf(gT("Please choose at least %s items."), $qidattributes['min_answers'])."</p>\n";
} }
if(!empty($qidattributes['max_answers'])) { if(!empty($qidattributes['max_answers'])) {
$output .= "\n<p class='extrahelp'>".sprintf($clang->gT("Please choose no more than %s items."),$qidattributes['max_answers'])."</p>\n"; $output .= "\n<p class='extrahelp'>".sprintf(gT("Please choose no more than %s items."),$qidattributes['max_answers'])."</p>\n";
} }
return $output; return $output;
} }
@ -1740,35 +1741,45 @@ class printablesurvey extends Survey_Common_Action
); );
} }
private function _array_filter_help($qidattributes, $surveyprintlang, $surveyid) private function _array_filter_help($qidattributes, $lang, $surveyid)
{ {
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$output = ""; $output = "";
if(!empty($qidattributes['array_filter'])) if(!empty($qidattributes['array_filter']))
{ {
$newquestiontext = Question::model()->findByAttributes(array('title' => $qidattributes['array_filter'], 'language' => $surveyprintlang, 'sid' => $surveyid))->getAttribute('question'); $aFilter=explode(';',$qidattributes['array_filter']);
$output .= "\n<p class='extrahelp'> $output .= "\n<p class='extrahelp'>";
".sprintf($clang->gT("Only answer this question for the items you selected in question %s ('%s')"),$qidattributes['array_filter'], flattenText(breakToNewline($newquestiontext)))." foreach ($aFilter as $sFilter)
</p>\n"; {
$oQuestion=Question::model()->findByAttributes(array('title' => $sFilter, 'language' => $lang, 'sid' => $surveyid));
if ($oQuestion)
{
$sNewQuestionText = flattenText(breakToNewline($oQuestion->getAttribute('question')));
$output .= sprintf(gT("Only answer this question for the items you selected in question %s ('%s')"),$qidattributes['array_filter'], $sNewQuestionText );
}
}
$output .= "</p>\n";
} }
if(!empty($qidattributes['array_filter_exclude'])) if(!empty($qidattributes['array_filter']))
{ {
$arQuestion = Question::model()->findByAttributes(array('title' => $qidattributes['array_filter_exclude'], 'language' => $surveyprintlang, 'sid' => $surveyid)); $aFilter=explode(';',$qidattributes['array_filter']);
if ($arQuestion) $output .= "\n<p class='extrahelp'>";
foreach ($aFilter as $sFilter)
{ {
$newquestiontext=$arQuestion->getAttribute('question'); $oQuestion=Question::model()->findByAttributes(array('title' => $sFilter, 'language' => $lang, 'sid' => $surveyid));
if ($oQuestion)
{
$sNewQuestionText = flattenText(breakToNewline($oQuestion->getAttribute('question')));
$output .= sprintf(gT("Only answer this question for the items you did not select in question %s ('%s')"),$qidattributes['array_filter'], $sNewQuestionText );
}
} }
else $output .= "</p>\n";
{
return '';
}
$output .= "\n <p class='extrahelp'>
".sprintf($clang->gT("Only answer this question for the items you did not select in question %s ('%s')"),$qidattributes['array_filter_exclude'], breakToNewline($newquestiontext))."
</p>\n";
} }
return $output; return $output;
} }
/* /*
* $code: Text string containing the reference (column heading) for the current (sub-) question * $code: Text string containing the reference (column heading) for the current (sub-) question
* *

View file

@ -1020,10 +1020,48 @@ class questions extends Survey_Common_Action
$language=null; $language=null;
} }
$resultdata=getlabelsets($language); $resultdata=getlabelsets($language);
// Label set title really don't need HTML
foreach($resultdata as &$aResult)
{
$aResult = array_map('flattenText', $aResult);
}
header('Content-type: application/json'); header('Content-type: application/json');
echo ls_json_encode($resultdata); echo ls_json_encode($resultdata);
} }
public function ajaxchecklabel()
{
$iLabelID = (int) Yii::app()->request->getParam('lid');
$aNewLanguages = Yii::app()->request->getParam('languages');
$bCheckAssessments = Yii::app()->request->getParam('bCheckAssessments',0);
$arLabelSet=LabelSet::model()->find('lid=:lid',array(':lid' => $iLabelID));
$iLabelsWithAssessmentValues=Label::model()->count('lid=:lid AND assessment_value<>0',array(':lid' => $iLabelID));
$aLabelSetLanguages=explode(' ',$arLabelSet->languages);
$aErrorMessages=array();
if ($bCheckAssessments && $iLabelsWithAssessmentValues)
{
$aErrorMessages[]=gT('The existing label set has some assessment values assigned.').'<strong>'.gT('If you replace the label set the existing asssessment values will be lost.').'</strong>';
}
if (count(array_diff($aLabelSetLanguages,$aNewLanguages)))
{
$aErrorMessages[]=gT('The existing label has different/more languages.').'<strong>'.gT('If you replace the label set these translations will be lost.').'</strong>';
}
if (count($aErrorMessages)){
foreach ($aErrorMessages as $sErrorMessage)
{
echo $sErrorMessage.'<br>';
}
eT('Do you really want to continue?');
}
else
{
eT('You are about to replace a given label set with the current answer options');
echo '<br>';
eT('Continue?');
}
}
/** /**
* Load preview of a question screen. * Load preview of a question screen.
* *
@ -1073,8 +1111,6 @@ class questions extends Survey_Common_Action
setNoAnswerMode($thissurvey); setNoAnswerMode($thissurvey);
Yii::app()->session['dateformats'] = getDateFormatData($thissurvey['surveyls_dateformat']);
$qrows = Question::model()->findByAttributes(array('sid' => $surveyid, 'qid' => $qid, 'language' => $language))->getAttributes(); $qrows = Question::model()->findByAttributes(array('sid' => $surveyid, 'qid' => $qid, 'language' => $language))->getAttributes();
$ia = array( $ia = array(

View file

@ -453,6 +453,8 @@ class quotas extends Survey_Common_Action
$sBaseLang = $aData['sBaseLang']; $sBaseLang = $aData['sBaseLang'];
$clang = $aData['clang']; $clang = $aData['clang'];
$this->_checkPermissions($iSurveyId, 'read'); $this->_checkPermissions($iSurveyId, 'read');
$aQuestion = Question::model()->findByPk(array('qid' => $iQuestionId, 'language' => $sBaseLang)); $aQuestion = Question::model()->findByPk(array('qid' => $iQuestionId, 'language' => $sBaseLang));
$aQuestionType = $aQuestion['type']; $aQuestionType = $aQuestion['type'];
@ -473,7 +475,8 @@ class quotas extends Survey_Common_Action
'F' => array('Title' => $aQuestion['title'], 'Display' => $clang->gT("Female"), 'code' => 'F')); 'F' => array('Title' => $aQuestion['title'], 'Display' => $clang->gT("Female"), 'code' => 'F'));
} elseif ($aQuestionType == 'L' || $aQuestionType == 'O' || $aQuestionType == '!') } elseif ($aQuestionType == 'L' || $aQuestionType == 'O' || $aQuestionType == '!')
{ {
$aAnsResults = Answer::model()->findAllByAttributes(array('qid' => $iQuestionId));
$aAnsResults = Answer::model()->findAllByAttributes(array('qid' => $iQuestionId, 'language' => $sBaseLang));
$aAnswerList = array(); $aAnswerList = array();
@ -481,6 +484,7 @@ class quotas extends Survey_Common_Action
{ {
$aAnswerList[$aDbAnsList['code']] = array('Title' => $aQuestion['title'], 'Display' => substr($aDbAnsList['answer'], 0, 40), 'code' => $aDbAnsList['code']); $aAnswerList[$aDbAnsList['code']] = array('Title' => $aQuestion['title'], 'Display' => substr($aDbAnsList['answer'], 0, 40), 'code' => $aDbAnsList['code']);
} }
} elseif ($aQuestionType == 'A') } elseif ($aQuestionType == 'A')
{ {
$aAnsResults = Question::model()->findAllByAttributes(array('parent_qid' => $iQuestionId)); $aAnsResults = Question::model()->findAllByAttributes(array('parent_qid' => $iQuestionId));
@ -497,7 +501,7 @@ class quotas extends Survey_Common_Action
} }
} elseif ($aQuestionType == 'B') } elseif ($aQuestionType == 'B')
{ {
$aAnsResults = Answer::model()->findAllByAttributes(array('qid' => $iQuestionId)); $aAnsResults = Answer::model()->findAllByAttributes(array('qid' => $iQuestionId, 'language' => $sBaseLang));
$aAnswerList = array(); $aAnswerList = array();

View file

@ -93,12 +93,16 @@ class remotecontrol extends Survey_Common_Action
*/ */
public function test() public function test()
{ {
die(); // Remove if you want to test this function
$RPCType=Yii::app()->getConfig("RPCInterface"); $RPCType=Yii::app()->getConfig("RPCInterface");
$serverUrl = App()->createAbsoluteUrl('/admin/remotecontrol'); $serverUrl = App()->createAbsoluteUrl('/admin/remotecontrol');
$sFileToImport=dirname(Yii::app()->basePath).DIRECTORY_SEPARATOR.'docs'.DIRECTORY_SEPARATOR.'demosurveys'.DIRECTORY_SEPARATOR.'limesurvey2_sample_survey_english.lss'; $sFileToImport=dirname(Yii::app()->basePath).DIRECTORY_SEPARATOR.'docs'.DIRECTORY_SEPARATOR.'demosurveys'.DIRECTORY_SEPARATOR.'limesurvey2_sample_survey_english.lss';
if ($RPCType == 'xml') { if ($RPCType == 'xml') {
$cur_path = get_include_path();
set_include_path($cur_path . PATH_SEPARATOR . APPPATH . 'helpers');
require_once('Zend/XmlRpc/Client.php'); require_once('Zend/XmlRpc/Client.php');
$client = new Zend_XmlRpc_Client($serverUrl); $client = new Zend_XmlRpc_Client($serverUrl);
} elseif ($RPCType == 'json') { } elseif ($RPCType == 'json') {
Yii::app()->loadLibrary('jsonRPCClient'); Yii::app()->loadLibrary('jsonRPCClient');

View file

@ -420,6 +420,10 @@ class responses extends Survey_Common_Action
readfile($file); readfile($file);
exit; exit;
} }
else
{
Yii::app()->session['flashmessage']=gT("The requested file does not exist on the server.");
}
break; break;
} }
} }
@ -497,8 +501,8 @@ class responses extends Survey_Common_Action
$fncount = count($fnames); $fncount = count($fnames);
$start = Yii::app()->request->getParam('start', 0); $start = (int)Yii::app()->request->getParam('start', 0);
$limit = Yii::app()->request->getParam('limit', 50); $limit = (int)Yii::app()->request->getParam('limit', 50);
$order = Yii::app()->request->getParam('order', 'asc'); $order = Yii::app()->request->getParam('order', 'asc');
if(!$limit){$limit=50;} if(!$limit){$limit=50;}
$oCriteria = new CDbCriteria; $oCriteria = new CDbCriteria;
@ -844,6 +848,8 @@ class responses extends Survey_Common_Action
exit; exit;
} }
} }
else Yii::app()->session['flashmessage']=gT("The requested file does not exist on the server.");
} }
/** /**

View file

@ -66,43 +66,40 @@ class SurveyAdmin extends Survey_Common_Action
public function regenquestioncodes($iSurveyID, $sSubAction ) public function regenquestioncodes($iSurveyID, $sSubAction )
{ {
if (Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update')) $clang = $this->getController()->lang;
if (!Permission::model()->hasSurveyPermission($iSurveyID, 'surveycontent', 'update'))
{ {
$clang = $this->getController()->lang; Yii::app()->setFlashMessage($clang->gT("You do not have sufficient rights to access this page."),'error');
$this->getController()->redirect(array('admin/survey','sa'=>'view','surveyid'=>$iSurveyID));
//Automatically renumbers the "question codes" so that they follow
//a methodical numbering method
$iQuestionNumber=1;
$iGroupNumber=0;
$iSequence=0;
$sQuery="SELECT a.qid, a.gid\n"
."FROM {{questions}} as a, {{groups}} g "
."WHERE a.gid=g.gid AND a.sid={$iSurveyID} AND a.parent_qid=0 "
."GROUP BY a.gid, a.qid, g.group_order, question_order "
."ORDER BY g.group_order, question_order";
$arResult=dbExecuteAssoc($sQuery) or safe_die ("Error: ".$connect->ErrorMsg()); // Checked
$grows = array(); //Create an empty array in case FetchRow does not return any rows
foreach ($arResult->readAll() as $grow) {$grows[] = $grow;} // Get table output into array
foreach($grows as $grow)
{
//Go through all the questions
if ($sSubAction == 'bygroup' && (!isset($iGroupNumber) || $iGroupNumber != $grow['gid']))
{ //If we're doing this by group, restart the numbering when the group number changes
$iQuestionNumber=1;
$iGroupNumber = $grow['gid'];
$iSequence++;
}
$usql="UPDATE {{questions}} "
."SET title='".(($sSubAction == 'bygroup') ? ('G' . $iSequence ) : '')."Q".str_pad($iQuestionNumber, 5, "0", STR_PAD_LEFT)."'\n"
."WHERE qid=".$grow['qid'];
//$databaseoutput .= "[$sql]";
$uresult=dbExecuteAssoc($usql) or safe_die("Error: ".$connect->ErrorMsg()); // Checked
$iQuestionNumber++;
$iGroupNumber=$grow['gid'];
}
$_SESSION['flashmessage'] = $clang->gT("Question codes were successfully regenerated.");
LimeExpressionManager::SetDirtyFlag(); // so refreshes syntax highlighting
} }
$oSurvey=Survey::model()->findByPk($iSurveyID);
if ($oSurvey->active=='Y')
{
Yii::app()->setFlashMessage($clang->gT("You can't update question code for an active survey."),'error');
$this->getController()->redirect(array('admin/survey','sa'=>'view','surveyid'=>$iSurveyID));
}
//Automatically renumbers the "question codes" so that they follow
//a methodical numbering method
$iQuestionNumber=1;
$iGroupNumber=0;
$iGroupSequence=0;
$oQuestions=Question::model()->with('groups')->findAll(array('select'=>'t.qid,t.gid','condition'=>"t.sid=:sid and t.language=:language and parent_qid=0",'order'=>'groups.group_order, question_order','params'=>array(':sid'=>$iSurveyID,':language'=>$oSurvey->language)));
foreach($oQuestions as $oQuestion)
{
if ($sSubAction == 'bygroup' && $iGroupNumber != $oQuestion->gid)
{ //If we're doing this by group, restart the numbering when the group number changes
$iQuestionNumber=1;
$iGroupNumber = $oQuestion->gid;
$iGroupSequence++;
}
$sNewTitle=(($sSubAction == 'bygroup') ? ('G' . $iGroupSequence ) : '')."Q".str_pad($iQuestionNumber, 5, "0", STR_PAD_LEFT);
Question::model()->updateAll(array('title'=>$sNewTitle),'qid=:qid',array(':qid'=>$oQuestion->qid));
$iQuestionNumber++;
$iGroupNumber=$oQuestion->gid;
}
Yii::app()->setFlashMessage($clang->gT("Question codes were successfully regenerated."));
LimeExpressionManager::SetDirtyFlag(); // so refreshes syntax highlighting
$this->getController()->redirect(array('admin/survey/sa/view/surveyid/' . $iSurveyID)); $this->getController()->redirect(array('admin/survey/sa/view/surveyid/' . $iSurveyID));
} }
@ -307,15 +304,15 @@ class SurveyAdmin extends Survey_Common_Action
$iSurveyID = Yii::app()->request->getPost('sid', $iSurveyID); $iSurveyID = Yii::app()->request->getPost('sid', $iSurveyID);
$iSurveyID = sanitize_int($iSurveyID); $iSurveyID = sanitize_int($iSurveyID);
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
if (!tableExists('survey_'.$iSurveyID))
{
$_SESSION['flashmessage'] = $clang->gT("Error: Response table does not exist. Survey cannot be deactivated.");
$this->getController()->redirect($this->getController()->createUrl("admin/survey/sa/view/surveyid/{$iSurveyID}"));
}
$date = date('YmdHis'); //'His' adds 24hours+minutes to name to allow multiple deactiviations in a day $date = date('YmdHis'); //'His' adds 24hours+minutes to name to allow multiple deactiviations in a day
if (empty($_POST['ok'])) if (empty($_POST['ok']))
{ {
if (!tableExists('survey_'.$iSurveyID))
{
$_SESSION['flashmessage'] = $clang->gT("Error: Response table does not exist. Survey cannot be deactivated.");
$this->getController()->redirect($this->getController()->createUrl("admin/survey/sa/view/surveyid/{$iSurveyID}"));
}
$aData['surveyid'] = $iSurveyID; $aData['surveyid'] = $iSurveyID;
$aData['date'] = $date; $aData['date'] = $date;
$aData['dbprefix'] = Yii::app()->db->tablePrefix; $aData['dbprefix'] = Yii::app()->db->tablePrefix;
@ -326,18 +323,19 @@ class SurveyAdmin extends Survey_Common_Action
//See if there is a tokens table for this survey //See if there is a tokens table for this survey
if (tableExists("{{tokens_{$iSurveyID}}}")) if (tableExists("{{tokens_{$iSurveyID}}}"))
{ {
if (Yii::app()->db->getDriverName() == 'postgre') $toldtable = Yii::app()->db->tablePrefix."tokens_{$iSurveyID}";
$tnewtable = Yii::app()->db->tablePrefix."old_tokens_{$iSurveyID}_{$date}";
if (Yii::app()->db->getDriverName() == 'pgsql')
{ {
$deactivateresult = Yii::app()->db->createCommand()->renameTable($toldtable . '_tid_seq', $tnewtable . '_tid_seq'); $tidDefault = Yii::app()->db->createCommand("SELECT pg_attrdef.adsrc FROM pg_attribute JOIN pg_class ON (pg_attribute.attrelid=pg_class.oid) JOIN pg_attrdef ON(pg_attribute.attrelid=pg_attrdef.adrelid AND pg_attribute.attnum=pg_attrdef.adnum) WHERE pg_class.relname='$toldtable' and pg_attribute.attname='tid'")->queryScalar();
$setsequence = "ALTER TABLE ".Yii::app()->db->quoteTableName($tnewtable)." ALTER COLUMN tid SET DEFAULT nextval('{{{$tnewtable}}}_tid_seq'::regclass);"; if(preg_match("/nextval\('(tokens_\d+_tid_seq\d*)'::regclass\)/", $tidDefault, $matches)){
$deactivateresult = Yii::app()->db->createCommand($setsequence)->query(); $oldSeq = $matches[1];
$setidx = "ALTER INDEX {{{$toldtable}}}_idx RENAME TO {{{$tnewtable}}}_idx;"; $deactivateresult = Yii::app()->db->createCommand()->renameTable($oldSeq, $tnewtable . '_tid_seq');
$deactivateresult = Yii::app()->db->createCommand($setidx)->query(); $setsequence = "ALTER TABLE ".Yii::app()->db->quoteTableName($toldtable)." ALTER COLUMN tid SET DEFAULT nextval('{$tnewtable}_tid_seq'::regclass);";
$deactivateresult = Yii::app()->db->createCommand($setsequence)->query();
}
} }
$toldtable = "{{tokens_{$iSurveyID}}}";
$tnewtable = "{{old_tokens_{$iSurveyID}_{$date}}}";
$tdeactivateresult = Yii::app()->db->createCommand()->renameTable($toldtable, $tnewtable); $tdeactivateresult = Yii::app()->db->createCommand()->renameTable($toldtable, $tnewtable);
$aData['tnewtable'] = $tnewtable; $aData['tnewtable'] = $tnewtable;
@ -362,11 +360,15 @@ class SurveyAdmin extends Survey_Common_Action
$survey = Survey::model()->findByAttributes(array('sid' => $iSurveyID)); $survey = Survey::model()->findByAttributes(array('sid' => $iSurveyID));
$survey->autonumber_start = $new_autonumber_start; $survey->autonumber_start = $new_autonumber_start;
$survey->save(); $survey->save();
if (Yii::app()->db->getDrivername() == 'postgre') if (Yii::app()->db->getDriverName() == 'pgsql')
{ {
$deactivateresult = Yii::app()->db->createCommand()->renameTable($sOldSurveyTableName . '_id_seq', $sNewSurveyTableName . '_id_seq'); $idDefault = Yii::app()->db->createCommand("SELECT pg_attrdef.adsrc FROM pg_attribute JOIN pg_class ON (pg_attribute.attrelid=pg_class.oid) JOIN pg_attrdef ON(pg_attribute.attrelid=pg_attrdef.adrelid AND pg_attribute.attnum=pg_attrdef.adnum) WHERE pg_class.relname='$sOldSurveyTableName' and pg_attribute.attname='id'")->queryScalar();
$setsequence = "ALTER TABLE $newtable ALTER COLUMN id SET DEFAULT nextval('{$sNewSurveyTableName}_id_seq'::regclass);"; if(preg_match("/nextval\('(survey_\d+_id_seq\d*)'::regclass\)/", $idDefault, $matches)){
$deactivateresult = Yii::app()->db->createCommand($setsequence)->execute(); $oldSeq = $matches[1];
$deactivateresult = Yii::app()->db->createCommand()->renameTable($oldSeq, $sNewSurveyTableName . '_id_seq');
$setsequence = "ALTER TABLE ".Yii::app()->db->quoteTableName($sOldSurveyTableName)." ALTER COLUMN id SET DEFAULT nextval('{{{$sNewSurveyTableName}}}_id_seq'::regclass);";
$deactivateresult = Yii::app()->db->createCommand($setsequence)->query();
}
} }
$deactivateresult = Yii::app()->db->createCommand()->renameTable($sOldSurveyTableName, $sNewSurveyTableName); $deactivateresult = Yii::app()->db->createCommand()->renameTable($sOldSurveyTableName, $sNewSurveyTableName);
@ -572,14 +574,13 @@ class SurveyAdmin extends Survey_Common_Action
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$dateformatdetails = getDateFormatData(Yii::app()->session['dateformat']); $dateformatdetails = getDateFormatData(Yii::app()->session['dateformat']);
$surveys = Survey::model(); $oSurvey = new Survey;
//!!! Is this even possible to execute? $oSurvey->permission(Yii::app()->user->getId());
if (!Permission::model()->hasGlobalPermission('superadmin','read'))
$surveys->permission(Yii::app()->user->getId()); $aSurveys = $oSurvey->with(array('languagesettings'=>array('condition'=>'surveyls_language=language'), 'owner'))->findAll();
$surveys = $surveys->with(array('languagesettings'=>array('condition'=>'surveyls_language=language'), 'owner'))->findAll();
$aSurveyEntries = new stdClass(); $aSurveyEntries = new stdClass();
$aSurveyEntries->page = 1; $aSurveyEntries->page = 1;
foreach ($surveys as $rows) foreach ($aSurveys as $rows)
{ {
if (!isset($rows->owner->attributes)) $aOwner=array('users_name'=>$clang->gT('(None)')); else $aOwner=$rows->owner->attributes; if (!isset($rows->owner->attributes)) $aOwner=array('users_name'=>$clang->gT('(None)')); else $aOwner=$rows->owner->attributes;
$rows = array_merge($rows->attributes, $rows->defaultlanguage->attributes, $aOwner); $rows = array_merge($rows->attributes, $rows->defaultlanguage->attributes, $aOwner);
@ -705,7 +706,7 @@ class SurveyAdmin extends Survey_Common_Action
* @param string $sa * @param string $sa
* @return void * @return void
*/ */
public function delete($iSurveyID, $delete = 'no') public function delete($iSurveyID)
{ {
$aData = $aViewUrls = array(); $aData = $aViewUrls = array();
$aData['surveyid'] = $iSurveyID = (int) $iSurveyID; $aData['surveyid'] = $iSurveyID = (int) $iSurveyID;
@ -713,7 +714,7 @@ class SurveyAdmin extends Survey_Common_Action
if (Permission::model()->hasSurveyPermission($iSurveyID, 'survey', 'delete')) if (Permission::model()->hasSurveyPermission($iSurveyID, 'survey', 'delete'))
{ {
if ($delete == 'yes') if (Yii::app()->request->getPost("delete") == 'yes')
{ {
$aData['issuperadmin'] = Permission::model()->hasGlobalPermission('superadmin','read'); $aData['issuperadmin'] = Permission::model()->hasGlobalPermission('superadmin','read');
$this->_deleteSurvey($iSurveyID); $this->_deleteSurvey($iSurveyID);
@ -923,7 +924,7 @@ class SurveyAdmin extends Survey_Common_Action
if ($action == 'importsurvey' && !$aData['bFailed']) if ($action == 'importsurvey' && !$aData['bFailed'])
{ {
$aImportResults=importSurveyFile($sFullFilepath,(isset($_POST['translinksfields']))); $aImportResults=importSurveyFile($sFullFilepath,(isset($_POST['translinksfields'])));
if (is_null($aImportResults) || isset($aImportResults['error'])) if (is_null($aImportResults) || !empty($aImportResults['error']) )
{ {
$aData['sErrorMessage']=$aImportResults['error']; $aData['sErrorMessage']=$aImportResults['error'];
$aData['bFailed'] = true; $aData['bFailed'] = true;
@ -951,8 +952,6 @@ class SurveyAdmin extends Survey_Common_Action
unlink($sFullFilepath); unlink($sFullFilepath);
} }
// if (isset($aImportResults['error']) && $aImportResults['error']) safeDie($aImportResults['error']);
if (!$aData['bFailed']) if (!$aData['bFailed'])
{ {
$aData['action'] = $action; $aData['action'] = $action;
@ -987,7 +986,7 @@ class SurveyAdmin extends Survey_Common_Action
{ {
// Prepare data for the view // Prepare data for the view
$sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language; $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
LimeExpressionManager::StartSurvey($iSurveyID, 'survey');
LimeExpressionManager::StartProcessingPage(true, Yii::app()->baseUrl); LimeExpressionManager::StartProcessingPage(true, Yii::app()->baseUrl);
$aGrouplist = QuestionGroup::model()->getGroups($iSurveyID); $aGrouplist = QuestionGroup::model()->getGroups($iSurveyID);
@ -1362,12 +1361,12 @@ class SurveyAdmin extends Survey_Common_Action
function getUrlParamsJSON($iSurveyID) function getUrlParamsJSON($iSurveyID)
{ {
$iSurveyID = (int) $iSurveyID; $iSurveyID = (int) $iSurveyID;
Yii::app()->loadHelper('database'); $sBaseLanguage = Survey::model()->findByPk($iSurveyID)->language;
$oResult = dbExecuteAssoc("select '' as act, up.*,q.title, sq.title as sqtitle, q.question, sq.question as sqquestion from {{survey_url_parameters}} up $sQuery = "select '' as act, up.*,q.title, sq.title as sqtitle, q.question, sq.question as sqquestion from {{survey_url_parameters}} up
left join {{questions}} q on q.qid=up.targetqid left join {{questions}} q on q.qid=up.targetqid
left join {{questions}} sq on sq.qid=up.targetsqid left join {{questions}} sq on sq.qid=up.targetsqid
where up.sid={$iSurveyID}"); where up.sid={$iSurveyID} and q.language='{$sBaseLanguage}' and (sq.language='{$sBaseLanguage}' or sq.language is null)";
$oResult= $oResult->readAll(); $oResult = Yii::app()->db->createCommand($sQuery)->queryAll();
$i = 0; $i = 0;
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$aData = new stdClass(); $aData = new stdClass();

View file

@ -387,7 +387,7 @@ class surveypermission extends Survey_Common_Action {
} }
elseif( $action == "setusergroupsurveysecurity" ) elseif( $action == "setusergroupsurveysecurity" )
{ {
if ( !Permission::model()->hasGlobalPermission('superadmin','read') && !in_array($postusergroupid,getUserList('onlyuidarray')) ) // User can not change own security (except for superadmin ?) if ( !Permission::model()->hasGlobalPermission('superadmin','read') && !in_array($postusergroupid,getUserGroupList(null, 'simplegidarray')) ) // User can not change own security (except for superadmin ?)
{ {
$this->getController()->error('Access denied'); $this->getController()->error('Access denied');
} }
@ -438,7 +438,7 @@ class surveypermission extends Survey_Common_Action {
foreach($aBasePermissions as $sPermissionKey=>$aCRUDPermissions) foreach($aBasePermissions as $sPermissionKey=>$aCRUDPermissions)
{ {
$oddcolumn=!$oddcolumn; $oddcolumn=!$oddcolumn;
$usersummary .= "<tr><td><img src='{$imageurl}{$aCRUDPermissions['img']}_30.png' alt='{$aCRUDPermissions['description']}'/></td>"; $usersummary .= "<tr><td><img src='{$imageurl}{$aCRUDPermissions['img']}_30.png' alt='' title='{$aCRUDPermissions['description']}'/></td>";
$usersummary .= "<td>{$aCRUDPermissions['title']}</td>"; $usersummary .= "<td>{$aCRUDPermissions['title']}</td>";
$usersummary .= "<td ><input type=\"checkbox\" class=\"markrow\" name='all_{$sPermissionKey}' /></td>"; $usersummary .= "<td ><input type=\"checkbox\" class=\"markrow\" name='all_{$sPermissionKey}' /></td>";
foreach ($aCRUDPermissions as $sCRUDKey=>$CRUDValue) foreach ($aCRUDPermissions as $sCRUDKey=>$CRUDValue)
@ -451,8 +451,17 @@ class surveypermission extends Survey_Common_Action {
if (!($sPermissionKey=='survey' && $sCRUDKey=='read')) if (!($sPermissionKey=='survey' && $sCRUDKey=='read'))
{ {
$usersummary .= "<input type=\"checkbox\" class=\"checkboxbtn\" name='perm_{$sPermissionKey}_{$sCRUDKey}' "; $usersummary .= "<input type=\"checkbox\" class=\"checkboxbtn\" name='perm_{$sPermissionKey}_{$sCRUDKey}' ";
if($action=='setsurveysecurity' && Permission::model()->hasSurveyPermission( $surveyid,$sPermissionKey,$sCRUDKey,$postuserid)) { if($action=='setsurveysecurity')
$usersummary .= ' checked="checked" '; {
if(Permission::model()->hasPermission($surveyid,'survey',$sPermissionKey,$sCRUDKey,$postuserid))
{
$usersummary .= ' checked="checked" ';// User have this permission set for this survey
}
elseif(Permission::model()->hasSurveyPermission( $surveyid,$sPermissionKey,$sCRUDKey,$postuserid))
{
$usersummary .= ' data-indeterminate=true ';// User have this permission for this survey by another system (global or owner)
}
} }
$usersummary .=" />"; $usersummary .=" />";
} }
@ -478,6 +487,7 @@ class surveypermission extends Survey_Common_Action {
$usersummary .= "</form>\n"; $usersummary .= "</form>\n";
$aViewUrls['output'] = $usersummary; $aViewUrls['output'] = $usersummary;
App()->getClientScript()->registerScript("data-indeterminate","$(':checkbox[data-indeterminate]').prop('indeterminate', true);",CClientScript::POS_READY);
} }
else else
{ {
@ -524,7 +534,7 @@ class surveypermission extends Survey_Common_Action {
{ {
if (isset($postuserid)) if (isset($postuserid))
{ {
$dbresult = Permission::model()->deleteAll('uid = :uid AND entity_id = :sid AND entity = :entity',array(':uid' => $postuserid, ':sid' => $surveyid, ':entity' => 'survey')); $dbresult = Permission::model()->deleteAll("uid = :uid AND entity_id = :sid AND entity = 'survey'",array(':uid' => $postuserid, ':sid' => $surveyid));
$addsummary .= "<br />".$clang->gT("Username").": ".sanitize_xss_string($_POST['user'])."<br /><br />\n"; $addsummary .= "<br />".$clang->gT("Username").": ".sanitize_xss_string($_POST['user'])."<br /><br />\n";
$addsummary .= "<div class=\"successheader\">".$clang->gT("Success!")."</div>\n"; $addsummary .= "<div class=\"successheader\">".$clang->gT("Success!")."</div>\n";
} }

View file

@ -113,7 +113,7 @@ class templates extends Survey_Common_Action
$zip = new PclZip($_FILES['the_file']['tmp_name']); $zip = new PclZip($_FILES['the_file']['tmp_name']);
// Create temporary directory so that if dangerous content is unzipped it would be unaccessible // Create temporary directory so that if dangerous content is unzipped it would be unaccessible
$sNewDirectoryName=sanitize_dirname($_FILES['the_file']['name']); $sNewDirectoryName=sanitize_dirname(pathinfo($_FILES['the_file']['name'], PATHINFO_FILENAME ));
$destdir = Yii::app()->getConfig('usertemplaterootdir').DIRECTORY_SEPARATOR.$sNewDirectoryName; $destdir = Yii::app()->getConfig('usertemplaterootdir').DIRECTORY_SEPARATOR.$sNewDirectoryName;
if (!is_writeable(dirname($destdir))) if (!is_writeable(dirname($destdir)))
@ -282,7 +282,7 @@ class templates extends Survey_Common_Action
} }
Yii::app()->session['flashmessage'] = $uploadresult; Yii::app()->session['flashmessage'] = $uploadresult;
} }
$this->getController()->redirect(array("admin/templates/view/editfile/" . $editfile . "/screenname/" . $screenname . "/templatename/" . $templatename)); $this->getController()->redirect(array("admin/templates/sa/view/editfile/" . $editfile . "/screenname/" . $screenname . "/templatename/" . $templatename));
} }
/** /**

View file

@ -33,7 +33,7 @@ class tokens extends Survey_Common_Action
$thissurvey = getSurveyInfo($iSurveyId); $thissurvey = getSurveyInfo($iSurveyId);
if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'read') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'create') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'read') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'create') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update')
&& !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'export') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'import') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'export') && !Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'import')
&& !Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update') && !Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update')
) )
{ {
Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page.");
@ -331,7 +331,13 @@ class tokens extends Survey_Common_Action
$aData['order'] = $order; $aData['order'] = $order;
$aData['surveyprivate'] = $aData['thissurvey']['anonymized']; $aData['surveyprivate'] = $aData['thissurvey']['anonymized'];
$aData['dateformatdetails'] = $dateformatdetails; $aData['dateformatdetails'] = $dateformatdetails;
$aLanguageCodes=Survey::model()->findByPk($iSurveyId)->getAllLanguages();
$aLanguages=array();
foreach ($aLanguageCodes as $aCode)
{
$aLanguages[$aCode]=getLanguageNameFromCode($aCode,false);
}
$aData['aLanguages'] = $aLanguages;
$this->_renderWrappedTemplate('token', array('tokenbar', 'browse'), $aData); $this->_renderWrappedTemplate('token', array('tokenbar', 'browse'), $aData);
} }
@ -365,9 +371,13 @@ class tokens extends Survey_Common_Action
$aData = new stdClass; $aData = new stdClass;
$aData->page = $page; $aData->page = $page;
$aSearchArray=Yii::app()->request->getPost('searcharray');
if(empty($search) && !empty($aSearchArray)){
$search=$aSearchArray;
}
if (!empty($search)) { if (!empty($search)) {
$condition = TokenDynamic::model($iSurveyId)->getSearchMultipleCondition($search); $condition = TokenDynamic::model($iSurveyId)->getSearchMultipleCondition($search);
} else { }else{
$condition = new CDbCriteria(); $condition = new CDbCriteria();
} }
@ -447,7 +457,7 @@ class tokens extends Survey_Common_Action
$action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; $action .= '<div style="width: 20px; height: 16px; float: left;"></div>';
} }
// Check if the token can be taken // Check if the token can be taken
if ($token['token'] != "" && ($token['completed'] == "N" || $token['completed'] == "") && $bCreatePermission) { if ($token['token'] != "" && ($token['completed'] == "N" || $token['completed'] == "" || $aSurveyInfo['alloweditaftercompletion']=="Y") && $bCreatePermission) {
$action .= viewHelper::getImageLink('do_16.png', "survey/index/sid/{$iSurveyId}/token/{$token['token']}/lang/{$token['language']}/newtest/Y", $clang->gT("Do survey"), '_blank'); $action .= viewHelper::getImageLink('do_16.png', "survey/index/sid/{$iSurveyId}/token/{$token['token']}/lang/{$token['language']}/newtest/Y", $clang->gT("Do survey"), '_blank');
} else { } else {
$action .= '<div style="width: 20px; height: 16px; float: left;"></div>'; $action .= '<div style="width: 20px; height: 16px; float: left;"></div>';
@ -866,7 +876,7 @@ class tokens extends Survey_Common_Action
SurveyLink::model()->deleteTokenLink($aTokenIds, $iSurveyID); SurveyLink::model()->deleteTokenLink($aTokenIds, $iSurveyID);
//Then delete the tokens //Then delete the tokens
Token::model($iSurveyID)->deleteByPk($aTokenIds); Token::model($iSurveyID)->deleteByPk($aTokenIds);
} }
} }
@ -920,7 +930,6 @@ class tokens extends Survey_Common_Action
$aData = array('firstname' => Yii::app()->request->getPost('firstname'), $aData = array('firstname' => Yii::app()->request->getPost('firstname'),
'lastname' => Yii::app()->request->getPost('lastname'), 'lastname' => Yii::app()->request->getPost('lastname'),
'email' => Yii::app()->request->getPost('email'), 'email' => Yii::app()->request->getPost('email'),
'emailstatus' => 'OK',
'token' => $santitizedtoken, 'token' => $santitizedtoken,
'language' => sanitize_languagecode(Yii::app()->request->getPost('language')), 'language' => sanitize_languagecode(Yii::app()->request->getPost('language')),
'sent' => 'N', 'sent' => 'N',
@ -1027,7 +1036,7 @@ class tokens extends Survey_Common_Action
{ {
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$iSurveyId = sanitize_int($iSurveyId); $iSurveyId = sanitize_int($iSurveyId);
if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update'))
{ {
Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page.");
$this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}"));
@ -1078,7 +1087,7 @@ class tokens extends Survey_Common_Action
{ {
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$iSurveyId = sanitize_int($iSurveyId); $iSurveyId = sanitize_int($iSurveyId);
if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update'))
{ {
Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page.");
$this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}"));
@ -1127,7 +1136,7 @@ class tokens extends Survey_Common_Action
Yii::app()->session['flashmessage'] = $clang->gT("No token table."); Yii::app()->session['flashmessage'] = $clang->gT("No token table.");
$this->getController()->redirect($this->getController()->createUrl("/admin/survey/sa/view/surveyid/{$iSurveyId}")); $this->getController()->redirect($this->getController()->createUrl("/admin/survey/sa/view/surveyid/{$iSurveyId}"));
} }
if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update'))
{ {
Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page.");
$this->getController()->redirect($this->getController()->createUrl("/admin/survey/sa/view/surveyid/{$iSurveyId}")); $this->getController()->redirect($this->getController()->createUrl("/admin/survey/sa/view/surveyid/{$iSurveyId}"));
@ -1161,9 +1170,14 @@ class tokens extends Survey_Common_Action
} }
elseif($sAttributeToDelete) elseif($sAttributeToDelete)
{ {
// Update field attributedescriptions in survey table
$aTokenAttributeDescriptions=decodeTokenAttributes(Survey::model()->findByPk($iSurveyId)->attributedescriptions);
unset($aTokenAttributeDescriptions[$sAttributeToDelete]);
Survey::model()->updateByPk($iSurveyId, array('attributedescriptions' => json_encode($aTokenAttributeDescriptions)));
$sTableName="{{tokens_".intval($iSurveyId)."}}"; $sTableName="{{tokens_".intval($iSurveyId)."}}";
Yii::app()->db->createCommand(Yii::app()->db->getSchema()->dropColumn($sTableName, $sAttributeToDelete))->execute(); Yii::app()->db->createCommand(Yii::app()->db->getSchema()->dropColumn($sTableName, $sAttributeToDelete))->execute();
Yii::app()->db->schema->getTable($sTableName, true); // Refresh schema cache just in case the table existed in the past Yii::app()->db->schema->getTable($sTableName, true); // Refresh schema cache
LimeExpressionManager::SetDirtyFlag(); LimeExpressionManager::SetDirtyFlag();
Yii::app()->session['flashmessage'] = sprintf($clang->gT("Attribute %s was deleted."), $sAttributeToDelete); Yii::app()->session['flashmessage'] = sprintf($clang->gT("Attribute %s was deleted."), $sAttributeToDelete);
Yii::app()->getController()->redirect(Yii::app()->getController()->createUrl("/admin/tokens/sa/managetokenattributes/surveyid/$iSurveyId")); Yii::app()->getController()->redirect(Yii::app()->getController()->createUrl("/admin/tokens/sa/managetokenattributes/surveyid/$iSurveyId"));
@ -1182,7 +1196,7 @@ class tokens extends Survey_Common_Action
{ {
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$iSurveyId = sanitize_int($iSurveyId); $iSurveyId = sanitize_int($iSurveyId);
if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyID, 'surveysettings', 'update')) if (!Permission::model()->hasSurveyPermission($iSurveyId, 'tokens', 'update') && !Permission::model()->hasSurveyPermission($iSurveyId, 'surveysettings', 'update'))
{ {
Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page."); Yii::app()->session['flashmessage'] = $clang->gT("You do not have sufficient rights to access this page.");
$this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}")); $this->getController()->redirect(array("/admin/survey/sa/view/surveyid/{$iSurveyId}"));
@ -1211,7 +1225,7 @@ class tokens extends Survey_Common_Action
$captions[$language][$fieldname] = $_POST["caption_{$fieldname}_$language"]; $captions[$language][$fieldname] = $_POST["caption_{$fieldname}_$language"];
} }
Survey::model()->updateByPk($iSurveyId, array('attributedescriptions' => serialize($fieldcontents))); Survey::model()->updateByPk($iSurveyId, array('attributedescriptions' => json_encode($fieldcontents)));
foreach ($languages as $language) foreach ($languages as $language)
{ {
$ls = SurveyLanguageSetting::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyId, 'surveyls_language' => $language)); $ls = SurveyLanguageSetting::model()->findByAttributes(array('surveyls_survey_id' => $iSurveyId, 'surveyls_language' => $language));
@ -1558,7 +1572,7 @@ class tokens extends Survey_Common_Action
} }
else else
{ {
$aData['tokenoutput'].='<b>All emails were sent.</b>'; $aData['tokenoutput'].="<strong class='result success text-success'>".gT("All emails were sent.")."<strong>";
} }
$this->_renderWrappedTemplate('token', $aViewUrls, $aData); $this->_renderWrappedTemplate('token', $aViewUrls, $aData);
@ -1570,7 +1584,7 @@ class tokens extends Survey_Common_Action
'message' => $clang->gT("There were no eligible emails to send. This will be because none satisfied the criteria of:") 'message' => $clang->gT("There were no eligible emails to send. This will be because none satisfied the criteria of:")
. "<br/>&nbsp;<ul><li>" . $clang->gT("having a valid email address") . "</li>" . "<br/>&nbsp;<ul><li>" . $clang->gT("having a valid email address") . "</li>"
. "<li>" . $clang->gT("not having been sent an invitation already") . "</li>" . "<li>" . $clang->gT("not having been sent an invitation already") . "</li>"
. "<li>" . $clang->gT("having already completed the survey") . "</li>" . "<li>" . $clang->gT("not having already completed the survey") . "</li>"
. "<li>" . $clang->gT("having a token") . "</li></ul>" . "<li>" . $clang->gT("having a token") . "</li></ul>"
)), $aData); )), $aData);
} }
@ -1922,6 +1936,7 @@ class tokens extends Survey_Common_Action
$duplicatelist = array(); $duplicatelist = array();
$invalidemaillist = array(); $invalidemaillist = array();
$invalidformatlist = array(); $invalidformatlist = array();
$errorlist = array();
$firstline = array(); $firstline = array();
$sPath = Yii::app()->getConfig('tempdir'); $sPath = Yii::app()->getConfig('tempdir');
@ -1984,7 +1999,7 @@ class tokens extends Survey_Common_Action
$separator = ';'; else $separator = ';'; else
$separator = ','; $separator = ',';
} }
$firstline = convertCSVRowToArray($buffer, $separator, '"'); $firstline = str_getcsv($buffer, $separator, '"');
$firstline = array_map('trim', $firstline); $firstline = array_map('trim', $firstline);
$ignoredcolumns = array(); $ignoredcolumns = array();
// Now check the first line for invalid fields // Now check the first line for invalid fields
@ -2010,16 +2025,15 @@ class tokens extends Survey_Common_Action
else else
{ {
$line = convertCSVRowToArray($buffer, $separator, '"'); $line = str_getcsv($buffer, $separator, '"');
if (count($firstline) != count($line)) if (count($firstline) != count($line))
{ {
$invalidformatlist[] = $recordcount; $invalidformatlist[] = sprintf(gt("Line %s"),$recordcount);
$recordcount++; $recordcount++;
continue; continue;
} }
$writearray = array_combine($firstline, $line); $writearray = array_combine($firstline, $line);
//kick out ignored columns //kick out ignored columns
foreach ($ignoredcolumns as $column) foreach ($ignoredcolumns as $column)
{ {
@ -2030,29 +2044,34 @@ class tokens extends Survey_Common_Action
if ($filterduplicatetoken != false) if ($filterduplicatetoken != false)
{ {
$dupquery = "SELECT count(tid) from {{tokens_".intval($iSurveyId)."}} where 1=1"; $aParams=array();
$oCriteria= new CDbCriteria;
$oCriteria->condition="";
foreach ($filterduplicatefields as $field) foreach ($filterduplicatefields as $field)
{ {
if (isset($writearray[$field])) if (isset($writearray[$field]))
{ {
$dupquery.= " and ".Yii::app()->db->quoteColumnName($field)." = " . Yii::app()->db->quoteValue($writearray[$field]); $oCriteria->addCondition("{$field} = :{$field}");
$aParams[":{$field}"]=$writearray[$field];
} }
} }
$dupresult = Yii::app()->db->createCommand($dupquery)->queryScalar(); if(!empty($aParams))
$oCriteria->params=$aParams;
$dupresult = TokenDynamic::model($iSurveyId)->count($oCriteria);
if ($dupresult > 0) if ($dupresult > 0)
{ {
$dupfound = true; $dupfound = true;
$duplicatelist[] = Yii::app()->db->quoteValue($writearray['firstname']) . " " . Yii::app()->db->quoteValue($writearray['lastname']) . " (" . Yii::app()->db->quoteValue($writearray['email']) . ")"; $duplicatelist[] = sprintf(gt("Line %s : %s %s (%s)"),$recordcount,$writearray['firstname'],$writearray['lastname'],$writearray['email']);
} }
} }
$writearray['email'] = trim($writearray['email']); $writearray['email'] = trim($writearray['email']);
//treat blank emails //treat blank emails
if ($filterblankemail && $writearray['email'] == '') if (!$dupfound && $filterblankemail && $writearray['email'] == '')
{ {
$invalidemail = true; $invalidemail = true;
$invalidemaillist[] = $line[0] . " " . $line[1] . " ( )"; $invalidemaillist[] = $line[0] . " " . $line[1] . " ( )";
} }
if ($writearray['email'] != '') if (!$dupfound && $writearray['email'] != '')
{ {
$aEmailAddresses = explode(';', $writearray['email']); $aEmailAddresses = explode(';', $writearray['email']);
foreach ($aEmailAddresses as $sEmailaddress) foreach ($aEmailAddresses as $sEmailaddress)
@ -2068,6 +2087,15 @@ class tokens extends Survey_Common_Action
if (isset($writearray['token'])) if (isset($writearray['token']))
{ {
$writearray['token'] = sanitize_token($writearray['token']); $writearray['token'] = sanitize_token($writearray['token']);
if(!$dupfound && $writearray['token']) // We allways filter duplicate token
{
$dupresult = TokenDynamic::model($iSurveyId)->count("token=:token",array('token'=>$writearray['token']));
if($dupresult>0)
{
$duplicatelist[] = sprintf(gt("Line %s : token %s already used."),$recordcount,$writearray['token']);
$dupfound=true;
}
}
} }
if (!$dupfound && !$invalidemail) if (!$dupfound && !$invalidemail)
@ -2075,25 +2103,27 @@ class tokens extends Survey_Common_Action
// unset all empty value // unset all empty value
foreach ($writearray as $key=>$value) foreach ($writearray as $key=>$value)
{ {
if($writearray[$key]=="") if($writearray[$key]=="" && !in_array($key,array('firstname','lastname','email')))
unset($writearray[$key]); unset($writearray[$key]);
if (substr($value, 0, 1)=='"' && substr($value, -1)=='"')// Fix CSV quote if (substr($value, 0, 1)=='"' && substr($value, -1)=='"')// Fix CSV quote
$value = substr($value, 1, -1); $value = substr($value, 1, -1);
} }
// Some default value : to be moved to Token model rules in future release ? // Some default value : to be moved to Token model rules in future release ?
// But think we have to accept invalid email etc ... then use specific scenario // But think we have to accept invalid email etc ... then use specific scenario
$writearray['emailstatus']=isset($writearray['emailstatus'])?$writearray['emailstatus']:"OK"; //$writearray['emailstatus']=isset($writearray['emailstatus'])?$writearray['emailstatus']:"OK";
$writearray['language']=isset($writearray['language'])?$writearray['language']:$sBaseLanguage; $writearray['language']=isset($writearray['language'])?$writearray['language']:$sBaseLanguage;
$oToken = Token::create($iSurveyId); //$oToken = Token::create($iSurveyId);//
TokenDynamic::sid($iSurveyId);
$oToken = new TokenDynamic;
foreach ($writearray as $key => $value) foreach ($writearray as $key => $value)
{ {
//if(in_array($key,$oToken->attributes)) Not needed because we filter attributes before //if(in_array($key,$oToken->attributes)) Not needed because we filter attributes before
$oToken->$key=$value; $oToken->$key=$value;
} }
$ir=$oToken->save(); if (!$oToken->save())
if (!$ir)
{ {
$duplicatelist[] = $writearray['firstname'] . " " . $writearray['lastname'] . " (" . $writearray['email'] . ")"; $errorlist[] = sprintf(gt("Line %s : %s %s (%s)"),$recordcount,$writearray['firstname'],$writearray['lastname'],$writearray['email']);
tracevar($oToken->getErrors());
} }
else else
{ {
@ -2116,6 +2146,7 @@ class tokens extends Survey_Common_Action
$aData['duplicatelist'] = $duplicatelist; $aData['duplicatelist'] = $duplicatelist;
$aData['invalidformatlist'] = $invalidformatlist; $aData['invalidformatlist'] = $invalidformatlist;
$aData['invalidemaillist'] = $invalidemaillist; $aData['invalidemaillist'] = $invalidemaillist;
$aData['errorlist'] = $errorlist;
$aData['thissurvey'] = getSurveyInfo($iSurveyId); $aData['thissurvey'] = getSurveyInfo($iSurveyId);
$aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId; $aData['iSurveyId'] = $aData['surveyid'] = $iSurveyId;
@ -2309,7 +2340,6 @@ class tokens extends Survey_Common_Action
} }
else else
{ {
App()->getClientScript()->registerScriptFile(Yii::app()->getConfig('adminscripts') . "tokenbounce.js");
$this->_renderWrappedTemplate('token', array('tokenbar', 'bounce'), $aData); $this->_renderWrappedTemplate('token', array('tokenbar', 'bounce'), $aData);
} }
} }
@ -2423,7 +2453,7 @@ class tokens extends Survey_Common_Action
); );
} }
} }
Survey::model()->updateByPk($iSurveyId, array('attributedescriptions' => serialize($fieldcontents))); Survey::model()->updateByPk($iSurveyId, array('attributedescriptions' => json_encode($fieldcontents)));
Yii::app()->db->createCommand()->renameTable(Yii::app()->request->getPost('oldtable'), Yii::app()->db->tablePrefix."tokens_".intval($iSurveyId)); Yii::app()->db->createCommand()->renameTable(Yii::app()->request->getPost('oldtable'), Yii::app()->db->tablePrefix."tokens_".intval($iSurveyId));
@ -2466,6 +2496,7 @@ class tokens extends Survey_Common_Action
$this->_renderWrappedTemplate('token', 'tokenwarning', $aData); $this->_renderWrappedTemplate('token', 'tokenwarning', $aData);
} }
Yii::app()->end();
} }
/** /**

View file

@ -1017,29 +1017,35 @@ class translate extends Survey_Common_Action {
return $image; return $image;
} }
public function ajaxtranslategoogleapi()
{
// Ensure YII_CSRF_TOKEN, we are in admin, then only user with admin rigth can post
if(Yii::app()->request->isPostRequest)
{
echo self::translate_google_api();
}
}
/* /*
* translate_google_api.php * translate_google_api.php
* Creates a JSON interface for the auto-translate feature * Creates a JSON interface for the auto-translate feature
*/ */
private function translate_google_api() private function translate_google_api()
{ {
header('Content-type: application/json');
$sBaselang = Yii::app()->getRequest()->getPost('baselang'); $sBaselang = Yii::app()->getRequest()->getPost('baselang');
$sTolang = Yii::app()->getRequest()->getPost('tolang'); $sTolang = Yii::app()->getRequest()->getPost('tolang');
$sToconvert = Yii::app()->getRequest()->getPost('text'); $sToconvert = Yii::app()->getRequest()->getPost('text');
$aSearch = array('zh-Hans','zh-Hant-HK','zh-Hant-TW', $aSearch = array('zh-Hans','zh-Hant-HK','zh-Hant-TW','nl-informal','de-informal','it-formal','pt-BR','es-MX','nb','nn');
'nl-informal','de-informal','it-formal','pt-BR','es-MX','nb','nn');
$aReplace = array('zh-CN','zh-TW','zh-TW','nl','de','it','pt','es','no','no'); $aReplace = array('zh-CN','zh-TW','zh-TW','nl','de','it','pt','es','no','no');
$sBaselang = str_replace($aSearch, $aReplace, $sBaselang);
$sTolang = str_replace($aSearch, $aReplace, $sTolang); $sTolang = str_replace($aSearch, $aReplace, $sTolang);
$error = FALSE; $error = false;
try try
{ {
Yii::app()->loadLibrary('admin/gtranslate/GTranslate'); Yii::app()->loadLibrary('admin/gtranslate/GTranslate');
$gtranslate = new Gtranslate(); $gtranslate = new Gtranslate();
$objGt = $gtranslate; $objGt = $gtranslate;
// Gtranslate requires you to run function named XXLANG_to_XXLANG // Gtranslate requires you to run function named XXLANG_to_XXLANG
@ -1078,7 +1084,9 @@ class translate extends Survey_Common_Action {
'converted' => $sOutput 'converted' => $sOutput
); );
return ls_json_encode($aOutput) . "\n"; header('Content-type: application/json');
return ls_json_encode($aOutput);
Yii::app()->end();
} }
/** /**

View file

@ -147,16 +147,21 @@ class update extends Survey_Common_Action
function step2() function step2()
{ {
$aReadOnlyFiles=array();
$clang = $this->getController()->lang; $clang = $this->getController()->lang;
$buildnumber = Yii::app()->getConfig("buildnumber"); $buildnumber = Yii::app()->getConfig("buildnumber");
$updatebuild = getGlobalSetting("updatebuild"); $updatebuild = getGlobalSetting("updatebuild");
list($error, $updateinfo, $cookies) = $this->_getChangedFiles($buildnumber, $updatebuild); list($error, $updateinfo, $cookies) = $this->_getChangedFiles($buildnumber, $updatebuild);
$aData = $this->_getFileStatus($updateinfo); $aData = $this->_getFileStatus($updateinfo);
$aReadOnlyFiles=array_unique($aData['readonlyfiles']); if(count($aData['readonlyfiles']))
sort($aReadOnlyFiles); {
$aData['readonlyfiles']=$aReadOnlyFiles; foreach (array_unique($aData['readonlyfiles']) as $aFile)
{
$aReadOnlyFiles[]=substr($aFile,strlen(Yii::app()->getConfig("rootdir")));
}
sort($aReadOnlyFiles);
$aData['readonlyfiles']=$aReadOnlyFiles;
}
Yii::app()->session['updateinfo'] = $updateinfo; Yii::app()->session['updateinfo'] = $updateinfo;
Yii::app()->session['updatesession'] = $cookies; Yii::app()->session['updatesession'] = $cookies;
@ -292,7 +297,7 @@ class update extends Survey_Common_Action
if ((in_array($aDatabasetype, array('mysql', 'mysqli'))) && Yii::app()->getConfig('demoMode') != true) { if ((in_array($aDatabasetype, array('mysql', 'mysqli'))) && Yii::app()->getConfig('demoMode') != true) {
Yii::app()->loadHelper("admin/backupdb"); Yii::app()->loadHelper("admin/backupdb");
$sfilename = $tempdir.DIRECTORY_SEPARATOR."backup_db_".randomChars(20)."_".dateShift(date("Y-m-d H:i:s"), "Y-m-d", Yii::app()->getConfig('timeadjust')).".sql"; $sfilename = $tempdir.DIRECTORY_SEPARATOR."backup_db_".randomChars(20)."_".dateShift(date("Y-m-d H:i:s"), "Y-m-d", Yii::app()->getConfig('timeadjust')).".sql";
$dfilename = $tempdir.DIRECTORY_SEPARATOR."LimeSurvey_database_backup_".$basefilename.".sql.gz"; $dfilename = $tempdir.DIRECTORY_SEPARATOR."LimeSurvey_database_backup_".$basefilename.".zip";
outputDatabase('',false,$sfilename); outputDatabase('',false,$sfilename);
// Before try to zip: test size of file // Before try to zip: test size of file

View file

@ -119,7 +119,7 @@ class UserAction extends Survey_Common_Action
$body = sprintf($clang->gT("Hello %s,"), $new_full_name) . "<br /><br />\n"; $body = sprintf($clang->gT("Hello %s,"), $new_full_name) . "<br /><br />\n";
$body .= sprintf($clang->gT("this is an automated email to notify that a user has been created for you on the site '%s'."), Yii::app()->getConfig("sitename")) . "<br /><br />\n"; $body .= sprintf($clang->gT("this is an automated email to notify that a user has been created for you on the site '%s'."), Yii::app()->getConfig("sitename")) . "<br /><br />\n";
$body .= $clang->gT("You can use now the following credentials to log into the site:") . "<br />\n"; $body .= $clang->gT("You can use now the following credentials to log into the site:") . "<br />\n";
$body .= $clang->gT("Username") . ": " . $new_user . "<br />\n"; $body .= $clang->gT("Username") . ": " . htmlspecialchars($new_user) . "<br />\n";
if (Yii::app()->getConfig("auth_webserver") === false) { // authent is not delegated to web server if (Yii::app()->getConfig("auth_webserver") === false) { // authent is not delegated to web server
// send password (if authorized by config) // send password (if authorized by config)
if (Yii::app()->getConfig("display_user_password_in_email") === true) { if (Yii::app()->getConfig("display_user_password_in_email") === true) {

View file

@ -337,11 +337,18 @@ class Usergroups extends Survey_Common_Action
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$uid = (int) Yii::app()->request->getPost('uid'); $uid = (int) Yii::app()->request->getPost('uid');
$group = UserGroup::model()->findByAttributes(array('ugid' => $ugid, 'owner_id' => Yii::app()->session['loginID'])); if (Permission::model()->hasGlobalPermission('superadmin','read'))
{
$group = UserGroup::model()->findByAttributes(array('ugid' => $ugid));
}
else
{
$group = UserGroup::model()->findByAttributes(array('ugid' => $ugid, 'owner_id' => Yii::app()->session['loginID']));
}
if (empty($group)) if (empty($group))
{ {
list($aViewUrls, $aData) = $this->index(0, array('type' => 'warning', 'message' => $clang->gT('Failed.') . '<br />' . $clang->gT('Group not found.'))); list($aViewUrls, $aData) = $this->index(0, array('type' => 'warning', 'message' => $clang->gT('Failed.') . ' ' . $clang->gT('You are ')));
} }
else else
{ {
@ -349,35 +356,36 @@ class Usergroups extends Survey_Common_Action
{ {
if ($group->owner_id == $uid) if ($group->owner_id == $uid)
{ {
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'warning', 'message' => $clang->gT('Failed.') . '<br />' . $clang->gT('You can not add or remove the group owner from the group.'))); list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'warning', 'message' => $clang->gT('Failed.') . ' ' . $clang->gT('You can not add or remove the group owner from the group.')));
} }
else {
$user_in_group = UserInGroup::model()->findByPk(array('ugid' => $ugid, 'uid' => $uid));
$user_in_group = UserInGroup::model()->findByPk(array('ugid' => $ugid, 'uid' => $uid)); switch ($action)
{
case 'add' :
if (empty($user_in_group) && UserInGroup::model()->insertRecords(array('ugid' => $ugid, 'uid' => $uid)))
{
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'success', 'message' => $clang->gT('User added.')));
}
else
{
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'warning', 'message' => $clang->gT('Failed to add user.') . ' ' . $clang->gT('User already exists in the group.')));
}
switch ($action) break;
{ case 'remove' :
case 'add' : if (!empty($user_in_group) && UserInGroup::model()->deleteByPk(array('ugid' => $ugid, 'uid' => $uid)))
if (empty($user_in_group) && UserInGroup::model()->insertRecords(array('ugid' => $ugid, 'uid' => $uid))) {
{ list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'success', 'message' => $clang->gT('User removed.')));
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'success', 'message' => $clang->gT('User added.'))); }
} else
else {
{ list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'warning', 'message' => $clang->gT('Failed to remove user.') . ' ' . $clang->gT('User does not exist in the group.')));
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'warning', 'message' => $clang->gT('Failed to add user.') . '<br />' . $clang->gT('User already exists in the group.'))); }
}
break; break;
case 'remove' : }
if (!empty($user_in_group) && UserInGroup::model()->deleteByPk(array('ugid' => $ugid, 'uid' => $uid)))
{
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'success', 'message' => $clang->gT('User removed.')));
}
else
{
list($aViewUrls, $aData) = $this->index($ugid, array('type' => 'warning', 'message' => $clang->gT('Failed to remove user.') . '<br />' . $clang->gT('User does not exist in the group.')));
}
break;
} }
} }
else else

View file

@ -69,7 +69,7 @@ class index extends CAction {
$thisstep = $param['thisstep']; $thisstep = $param['thisstep'];
$move=getMove(); $move=getMove();
Yii::app()->setConfig('move',$move); Yii::app()->setConfig('move',$move);
$clienttoken = $param['token']; $clienttoken = trim($param['token']);
$standardtemplaterootdir = Yii::app()->getConfig('standardtemplaterootdir'); $standardtemplaterootdir = Yii::app()->getConfig('standardtemplaterootdir');
if (is_null($thissurvey) && !is_null($surveyid)) $thissurvey = getSurveyInfo($surveyid); if (is_null($thissurvey) && !is_null($surveyid)) $thissurvey = getSurveyInfo($surveyid);
@ -313,9 +313,6 @@ class index extends CAction {
} }
} }
$_SESSION['survey_'.$surveyid]['holdname'] = $sLoadName;
$_SESSION['survey_'.$surveyid]['holdpass'] = $sLoadPass;
if ($errormsg == "") { if ($errormsg == "") {
LimeExpressionManager::SetDirtyFlag(); LimeExpressionManager::SetDirtyFlag();
buildsurveysession($surveyid); buildsurveysession($surveyid);
@ -378,27 +375,35 @@ class index extends CAction {
} }
if (!isset($tokenInstance)) if (!isset($tokenInstance))
{ {
$tk = Token::model($surveyid)->findByAttributes(array('token' => $token)); $oToken = Token::model($surveyid)->findByAttributes(array('token' => $token));
if($tk->completed == 'N') if($oToken)
{ {
$now = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", Yii::app()->getConfig("timeadjust")); $now = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", Yii::app()->getConfig("timeadjust"));
if(strtotime($now) < strtotime($tk->validfrom)) if($oToken->completed != 'N' && !empty($oToken->completed))
{ {
$err = $clang->gT("This invitation is not valid yet."); $sError = $clang->gT("This invitation has already been used.");
} }
else elseif(strtotime($now) < strtotime($oToken->validfrom))
{ {
$err = $clang->gT("This invitation is not valid anymore."); $sError = $clang->gT("This invitation is not valid yet.");
}
elseif(strtotime($now) > strtotime($oToken->validuntil))
{
$sError = $clang->gT("This invitation is not valid anymore.");
}
else // This can not happen
{
$sError = $clang->gT("This is a controlled survey. You need a valid token to participate.");
} }
} }
else else
{ {
$err = $clang->gT("This invitation has already been used."); $sError = $clang->gT("This is a controlled survey. You need a valid token to participate.");
} }
$asMessage = array( $asMessage = array(
null, null,
$clang->gT("We are sorry but you are not allowed to enter this survey."), $clang->gT("We are sorry but you are not allowed to enter this survey."),
$err, $sError,
sprintf($clang->gT("For further information please contact %s"), $thissurvey['adminname']." (<a href='mailto:{$thissurvey['adminemail']}'>"."{$thissurvey['adminemail']}</a>)") sprintf($clang->gT("For further information please contact %s"), $thissurvey['adminname']." (<a href='mailto:{$thissurvey['adminemail']}'>"."{$thissurvey['adminemail']}</a>)")
); );
@ -499,25 +504,52 @@ class index extends CAction {
if (!isset($_SESSION['survey_'.$surveyid]['srid']) && $thissurvey['anonymized'] == "N" && $thissurvey['active'] == "Y" && isset($token) && $token !='') if (!isset($_SESSION['survey_'.$surveyid]['srid']) && $thissurvey['anonymized'] == "N" && $thissurvey['active'] == "Y" && isset($token) && $token !='')
{ {
// load previous answers if any (dataentry with nosubmit) // load previous answers if any (dataentry with nosubmit)
//$oSurveyTokenInstance=SurveyDynamic::model($surveyid)->find(array('select'=>'id,submitdate,lastpage', 'condition'=>'token=:token', 'order'=>'id DESC','params'=>array('token' => $token))); $oResponses = Response::model($surveyid)->findAllByAttributes(array(
$oSurveyTokenInstance=SurveyDynamic::model($surveyid)->find(array('condition'=>'token=:token', 'order'=>'id DESC','params'=>array('token' => $token))); 'token' => $token
if ( $oSurveyTokenInstance ) ), array('order' => 'id DESC'));
if (!empty($oResponses))
{ {
if((empty($oSurveyTokenInstance->submitdate) || $thissurvey['alloweditaftercompletion'] == 'Y' ) && $thissurvey['tokenanswerspersistence'] == 'Y') /**
* We fire the response selection event when at least 1 response was found.
* If there is just 1 response the plugin still has to option to choose
* NOT to use it.
*/
$event = new PluginEvent('beforeLoadResponse');
$event->set('responses', $oResponses);
$event->set('surveyId', $surveyid);
App()->pluginManager->dispatchEvent($event);
$oResponse = $event->get('response');
// If $oResponse is false we act as if no response was found.
// This allows a plugin to deny continuing a response.
if ($oResponse !== false)
{ {
$_SESSION['survey_'.$surveyid]['srid'] = $oSurveyTokenInstance->id; // If plugin does not set a response we use the first one found, (this replicates pre-plugin behavior)
if (!empty($oSurveyTokenInstance->lastpage)) if (!isset($oResponse) && (!isset($oResponses[0]->submitdate) || $thissurvey['alloweditaftercompletion'] == 'Y') && $thissurvey['tokenanswerspersistence'] == 'Y')
{ {
$_SESSION['survey_'.$surveyid]['LEMtokenResume'] = true; $oResponse = $oResponses[0];
$_SESSION['survey_'.$surveyid]['step'] = $oSurveyTokenInstance->lastpage; }
if (isset($oResponse))
{
$_SESSION['survey_'.$surveyid]['srid'] = $oResponse->id;
if (!empty($oResponse->lastpage))
{
$_SESSION['survey_'.$surveyid]['LEMtokenResume'] = true;
// If the response was completed and user is allowed to edit after completion start at the beginning and not at the last page - just makes more sense
if (!($oResponse->submitdate && $thissurvey['alloweditaftercompletion'] == 'Y'))
{
$_SESSION['survey_'.$surveyid]['step'] = $oResponse->lastpage;
}
}
buildsurveysession($surveyid);
if(!empty($oResponse->submitdate)) // alloweditaftercompletion
{
$_SESSION['survey_'.$surveyid]['maxstep'] = $_SESSION['survey_'.$surveyid]['totalsteps'];
}
loadanswers();
} }
} }
buildsurveysession($surveyid);
if(!empty($oSurveyTokenInstance->submitdate)) // alloweditaftercompletion
{
$_SESSION['survey_'.$surveyid]['maxstep'] = $_SESSION['survey_'.$surveyid]['totalsteps'];
}
loadanswers();
} }
} }
// Preview action : Preview right already tested before // Preview action : Preview right already tested before

View file

@ -66,7 +66,7 @@ class LSUserIdentity extends CUserIdentity {
// Delegate actual authentication to plugin // Delegate actual authentication to plugin
$authEvent = new PluginEvent('newUserSession', $this); $authEvent = new PluginEvent('newUserSession', $this);
$authEvent->set('identity', $this); $authEvent->set('identity', $this);
App()->getPluginManager()->dispatchEvent($authEvent, array($this->plugin)); App()->getPluginManager()->dispatchEvent($authEvent);
$pluginResult = $authEvent->get('result'); $pluginResult = $authEvent->get('result');
if ($pluginResult instanceof LSAuthResult) { if ($pluginResult instanceof LSAuthResult) {
$result = $pluginResult; $result = $pluginResult;

View file

@ -0,0 +1,47 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
* LimeSurvey
* Copyright (C) 2007-2011 The LimeSurvey Project Team / Carsten Schmitz
* All rights reserved.
* License: GNU/GPL License v2 or later, see LICENSE.php
* LimeSurvey is free software. This version may have been modified pursuant
* to the GNU General Public License, and as distributed it includes or
* is derivative of works licensed under the GNU General Public License or
* other free or open source software licenses.
* See COPYRIGHT.php for copyright notices and details.
*
*/
class LSYii_CaseValidator extends CValidator {
public $type='lower';
public function validateAttribute($object,$attribute){
if ($this->type=='upper')
{
if (strtoupper($object->$attribute)==$object->$attribute){
return;
}
else
{
$this->addError($object, $attribute, gT('Text needs to be uppercase.'));
return;
}
}
else // default to lowercase
{
if (strtolower($object->$attribute)==$object->$attribute){
return;
}
else
{
$this->addError($object, $attribute, gT('Text needs to be lowercase.'));
return;
}
}
return;
}
}

View file

@ -36,7 +36,7 @@ class LSYii_EmailIDNAValidator extends CValidator {
foreach ($aEmailAdresses as $sEmailAddress) foreach ($aEmailAdresses as $sEmailAddress)
{ {
if (!validateEmailAddress($object->$attribute)) if (!validateEmailAddress($sEmailAddress))
{ {
$this->addError($object, $attribute, gT('Invalid email address.')); $this->addError($object, $attribute, gT('Invalid email address.'));
return; return;

View file

@ -54,7 +54,7 @@ class LSYii_Validators extends CValidator {
if($this->isUrl) if($this->isUrl)
{ {
if ($object->$attribute== 'http://' || $object->$attribute=='https://') {$object->$attribute="";} if ($object->$attribute== 'http://' || $object->$attribute=='https://') {$object->$attribute="";}
$object->$attribute=html_entity_decode($object->$attribute, ENT_QUOTES, "UTF-8"); // 140219 : Why not urlencode ? $object->$attribute=str_replace(array('"',"'",' ','<','>'),'',html_entity_decode($object->$attribute, ENT_QUOTES, "UTF-8")); // 140219 : Why not urlencode ?
} }
if($this->isLanguage) if($this->isLanguage)
{ {
@ -104,6 +104,7 @@ class LSYii_Validators extends CValidator {
$filter = new CHtmlPurifier(); $filter = new CHtmlPurifier();
$filter->options = array( $filter->options = array(
'AutoFormat.RemoveEmpty'=>false, 'AutoFormat.RemoveEmpty'=>false,
'Core.NormalizeNewlines'=>false,
'CSS.AllowTricky'=>true, // Allow display:none; (and other) 'CSS.AllowTricky'=>true, // Allow display:none; (and other)
'HTML.SafeObject'=>true, // To allow including youtube 'HTML.SafeObject'=>true, // To allow including youtube
'Output.FlashCompat'=>true, 'Output.FlashCompat'=>true,
@ -119,22 +120,29 @@ class LSYii_Validators extends CValidator {
) )
); );
// To allow script BUT purify : HTML.Trusted=true (plugin idea for admin or without XSS filtering ?) // To allow script BUT purify : HTML.Trusted=true (plugin idea for admin or without XSS filtering ?)
/** Start to get complete filtered value with url decode {QCODE} (bug #09300). This allow only question number in url, seems OK with XSS protection **/
$sFiltered=preg_replace('#%7B([a-zA-Z0-9\.]*)%7D#','{$1}',$filter->purify($value));
Yii::import('application.helpers.expressions.em_core_helper');// Already imported in em_manager_helper.php ? Yii::import('application.helpers.expressions.em_core_helper');// Already imported in em_manager_helper.php ?
$oExpressionManager= new ExpressionManager; $oExpressionManager= new ExpressionManager;
/** We get 2 array : one filtered, other unfiltered **/
$aValues=$oExpressionManager->asSplitStringOnExpressions($value);// Return array of array : 0=>the string,1=>string length,2=>string type (STRING or EXPRESSION) $aValues=$oExpressionManager->asSplitStringOnExpressions($value);// Return array of array : 0=>the string,1=>string length,2=>string type (STRING or EXPRESSION)
$aFilteredValues=$oExpressionManager->asSplitStringOnExpressions($sFiltered);// Same but for the filtered string
$bCountIsOk=count($aValues)==count($aFilteredValues);
/** Construction of new string with unfiltered EM and filtered HTML **/
$sNewValue=""; $sNewValue="";
foreach($aValues as $aValue){ foreach($aValues as $key=>$aValue){
if($aValue[2]=="STRING") if($aValue[2]=="STRING")
$sNewValue.=$filter->purify($aValue[0]); $sNewValue.=$bCountIsOk ? $aFilteredValues[$key][0]:$filter->purify($aValue[0]);// If EM is broken : can throw invalid $key
else else
{ {
$sExpression=trim($aValue[0], '{}'); $sExpression=trim($aValue[0], '{}');
$sNewValue.="{"; $sNewValue.="{";
$aParsedExpressions=$oExpressionManager->Tokenize($sExpression,true);// Return array of array : 0=>the string,1=>string length,2=>string type $aParsedExpressions=$oExpressionManager->Tokenize($sExpression,true);
foreach($aParsedExpressions as $aParsedExpression) foreach($aParsedExpressions as $aParsedExpression)
{ {
if($aParsedExpression[2]=='DQ_STRING') if($aParsedExpression[2]=='DQ_STRING')
$sNewValue.="\"".$filter->purify($aParsedExpression[0])."\""; $sNewValue.="\"".$filter->purify($aParsedExpression[0])."\""; // This disallow complex HTML construction with XSS
elseif($aParsedExpression[2]=='SQ_STRING') elseif($aParsedExpression[2]=='SQ_STRING')
$sNewValue.="'".$filter->purify($aParsedExpression[0])."'"; $sNewValue.="'".$filter->purify($aParsedExpression[0])."'";
else else
@ -143,6 +151,7 @@ class LSYii_Validators extends CValidator {
$sNewValue.="}"; $sNewValue.="}";
} }
} }
gc_collect_cycles(); // To counter a high memory usage of HTML-Purifier
return $sNewValue; return $sNewValue;
} }
/** /**

View file

@ -816,7 +816,7 @@ class Survey_Common_Action extends CAction
if ($aSurveyInfo['surveyls_url'] != "") if ($aSurveyInfo['surveyls_url'] != "")
{ {
$aData['endurl'] = " <a target='_blank' href=\"" . flattenText($aSurveyInfo['surveyls_url']) . "\" title=\"" . flattenText($aSurveyInfo['surveyls_url']) . "\">".flattenText($aSurveyInfo['surveyls_urldescription'])."</a>"; $aData['endurl'] = " <a target='_blank' href=\"" . htmlspecialchars($aSurveyInfo['surveyls_url']) . "\" title=\"" . htmlspecialchars($aSurveyInfo['surveyls_url']) . "\">".flattenText($aSurveyInfo['surveyls_urldescription'])."</a>";
} }
else else
{ {

View file

@ -108,16 +108,6 @@ class AuthLDAP extends AuthPluginBase
->addContent(CHtml::tag('li', array(), "<label for='password'>" . gT("Password") . "</label><input name='password' id='password' type='password' size='40' maxlength='40' value='' />")); ->addContent(CHtml::tag('li', array(), "<label for='password'>" . gT("Password") . "</label><input name='password' id='password' type='password' size='40' maxlength='40' value='' />"));
} }
public function afterLoginFormSubmit()
{
// Here we handle post data
$request = $this->api->getRequest();
if ($request->getIsPostRequest()) {
$this->setUsername( $request->getPost('user'));
$this->setPassword($request->getPost('password'));
}
}
/** /**
* Modified getPluginSettings since we have a select box that autosubmits * Modified getPluginSettings since we have a select box that autosubmits
* and we only want to show the relevant options. * and we only want to show the relevant options.
@ -166,6 +156,13 @@ class AuthLDAP extends AuthPluginBase
public function newUserSession() public function newUserSession()
{ {
// Do nothing if this user is not Authdb type
$identity = $this->getEvent()->get('identity');
if ($identity->plugin != 'AuthLDAP')
{
return;
}
// Here we do the actual authentication // Here we do the actual authentication
$username = $this->getUsername(); $username = $this->getUsername();
$password = $this->getPassword(); $password = $this->getPassword();

View file

@ -2,13 +2,13 @@
class Authdb extends AuthPluginBase class Authdb extends AuthPluginBase
{ {
protected $storage = 'DbStorage'; protected $storage = 'DbStorage';
protected $_onepass = null; protected $_onepass = null;
static protected $description = 'Core: Database authentication + exports'; static protected $description = 'Core: Database authentication + exports';
static protected $name = 'LimeSurvey internal database'; static protected $name = 'LimeSurvey internal database';
public function __construct(PluginManager $manager, $id) { public function __construct(PluginManager $manager, $id)
{
parent::__construct($manager, $id); parent::__construct($manager, $id);
/** /**
@ -62,7 +62,6 @@ class Authdb extends AuthPluginBase
public function newLoginForm() public function newLoginForm()
{ {
$sUserName=''; $sUserName='';
$sPassword=''; $sPassword='';
if (Yii::app()->getConfig("demoMode") === true && Yii::app()->getConfig("demoModePrefill") === true) if (Yii::app()->getConfig("demoMode") === true && Yii::app()->getConfig("demoModePrefill") === true)
@ -76,18 +75,15 @@ class Authdb extends AuthPluginBase
->addContent(CHtml::tag('li', array(), "<label for='password'>" . gT("Password") . "</label>".CHtml::passwordField('password',$sPassword,array('size'=>40,'maxlength'=>40)))); ->addContent(CHtml::tag('li', array(), "<label for='password'>" . gT("Password") . "</label>".CHtml::passwordField('password',$sPassword,array('size'=>40,'maxlength'=>40))));
} }
public function afterLoginFormSubmit()
{
// Here we handle post data
$request = $this->api->getRequest();
if ($request->getIsPostRequest()) {
$this->setUsername( $request->getPost('user'));
$this->setPassword($request->getPost('password'));
}
}
public function newUserSession() public function newUserSession()
{ {
// Do nothing if this user is not Authdb type
$identity = $this->getEvent()->get('identity');
if ($identity->plugin != 'Authdb')
{
return;
}
// Here we do the actual authentication // Here we do the actual authentication
$username = $this->getUsername(); $username = $this->getUsername();
$password = $this->getPassword(); $password = $this->getPassword();
@ -95,7 +91,7 @@ class Authdb extends AuthPluginBase
$user = $this->api->getUserByName($username); $user = $this->api->getUserByName($username);
if ($user !== null) if ($user !== null and $username==$user->users_name) // Control of equality for uppercase/lowercase with mysql
{ {
if (gettype($user->password)=='resource') if (gettype($user->password)=='resource')
{ {
@ -125,7 +121,6 @@ class Authdb extends AuthPluginBase
$this->setAuthFailure(self::ERROR_PASSWORD_INVALID); $this->setAuthFailure(self::ERROR_PASSWORD_INVALID);
return; return;
} }
$this->setAuthSuccess($user); $this->setAuthSuccess($user);
} }

View file

@ -9,13 +9,18 @@ class Authwebserver extends AuthPluginBase
protected $settings = array( protected $settings = array(
'strip_domain' => array( 'strip_domain' => array(
'type' => 'checkbox', 'type' => 'checkbox',
'label' => 'Strip domain part (DOMAIN\\USER or USER@DOMAIN)' 'label' => 'Strip domain part (DOMAIN\\USER or USER@DOMAIN)',
), ),
'serverkey' => array( 'serverkey' => array(
'type' => 'string', 'type' => 'string',
'label' => 'Key to use for username e.g. PHP_AUTH_USER, LOGON_USER, REMOTE_USER. See phpinfo in global settings.', 'label' => 'Key to use for username e.g. PHP_AUTH_USER, LOGON_USER, REMOTE_USER. See phpinfo in global settings.',
'default' => 'REMOTE_USER' 'default' => 'REMOTE_USER',
), ),
'is_default' => array(
'type' => 'checkbox',
'label' => 'Check to make default authentication method (This disable Default LimeSurvey authentification by database)',
'default' => true,
)
); );
public function __construct(PluginManager $manager, $id) { public function __construct(PluginManager $manager, $id) {
@ -52,13 +57,28 @@ class Authwebserver extends AuthPluginBase
{ {
$sUser = $aUserMappings[$sUser]; $sUser = $aUserMappings[$sUser];
} }
$this->setUsername($sUser); $oUser = $this->api->getUserByName($sUser);
$this->setAuthPlugin(); // This plugin handles authentication, halt further execution of auth plugins if($oUser || $this->api->getConfigKey('auth_webserver_autocreate_user'))
{
$this->setUsername($sUser);
$this->setAuthPlugin(); // This plugin handles authentication, halt further execution of auth plugins
}
elseif($this->get('is_default',null,null,$this->settings['is_default']['default']))
{
throw new CHttpException(401,'Wrong credentials for LimeSurvey administration.');
}
} }
} }
public function newUserSession() public function newUserSession()
{ {
// Do nothing if this user is not Authwebserver type
$identity = $this->getEvent()->get('identity');
if ($identity->plugin != 'Authwebserver')
{
return;
}
/* @var $identity LSUserIdentity */ /* @var $identity LSUserIdentity */
$sUser = $this->getUserName(); $sUser = $this->getUserName();
@ -103,7 +123,6 @@ class Authwebserver extends AuthPluginBase
{ {
$this->setAuthFailure(self::ERROR_USERNAME_INVALID); $this->setAuthFailure(self::ERROR_USERNAME_INVALID);
} }
} }
} }

View file

@ -74,9 +74,9 @@ class RDataWriter extends CsvWriter {
} }
if ($value == 'Y') { // Yes if ($value == 'Y') { // Yes
return 1; return 2;
} elseif ($value === '') { // No } elseif ($value === '') { // No
return 0; return 1;
} else { // Not shown } else { // Not shown
return $this->na; return $this->na;
} }
@ -84,9 +84,9 @@ class RDataWriter extends CsvWriter {
case 'Y': // Yes no question case 'Y': // Yes no question
if ($value == 'Y') { if ($value == 'Y') {
return 1; return 2;
} elseif ($value == 'N') { } elseif ($value == 'N') {
return 0; return 1;
} else { } else {
// No data, probably a hidden question // No data, probably a hidden question
return $this->na; return $this->na;

View file

@ -351,7 +351,7 @@ class STATAxmlWriter extends Writer
if (empty($this->headers)) if (empty($this->headers))
{ {
$this->headers = $headers; $this->headers = $headers;
foreach ($this->headers as $iKey => $sVarname) foreach ($this->headers as $iKey => &$sVarname)
{ {
$this->headers[$iKey] = $this->STATAvarname($sVarname); $this->headers[$iKey] = $this->STATAvarname($sVarname);
} }
@ -366,10 +366,11 @@ class STATAxmlWriter extends Writer
*/ */
protected function updateCustomresponsemap() protected function updateCustomresponsemap()
{ {
//create array that holds each values' data type //go through each particpants' responses
foreach ($this->customResponsemap as $iRespId => $aResponses) foreach ($this->customResponsemap as $iRespId => &$aResponses)
{ {
foreach ($aResponses as $iVarid => $response) // go through variables and response items
foreach ($aResponses as $iVarid => &$response)
{ {
$response=trim($response); $response=trim($response);
//recode answercode=answer if codes are non-numeric (cannot be used with value labels) //recode answercode=answer if codes are non-numeric (cannot be used with value labels)
@ -382,18 +383,15 @@ class STATAxmlWriter extends Writer
{ {
$iScaleID = $this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['scale_id']; $iScaleID = $this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['scale_id'];
} }
$iQID = $this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['qid']; $iQID = $this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['qid'];
if (isset($this->customFieldmap['answers'][$iQID][$iScaleID][$response]['answer'])) if (isset($this->customFieldmap['answers'][$iQID][$iScaleID][$response]['answer']))
{ {
$response = trim($this->customFieldmap['answers'][$iQID][$iScaleID][$response]['answer']); // get answertext instead of answercode $response = trim($this->customFieldmap['answers'][$iQID][$iScaleID][$response]['answer']); // get answertext instead of answercode
} }
} }
if ($response == '')
{ if ($response != '')
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'emptystr';
}
else
{ {
// recode some values from letters to numeric, so we can attach value labels and have more time doing statistics // recode some values from letters to numeric, so we can attach value labels and have more time doing statistics
switch ($this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['type']) switch ($this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['type'])
@ -435,7 +433,16 @@ class STATAxmlWriter extends Writer
break; break;
} }
// look at each of the responses and fill $aDatatypes with the respective STATA data type /* look at each of the responses and determine STATA data type and format of the respective variables
datatypes coded as follows:
1=""
2=byte
3=int
4=long
5=float
6=double
7=string
*/
$numberresponse = trim($response); $numberresponse = trim($response);
if ($this->customFieldmap['info']['surveyls_numberformat'] == 1) // if settings: decimal seperator==',' if ($this->customFieldmap['info']['surveyls_numberformat'] == 1) // if settings: decimal seperator==','
{ {
@ -448,83 +455,98 @@ class STATAxmlWriter extends Writer
{ {
if ($numberresponse >= $this->minByte && $numberresponse <= $this->maxByte) if ($numberresponse >= $this->minByte && $numberresponse <= $this->maxByte)
{ {
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'byte'; //this response is of STATA type 'byte' $iDatatype=2; //this response is of STATA type 'byte'
} }
elseif ($numberresponse >= $this->minInt && $numberresponse <= $this->maxInt) elseif ($numberresponse >= $this->minInt && $numberresponse <= $this->maxInt)
{ {
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'int'; // and this is is 'int' $iDatatype=3; // and this is is 'int'
} }
else else
{ {
if ($this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['type'] == 'D') // if datefield then a 'double' data type is needed if ($this->customFieldmap['questions'][$this->headersSGQA[$iVarid]]['type'] == 'D') // if datefield then a 'double' data type is needed
{ {
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'double'; $iDatatype=6; // double
} }
else else
{ {
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'long'; $iDatatype=4; //long
} }
} }
} }
else //non-integer numeric response else //non-integer numeric response
{ {
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'float'; $iDatatype=5; // float
$response = $numberresponse; //replace in customResponsemap: value with '.' as decimal $response = $numberresponse; //replace in customResponsemap: value with '.' as decimal
} }
} }
else // non-numeric response else // non-numeric response
{ {
$aDatatypes[$this->headersSGQA[$iVarid]][$iRespId] = 'string'; $iDatatype=7; //string
$strlenarray[$this->headersSGQA[$iVarid]][$iRespId] = strlen($response); //for strings we need the length as well for the data type $iStringlength=strlen($response); //for strings we need the length for the format and the data type
} }
} }
$this->customResponsemap[$iRespId][$iVarid]=$response; //write the recoded response back to the response array else
{
$iDatatype=1; // response = ""
}
// initialize format and type (default: empty)
if (!isset($aStatatypelist[$this->headersSGQA[$iVarid]]['type']))
$aStatatypelist[$this->headersSGQA[$iVarid]]['type']=1;
if (!isset($aStatatypelist[$this->headersSGQA[$iVarid]]['format']))
$aStatatypelist[$this->headersSGQA[$iVarid]]['format']=0;
// Does the variable need a higher datatype because of the current response?
if ($aStatatypelist[$this->headersSGQA[$iVarid]]['type'] < $iDatatype)
$aStatatypelist[$this->headersSGQA[$iVarid]]['type'] = $iDatatype;
// if datatype is a string, set needed stringlength
if ($iDatatype==7)
{
// Does the variable need a higher stringlength because of the current response?
if ($aStatatypelist[$this->headersSGQA[$iVarid]]['format'] < $iStringlength)
$aStatatypelist[$this->headersSGQA[$iVarid]]['format'] = $iStringlength;
}
//write the recoded response back to the response array
$this->customResponsemap[$iRespId][$iVarid]=$response;
} }
} }
// create an array $typelist from $aDatatypes with content: variable=> data type and data format
foreach ($aDatatypes as $variable => $responses) // translate coding into STATA datatypes, format and length
foreach ($aStatatypelist as $variable => $data)
{ {
if (in_array('string', $responses, true)) switch ($data['type'])
{ {
$max = max($strlenarray[$variable]); // get maximum string length per string variable case 7:
// cap str[length] at $maxStringLength $this->customFieldmap['questions'][$variable]['statatype'] = 'str'. min($data['format'], $this->maxStringLength);
$typelist[$variable]['type'] = 'str' . $max = $max > $this->maxStringLength ? $this->maxStringLength : $max; $this->customFieldmap['questions'][$variable]['stataformat'] = '%' . min($data['format'], $this->maxStringLength) . 's';
$typelist[$variable]['format'] = '%' . $max = $max > $this->maxStringLength ? $this->maxStringLength : $max . 's'; break;
case 6:
$this->customFieldmap['questions'][$variable]['statatype'] = 'double';
$this->customFieldmap['questions'][$variable]['stataformat'] = '%tc';
break;
case 5:
$this->customFieldmap['questions'][$variable]['statatype'] = 'float';
$this->customFieldmap['questions'][$variable]['stataformat'] = '%10.0g';
break;
case 4:
$this->customFieldmap['questions'][$variable]['statatype'] = 'long';
$this->customFieldmap['questions'][$variable]['stataformat'] = '%10.0g';
break;
case 3:
$this->customFieldmap['questions'][$variable]['statatype'] = 'int';
$this->customFieldmap['questions'][$variable]['stataformat'] = '%10.0g';
break;
case 2:
$this->customFieldmap['questions'][$variable]['statatype'] = 'byte';
$this->customFieldmap['questions'][$variable]['stataformat'] = '%10.0g';
break;
case 1:
$this->customFieldmap['questions'][$variable]['statatype'] = 'byte';
$this->customFieldmap['questions'][$variable]['stataformat'] = '%9.0g';
break;
} }
elseif (in_array('double', $responses, true)) // only used for dates/times (milliseconds passed since 1960)
{
$typelist[$variable]['type'] = 'double';
$typelist[$variable]['format'] = '%tc';
}
elseif (in_array('float', $responses, true))
{
$typelist[$variable]['type'] = 'float';
$typelist[$variable]['format'] = '%10.0g';
}
elseif (in_array('long', $responses, true))
{
$typelist[$variable]['type'] = 'long';
$typelist[$variable]['format'] = '%10.0g';
}
elseif (in_array('int', $responses, true))
{
$typelist[$variable]['type'] = 'int';
$typelist[$variable]['format'] = '%10.0g';
}
elseif (in_array('byte', $responses, true))
{
$typelist[$variable]['type'] = 'byte';
$typelist[$variable]['format'] = '%10.0g';
}
elseif (in_array('emptystr', $responses, true))
{
$typelist[$variable]['type'] = 'byte'; //variables that only contain '' as responses will be a byte...
$typelist[$variable]['format'] = '%9.0g';
}
$this->customFieldmap['questions'][$variable]['statatype'] = $typelist[$variable]['type'];
$this->customFieldmap['questions'][$variable]['stataformat'] = $typelist[$variable]['format'];
} }
} }

View file

@ -233,10 +233,10 @@
{ {
$out .= CHtml::label($metaData['label'], $id, $metaData['labelOptions']); $out .= CHtml::label($metaData['label'], $id, $metaData['labelOptions']);
} }
$out .= CHtml::textField($id, $value, array( $out .= CHtml::numberField($id, $value, array(
'id' => $id, 'id' => $id,
'form' => $form, 'form' => $form,
'pattern' => '\d+(\.\d+)?' 'data-type'=>'float',
)); ));
return $out; return $out;
@ -267,6 +267,17 @@
return $out; return $out;
} }
public function renderInfo($name, array $metaData, $form = null)
{
$out = '';
$id = $name;
$value = isset($metaData['content']) ? $metaData['content'] : '';
if (is_array($value)) { throw new CException('wrong type' . $name); }
$out .= $value;
return $out;
}
public function renderInt($name, array $metaData, $form = null) public function renderInt($name, array $metaData, $form = null)
{ {
$out = ''; $out = '';
@ -277,11 +288,12 @@
{ {
$out .= CHtml::label($metaData['label'], $id, $metaData['labelOptions']); $out .= CHtml::label($metaData['label'], $id, $metaData['labelOptions']);
} }
$out .= CHtml::textField($id, $value, array( $step=isset($metaData['step'])?$metaData['step']:1;
$out .= CHtml::numberField($id, $value, array(
'id' => $id, 'id' => $id,
'form' => $form, 'form' => $form,
'data-type' => 'int', 'data-type' => 'int',
'pattern' => '\d+' 'step' => 1,
)); ));
return $out; return $out;
@ -313,6 +325,21 @@
{ {
return CHtml::image($metaData['path']); return CHtml::image($metaData['path']);
} }
public function renderRadio($name, array $metaData, $form = null)
{
$out = '';
$id = $name;
$value = isset($metaData['current']) ? $metaData['current'] : (isset($metaData['default']) ? $metaData['default'] : null);
if (isset($metaData['label']))
{
$out .= CHtml::label($metaData['label'], $id);
}
$out .= CHtml::radioButtonList($name, $value, $metaData['options']);
return $out;
}
public function renderRelevance($name, array $metaData, $form = null) public function renderRelevance($name, array $metaData, $form = null)
{ {
$out = ''; $out = '';
@ -405,6 +432,24 @@
return $out; return $out;
} }
public function renderLink($name, array $metaData, $form = null)
{
$out = '';
$id = $name;
if (isset($metaData['label']))
{
$out .= CHtml::label($metaData['label'], $id);
}
$metaData['class'][] = 'btn';
$out .= CHtml::link($metaData['label'], $metaData['link'], array(
'id' => $id,
'style' => $metaData['style'],
'class' => implode(' ', $metaData['class'])
));
return $out;
}
public function renderList($name, array $metaData, $form = null) public function renderList($name, array $metaData, $form = null)
{ {
$id = $name; $id = $name;

View file

@ -8,8 +8,7 @@ div.row {
} }
.settingswidget input[type^='button'], .settingswidget label{ .settingswidget input[type^='button'], .settingswidget label{
height: 30px; line-height: normal;
line-height: 30px;
margin-top: 0px; margin-top: 0px;
} }
@ -69,6 +68,7 @@ div.row {
padding-right: 10px; padding-right: 10px;
width: 40%; width: 40%;
display: inline-block; display: inline-block;
vertical-align: top;
} }
.settingswidget .setting > label:after{ .settingswidget .setting > label:after{
content: ':'; content: ':';

View file

@ -15,154 +15,154 @@
class SurveyRuntimeHelper { class SurveyRuntimeHelper {
protected function createFullQuestionIndex($LEMsessid, $surveyMode) protected function createFullQuestionIndex($LEMsessid, $surveyMode)
{ {
if ($surveyMode == 'group') if ($surveyMode == 'group')
{ {
$this->createFullQuestionIndexByGroup($LEMsessid); $this->createFullQuestionIndexByGroup($LEMsessid);
} }
else else
{ {
$this->createFullQuestionIndexByQuestion($LEMsessid); $this->createFullQuestionIndexByQuestion($LEMsessid);
} }
} }
protected function createFullQuestionIndexByGroup($LEMsessid) protected function createFullQuestionIndexByGroup($LEMsessid)
{ {
echo "\n\n<!-- PRESENT THE INDEX -->\n"; echo "\n\n<!-- PRESENT THE INDEX -->\n";
echo CHtml::openTag('div', array('id' => 'index')); echo CHtml::openTag('div', array('id' => 'index'));
echo CHtml::openTag('div', array('class' => 'container')); echo CHtml::openTag('div', array('class' => 'container'));
echo CHtml::tag('h2', array(), gT("Question index")); echo CHtml::tag('h2', array(), gT("Question index"));
echo CHtml::openTag('ol'); echo CHtml::openTag('ol');
foreach ($_SESSION[$LEMsessid]['grouplist'] as $key => $group) foreach ($_SESSION[$LEMsessid]['grouplist'] as $key => $group)
{ {
// echo '<script>'; // echo '<script>';
// echo 'var session = '. json_encode(LimeExpressionManager::singleton()->_ValidateGroup($key)) . ';'; // echo 'var session = '. json_encode(LimeExpressionManager::singleton()->_ValidateGroup($key)) . ';';
// echo 'console.log(session);'; // echo 'console.log(session);';
// echo '</script>'; // echo '</script>';
// Better to use tracevar / // Better to use tracevar /
if (LimeExpressionManager::GroupIsRelevant($group['gid'])) if (LimeExpressionManager::GroupIsRelevant($group['gid']))
{ {
$group['step'] = $key + 1; $group['step'] = $key + 1;
$stepInfo = LimeExpressionManager::singleton()->_ValidateGroup($key); $stepInfo = LimeExpressionManager::singleton()->_ValidateGroup($key);
$classes = implode(' ', array( $classes = implode(' ', array(
'row', 'row',
$stepInfo['anyUnanswered'] ? 'missing' : '', $stepInfo['anyUnanswered'] ? 'missing' : '',
$_SESSION[$LEMsessid]['step'] == $group['step'] ? 'current' : '' $_SESSION[$LEMsessid]['step'] == $group['step'] ? 'current' : ''
)); ));
$sButtonSubmit=CHtml::htmlButton(gT('Go to this group'),array('type'=>'submit','value'=>$group['step'],'name'=>'move','class'=>'jshide')); $sButtonSubmit=CHtml::htmlButton(gT('Go to this group'),array('type'=>'submit','value'=>$group['step'],'name'=>'move','class'=>'jshide'));
echo CHtml::tag('li', array( echo CHtml::tag('li', array(
'data-gid' => $group['gid'], 'data-gid' => $group['gid'],
'title' => $group['description'], 'title' => $group['description'],
'class' => $classes, 'class' => $classes,
), $group['group_name'].$sButtonSubmit); ), $group['group_name'].$sButtonSubmit);
} }
} }
echo CHtml::closeTag('ol'); echo CHtml::closeTag('ol');
echo CHtml::closeTag('div'); echo CHtml::closeTag('div');
echo CHtml::closeTag('div'); echo CHtml::closeTag('div');
App()->getClientScript()->registerScript('manageIndex',"manageIndex()\n",CClientScript::POS_END); App()->getClientScript()->registerScript('manageIndex',"manageIndex()\n",CClientScript::POS_END);
} }
protected function createFullQuestionIndexByQuestion($LEMsessid) protected function createFullQuestionIndexByQuestion($LEMsessid)
{ {
echo CHtml::openTag('div', array('id' => 'index')); echo CHtml::openTag('div', array('id' => 'index'));
echo CHtml::openTag('div', array('class' => 'container')); echo CHtml::openTag('div', array('class' => 'container'));
echo CHtml::tag('h2', array(), gT("Question index")); echo CHtml::tag('h2', array(), gT("Question index"));
echo 'Question by question not yet supported, use incremental index.'; echo 'Question by question not yet supported, use incremental index.';
echo CHtml::closeTag('div'); echo CHtml::closeTag('div');
echo CHtml::closeTag('div'); echo CHtml::closeTag('div');
App()->getClientScript()->registerScript('manageIndex',"manageIndex()\n",CClientScript::POS_END); App()->getClientScript()->registerScript('manageIndex',"manageIndex()\n",CClientScript::POS_END);
} }
protected function createIncrementalQuestionIndex($LEMsessid, $surveyMode) protected function createIncrementalQuestionIndex($LEMsessid, $surveyMode)
{ {
echo "\n\n<!-- PRESENT THE INDEX -->\n"; echo "\n\n<!-- PRESENT THE INDEX -->\n";
echo '<div id="index"><div class="container"><h2>' . gT("Question index") . '</h2>'; echo '<div id="index"><div class="container"><h2>' . gT("Question index") . '</h2>';
$stepIndex = LimeExpressionManager::GetStepIndexInfo(); $stepIndex = LimeExpressionManager::GetStepIndexInfo();
$lastGseq=-1; $lastGseq=-1;
$gseq = -1; $gseq = -1;
$grel = true; $grel = true;
for($v = 0, $n = 0; $n != $_SESSION[$LEMsessid]['maxstep']; ++$n) for($v = 0, $n = 0; $n != $_SESSION[$LEMsessid]['maxstep']; ++$n)
{ {
if (!isset($stepIndex[$n])) { if (!isset($stepIndex[$n])) {
continue; // this is an invalid group - skip it continue; // this is an invalid group - skip it
} }
$stepInfo = $stepIndex[$n]; $stepInfo = $stepIndex[$n];
if ($surveyMode == 'question') if ($surveyMode == 'question')
{ {
if ($lastGseq != $stepInfo['gseq']) { if ($lastGseq != $stepInfo['gseq']) {
// show the group label // show the group label
++$gseq; ++$gseq;
$g = $_SESSION[$LEMsessid]['grouplist'][$gseq]; $g = $_SESSION[$LEMsessid]['grouplist'][$gseq];
$grel = !LimeExpressionManager::GroupIsIrrelevantOrHidden($gseq); $grel = !LimeExpressionManager::GroupIsIrrelevantOrHidden($gseq);
if ($grel) if ($grel)
{ {
$gtitle = LimeExpressionManager::ProcessString($g['group_name']); $gtitle = LimeExpressionManager::ProcessString($g['group_name']);
echo '<h3>' . flattenText($gtitle) . "</h3>"; echo '<h3>' . flattenText($gtitle) . "</h3>";
} }
$lastGseq = $stepInfo['gseq']; $lastGseq = $stepInfo['gseq'];
} }
if (!$grel || !$stepInfo['show']) if (!$grel || !$stepInfo['show'])
{ {
continue; continue;
} }
$q = $_SESSION[$LEMsessid]['fieldarray'][$n]; $q = $_SESSION[$LEMsessid]['fieldarray'][$n];
} }
else else
{ {
++$gseq; ++$gseq;
if (!$stepInfo['show']) if (!$stepInfo['show'])
{ {
continue; continue;
} }
$g = $_SESSION[$LEMsessid]['grouplist'][$gseq]; $g = $_SESSION[$LEMsessid]['grouplist'][$gseq];
} }
if ($surveyMode == 'group') if ($surveyMode == 'group')
{ {
$indexlabel = LimeExpressionManager::ProcessString($g['group_name']); $indexlabel = LimeExpressionManager::ProcessString($g['group_name']);
$sButtonText=gT('Go to this group'); $sButtonText=gT('Go to this group');
} }
else else
{ {
$indexlabel = LimeExpressionManager::ProcessString($q[3]); $indexlabel = LimeExpressionManager::ProcessString($q[3]);
$sButtonText=gT('Go to this question'); $sButtonText=gT('Go to this question');
} }
$sText = (($surveyMode == 'group') ? flattenText($indexlabel) : flattenText($indexlabel)); $sText = (($surveyMode == 'group') ? flattenText($indexlabel) : flattenText($indexlabel));
$bGAnsw = !$stepInfo['anyUnanswered']; $bGAnsw = !$stepInfo['anyUnanswered'];
++$v; ++$v;
$class = ($n == $_SESSION[$LEMsessid]['step'] - 1 ? 'current' : ($bGAnsw ? 'answer' : 'missing')); $class = ($n == $_SESSION[$LEMsessid]['step'] - 1 ? 'current' : ($bGAnsw ? 'answer' : 'missing'));
if ($v % 2) if ($v % 2)
$class .= " odd"; $class .= " odd";
$s = $n + 1; $s = $n + 1;
echo "<div class=\"row $class\">"; echo "<div class=\"row $class\">";
echo "<span class=\"hdr\">$v</span>"; echo "<span class=\"hdr\">$v</span>";
echo "<span title=\"$sText\">$sText</span>"; echo "<span title=\"$sText\">$sText</span>";
echo CHtml::htmlButton($sButtonText,array('type'=>'submit','value'=>$s,'name'=>'move','class'=>'jshide')); echo CHtml::htmlButton($sButtonText,array('type'=>'submit','value'=>$s,'name'=>'move','class'=>'jshide'));
echo "</div>"; echo "</div>";
} }
if ($_SESSION[$LEMsessid]['maxstep'] == $_SESSION[$LEMsessid]['totalsteps']) if ($_SESSION[$LEMsessid]['maxstep'] == $_SESSION[$LEMsessid]['totalsteps'])
{ {
echo CHtml::htmlButton(gT('Submit'),array('type'=>'submit','value'=>'movesubmit','name'=>'move','class'=>'submit button')); echo CHtml::htmlButton(gT('Submit'),array('type'=>'submit','value'=>'movesubmit','name'=>'move','class'=>'submit button'));
} }
echo '</div></div>'; echo '</div></div>';
App()->getClientScript()->registerScript('manageIndex',"manageIndex()\n",CClientScript::POS_END); App()->getClientScript()->registerScript('manageIndex',"manageIndex()\n",CClientScript::POS_END);
} }
/** /**
* Main function * Main function
* *
@ -172,25 +172,18 @@ class SurveyRuntimeHelper {
function run($surveyid,$args) { function run($surveyid,$args) {
global $errormsg; global $errormsg;
extract($args); extract($args);
if (!$thissurvey) { if (!$thissurvey) {
$thissurvey = getSurveyInfo($surveyid); $thissurvey = getSurveyInfo($surveyid);
} }
$LEMsessid = 'survey_' . $surveyid; $LEMsessid = 'survey_' . $surveyid;
if (isset($_SESSION[$LEMsessid]['s_lang'])) $this->setJavascriptVar($surveyid, isset($clang->langcode) ? $clang->langcode : $thissurvey['language']);
{
$this->setJavascriptVar($surveyid, $_SESSION[$LEMsessid]['s_lang']);
}
else
{
$this->setJavascriptVar($surveyid, $thissurvey['language']);
}
$sTemplatePath=getTemplatePath(Yii::app()->getConfig("defaulttemplate")).DIRECTORY_SEPARATOR; $sTemplatePath=getTemplatePath(Yii::app()->getConfig("defaulttemplate")).DIRECTORY_SEPARATOR;
if (isset ($_SESSION['survey_'.$surveyid]['templatepath'])) if (isset ($_SESSION['survey_'.$surveyid]['templatepath']))
{ {
$sTemplatePath=$_SESSION['survey_'.$surveyid]['templatepath']; $sTemplatePath=$_SESSION['survey_'.$surveyid]['templatepath'];
} }
// $LEMdebugLevel - customizable debugging for Lime Expression Manager // $LEMdebugLevel - customizable debugging for Lime Expression Manager
$LEMdebugLevel = 0; // LEM_DEBUG_TIMING; // (LEM_DEBUG_TIMING + LEM_DEBUG_VALIDATION_SUMMARY + LEM_DEBUG_VALIDATION_DETAIL); $LEMdebugLevel = 0; // LEM_DEBUG_TIMING; // (LEM_DEBUG_TIMING + LEM_DEBUG_VALIDATION_SUMMARY + LEM_DEBUG_VALIDATION_DETAIL);
$LEMskipReprocessing=false; // true if used GetLastMoveResult to avoid generation of unneeded extra JavaScript $LEMskipReprocessing=false; // true if used GetLastMoveResult to avoid generation of unneeded extra JavaScript
switch ($thissurvey['format']) switch ($thissurvey['format'])
@ -208,25 +201,24 @@ class SurveyRuntimeHelper {
} }
$radix=getRadixPointData($thissurvey['surveyls_numberformat']); $radix=getRadixPointData($thissurvey['surveyls_numberformat']);
$radix = $radix['separator']; $radix = $radix['separator'];
$surveyOptions = array( $surveyOptions = array(
'active' => ($thissurvey['active'] == 'Y'), 'active' => ($thissurvey['active'] == 'Y'),
'allowsave' => ($thissurvey['allowsave'] == 'Y'), 'allowsave' => ($thissurvey['allowsave'] == 'Y'),
'anonymized' => ($thissurvey['anonymized'] != 'N'), 'anonymized' => ($thissurvey['anonymized'] != 'N'),
'assessments' => ($thissurvey['assessments'] == 'Y'), 'assessments' => ($thissurvey['assessments'] == 'Y'),
'datestamp' => ($thissurvey['datestamp'] == 'Y'), 'datestamp' => ($thissurvey['datestamp'] == 'Y'),
'deletenonvalues'=>Yii::app()->getConfig('deletenonvalues'), 'deletenonvalues'=>Yii::app()->getConfig('deletenonvalues'),
'hyperlinkSyntaxHighlighting' => (($LEMdebugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY), // TODO set this to true if in admin mode but not if running a survey 'hyperlinkSyntaxHighlighting' => (($LEMdebugLevel & LEM_DEBUG_VALIDATION_SUMMARY) == LEM_DEBUG_VALIDATION_SUMMARY), // TODO set this to true if in admin mode but not if running a survey
'ipaddr' => ($thissurvey['ipaddr'] == 'Y'), 'ipaddr' => ($thissurvey['ipaddr'] == 'Y'),
'radix'=>$radix, 'radix'=>$radix,
'refurl' => (($thissurvey['refurl'] == "Y" && isset($_SESSION[$LEMsessid]['refurl'])) ? $_SESSION[$LEMsessid]['refurl'] : NULL), 'refurl' => (($thissurvey['refurl'] == "Y" && isset($_SESSION[$LEMsessid]['refurl'])) ? $_SESSION[$LEMsessid]['refurl'] : NULL),
'savetimings' => ($thissurvey['savetimings'] == "Y"), 'savetimings' => ($thissurvey['savetimings'] == "Y"),
'surveyls_dateformat' => (isset($thissurvey['surveyls_dateformat']) ? $thissurvey['surveyls_dateformat'] : 1), 'surveyls_dateformat' => (isset($thissurvey['surveyls_dateformat']) ? $thissurvey['surveyls_dateformat'] : 1),
'startlanguage'=>(isset($clang->langcode) ? $clang->langcode : $thissurvey['language']), 'startlanguage'=>(isset($clang->langcode) ? $clang->langcode : $thissurvey['language']),
'target' => Yii::app()->getConfig('uploaddir').DIRECTORY_SEPARATOR.'surveys'.DIRECTORY_SEPARATOR.$thissurvey['sid'].DIRECTORY_SEPARATOR.'files'.DIRECTORY_SEPARATOR, 'target' => Yii::app()->getConfig('uploaddir').DIRECTORY_SEPARATOR.'surveys'.DIRECTORY_SEPARATOR.$thissurvey['sid'].DIRECTORY_SEPARATOR.'files'.DIRECTORY_SEPARATOR,
'tempdir' => Yii::app()->getConfig('tempdir').DIRECTORY_SEPARATOR, 'tempdir' => Yii::app()->getConfig('tempdir').DIRECTORY_SEPARATOR,
'timeadjust' => (isset($timeadjust) ? $timeadjust : 0), 'timeadjust' => (isset($timeadjust) ? $timeadjust : 0),
'token' => (isset($clienttoken) ? $clienttoken : NULL), 'token' => (isset($clienttoken) ? $clienttoken : NULL),
); );
//Security Checked: POST, GET, SESSION, REQUEST, returnGlobal, DB //Security Checked: POST, GET, SESSION, REQUEST, returnGlobal, DB
@ -264,11 +256,11 @@ class SurveyRuntimeHelper {
$_SESSION[$LEMsessid]['step'] = 0; $_SESSION[$LEMsessid]['step'] = 0;
if ($surveyMode == 'survey') if ($surveyMode == 'survey')
{ {
$move = "movenext"; // to force a call to NavigateForwards() LimeExpressionManager::JumpTo(1, false, false, true);
} }
elseif (isset($thissurvey['showwelcome']) && $thissurvey['showwelcome'] == 'N') elseif (isset($thissurvey['showwelcome']) && $thissurvey['showwelcome'] == 'N')
{ {
$move = "movenext"; $moveResult=LimeExpressionManager::JumpTo(1, false, false, true);
$_SESSION[$LEMsessid]['step']=1; $_SESSION[$LEMsessid]['step']=1;
} }
} }
@ -334,16 +326,16 @@ class SurveyRuntimeHelper {
unset($_SESSION[$LEMsessid]['LEMtokenResume']); unset($_SESSION[$LEMsessid]['LEMtokenResume']);
} }
else if (!$LEMskipReprocessing) else if (!$LEMskipReprocessing)
{
//Move current step ###########################################################################
if (isset($move) && $move == 'moveprev' && ($thissurvey['allowprev'] == 'Y' || $thissurvey['questionindex'] > 0))
{ {
//Move current step ########################################################################### $moveResult = LimeExpressionManager::NavigateBackwards();
if (isset($move) && $move == 'moveprev' && ($thissurvey['allowprev'] == 'Y' || $thissurvey['questionindex'] > 0)) if ($moveResult['at_start'])
{ {
$moveResult = LimeExpressionManager::NavigateBackwards(); $_SESSION[$LEMsessid]['step'] = 0;
if ($moveResult['at_start']) unset($moveResult); // so display welcome page again
{ }
$_SESSION[$LEMsessid]['step'] = 0;
unset($moveResult); // so display welcome page again
}
} }
if (isset($move) && $move == "movenext") if (isset($move) && $move == "movenext")
{ {
@ -362,24 +354,24 @@ class SurveyRuntimeHelper {
$moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['totalsteps'] + 1, false); $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['totalsteps'] + 1, false);
} }
} }
if (isset($move) && (preg_match('/^changelang_/', $move) || $move=='changelang')) if (isset($move) && $move=='changelang')
{ {
// jump to current step using new language, processing POST values // jump to current step using new language, processing POST values
$moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, true, false, true); // do process the POST data $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, true, true, true); // do process the POST data
} }
if (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 1) if (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 1)
{ {
$move = (int) $move; $move = (int) $move;
if ($move > 0 && (($move <= $_SESSION[$LEMsessid]['step']) || (isset($_SESSION[$LEMsessid]['maxstep']) && $move <= $_SESSION[$LEMsessid]['maxstep']))) if ($move > 0 && (($move <= $_SESSION[$LEMsessid]['step']) || (isset($_SESSION[$LEMsessid]['maxstep']) && $move <= $_SESSION[$LEMsessid]['maxstep'])))
{ {
$moveResult = LimeExpressionManager::JumpTo($move, false); $moveResult = LimeExpressionManager::JumpTo($move, false);
} }
} }
elseif (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 2) elseif (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 2)
{ {
$move = (int) $move; $move = (int) $move;
$moveResult = LimeExpressionManager::JumpTo($move, false, true, true); $moveResult = LimeExpressionManager::JumpTo($move, false, true, true);
} }
if (!isset($moveResult) && !($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] == 0)) if (!isset($moveResult) && !($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] == 0))
{ {
// Just in case not set via any other means, but don't do this if it is the welcome page // Just in case not set via any other means, but don't do this if it is the welcome page
@ -387,9 +379,17 @@ class SurveyRuntimeHelper {
$LEMskipReprocessing=true; $LEMskipReprocessing=true;
} }
} }
if (isset($moveResult) && isset($moveResult['seq']) )// Reload at first page (welcome after click previous fill an empty $moveResult array if (isset($moveResult) && isset($moveResult['seq']) )// Reload at first page (welcome after click previous fill an empty $moveResult array
{ {
// With complete index, we need to revalidate whole group bug #08806. It's actually the only mode where we JumpTo with force
if($moveResult['finished'] == true && $thissurvey['questionindex']==2)// $thissurvey['questionindex']>=2
{
//LimeExpressionManager::JumpTo(-1, false, false, true);
LimeExpressionManager::StartSurvey($surveyid, $surveyMode, $surveyOptions);
$moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['totalsteps']+1, false, false, false);// no preview, no save data and NO force
if(!$moveResult['mandViolation'] && $moveResult['valid'] && empty($moveResult['invalidSQs']))
$moveResult['finished'] = true;
}
if ($moveResult['finished'] == true) if ($moveResult['finished'] == true)
{ {
$move = 'movesubmit'; $move = 'movesubmit';
@ -418,31 +418,12 @@ class SurveyRuntimeHelper {
Yii::app()->end(); // So we can still see debug messages Yii::app()->end(); // So we can still see debug messages
} }
//CHECK IF ALL MANDATORY QUESTIONS HAVE BEEN ANSWERED ############################################
//First, see if we are moving backwards or doing a Save so far, and its OK not to check:
if (
(isset($move) && ($move == "moveprev" || (is_int($move) && $_SESSION[$LEMsessid]['prevstep'] == $_SESSION[$LEMsessid]['maxstep']) || $_SESSION[$LEMsessid]['prevstep'] == $_SESSION[$LEMsessid]['step'])) ||
(isset($_POST['saveall']) && $_POST['saveall'] == $clang->gT("Save your responses so far")))
{
if (Yii::app()->getConfig('allowmandbackwards') == 1)
{
$backok = "Y";
}
else
{
$backok = "N";
}
}
else
{
$backok = "N"; // NA, since not moving backwards
}
// TODO FIXME // TODO FIXME
if ($thissurvey['active'] == "Y") { if ($thissurvey['active'] == "Y") {
Yii::import("application.libraries.Save"); Yii::import("application.libraries.Save");
$cSave = new Save(); $cSave = new Save();
} }
if ($thissurvey['active'] == "Y" && Yii::app()->request->getPost('saveall')) // Don't test if save is allowed if ($thissurvey['active'] == "Y" && Yii::app()->request->getPost('saveall')) // Don't test if save is allowed
{ {
$bTokenAnswerPersitance = $thissurvey['tokenanswerspersistence'] == 'Y' && isset($surveyid) && tableExists('tokens_'.$surveyid); $bTokenAnswerPersitance = $thissurvey['tokenanswerspersistence'] == 'Y' && isset($surveyid) && tableExists('tokens_'.$surveyid);
// must do this here to process the POSTed values // must do this here to process the POSTed values
@ -487,7 +468,7 @@ class SurveyRuntimeHelper {
if (isset($moveResult) && !$moveResult['finished']) if (isset($moveResult) && !$moveResult['finished'])
{ {
$unansweredSQList = $moveResult['unansweredSQs']; $unansweredSQList = $moveResult['unansweredSQs'];
if (strlen($unansweredSQList) > 0 && $backok != "N") if (strlen($unansweredSQList) > 0)
{ {
$notanswered = explode('|', $unansweredSQList); $notanswered = explode('|', $unansweredSQList);
} }
@ -498,7 +479,7 @@ class SurveyRuntimeHelper {
//CHECK INPUT //CHECK INPUT
$invalidSQList = $moveResult['invalidSQs']; $invalidSQList = $moveResult['invalidSQs'];
if (strlen($invalidSQList) > 0 && $backok != "N") if (strlen($invalidSQList) > 0)
{ {
$notvalidated = explode('|', $invalidSQList); $notvalidated = explode('|', $invalidSQList);
} }
@ -510,7 +491,7 @@ class SurveyRuntimeHelper {
// CHECK UPLOADED FILES // CHECK UPLOADED FILES
// TMSW - Move this into LEM::NavigateForwards? // TMSW - Move this into LEM::NavigateForwards?
$filenotvalidated = checkUploadedFileValidity($surveyid, $move, $backok); $filenotvalidated = checkUploadedFileValidity($surveyid, $move);
//SEE IF THIS GROUP SHOULD DISPLAY //SEE IF THIS GROUP SHOULD DISPLAY
$show_empty_group = false; $show_empty_group = false;
@ -625,7 +606,7 @@ class SurveyRuntimeHelper {
} }
if (trim(strip_tags($thissurvey['surveyls_endtext'])) == '') if (trim(str_replace(array('<p>','</p>'),'',$thissurvey['surveyls_endtext'])) == '')
{ {
$completed = "<br /><span class='success'>" . $clang->gT("Thank you!") . "</span><br /><br />\n\n" $completed = "<br /><span class='success'>" . $clang->gT("Thank you!") . "</span><br /><br />\n\n"
. $clang->gT("Your survey responses have been recorded.") . "<br /><br />\n"; . $clang->gT("Your survey responses have been recorded.") . "<br /><br />\n";
@ -772,21 +753,21 @@ class SurveyRuntimeHelper {
$groupdescription = $clang->gT("There are no more questions. Please press the <Submit> button to finish this survey."); $groupdescription = $clang->gT("There are no more questions. Please press the <Submit> button to finish this survey.");
} }
else if ($surveyMode != 'survey') else if ($surveyMode != 'survey')
{ {
if ($previewquestion) { if ($previewquestion) {
$_qid = sanitize_int($param['qid']); $_qid = sanitize_int($param['qid']);
LimeExpressionManager::StartSurvey($surveyid, 'question', $surveyOptions, false, $LEMdebugLevel); LimeExpressionManager::StartSurvey($surveyid, 'question', $surveyOptions, false, $LEMdebugLevel);
$qSec = LimeExpressionManager::GetQuestionSeq($_qid); $qSec = LimeExpressionManager::GetQuestionSeq($_qid);
$moveResult = LimeExpressionManager::JumpTo($qSec+1,true,false,true); $moveResult = LimeExpressionManager::JumpTo($qSec+1,true,false,true);
$stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']); $stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']);
} else { } else {
$stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']); $stepInfo = LimeExpressionManager::GetStepIndexInfo($moveResult['seq']);
}
$gid = $stepInfo['gid'];
$groupname = $stepInfo['gname'];
$groupdescription = $stepInfo['gtext'];
} }
$gid = $stepInfo['gid'];
$groupname = $stepInfo['gname'];
$groupdescription = $stepInfo['gtext'];
}
} }
if ($previewquestion) if ($previewquestion)
{ {
@ -942,7 +923,7 @@ class SurveyRuntimeHelper {
} }
Yii::app()->clientScript->registerScript("showpopup","showpopup=".(int)Yii::app()->getConfig('showpopups').";",CClientScript::POS_HEAD); Yii::app()->clientScript->registerScript("showpopup","showpopup=".(int)Yii::app()->getConfig('showpopups').";",CClientScript::POS_HEAD);
//if(count($aPopup)) //if(count($aPopup))
Yii::app()->clientScript->registerScript('startPopup',"startPopups=".json_encode($aPopup).";",CClientScript::POS_HEAD); Yii::app()->clientScript->registerScript('startPopup',"startPopups=".json_encode($aPopup).";",CClientScript::POS_HEAD);
//ALTER PAGE CLASS TO PROVIDE WHOLE-PAGE ALTERNATION //ALTER PAGE CLASS TO PROVIDE WHOLE-PAGE ALTERNATION
if ($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] != $_SESSION[$LEMsessid]['prevstep'] || if ($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] != $_SESSION[$LEMsessid]['prevstep'] ||
(isset($_SESSION[$LEMsessid]['stepno']) && $_SESSION[$LEMsessid]['stepno'] % 2)) (isset($_SESSION[$LEMsessid]['stepno']) && $_SESSION[$LEMsessid]['stepno'] % 2))
@ -1161,12 +1142,12 @@ class SurveyRuntimeHelper {
if ($surveyMode != 'survey' && $thissurvey['questionindex'] == 1) if ($surveyMode != 'survey' && $thissurvey['questionindex'] == 1)
{ {
$this->createIncrementalQuestionIndex($LEMsessid, $surveyMode); $this->createIncrementalQuestionIndex($LEMsessid, $surveyMode);
}
elseif ($surveyMode != 'survey' && $thissurvey['questionindex'] == 2)
{
$this->createFullQuestionIndex($LEMsessid, $surveyMode);
} }
elseif ($surveyMode != 'survey' && $thissurvey['questionindex'] == 2)
{
$this->createFullQuestionIndex($LEMsessid, $surveyMode);
}
echo "<input type='hidden' name='thisstep' value='{$_SESSION[$LEMsessid]['step']}' id='thisstep' />\n"; echo "<input type='hidden' name='thisstep' value='{$_SESSION[$LEMsessid]['step']}' id='thisstep' />\n";
echo "<input type='hidden' name='sid' value='$surveyid' id='sid' />\n"; echo "<input type='hidden' name='sid' value='$surveyid' id='sid' />\n";
@ -1198,16 +1179,16 @@ class SurveyRuntimeHelper {
} }
/** /**
* setJavascriptVar * setJavascriptVar
* *
* *
* @return @void * @return @void
* @param integer $iSurveyId : the survey id for the script * @param integer $iSurveyId : the survey id for the script
* @param string $sLanguage : the actual language for the survey * @param string $sLanguage : the actual language for the survey
*/ */
public function setJavascriptVar($iSurveyId, $sLanguage) public function setJavascriptVar($iSurveyId, $sLanguage)
{ {
$aSurveyinfo=getSurveyInfo($iSurveyId); $aSurveyinfo=getSurveyInfo($iSurveyId,$sLanguage);
if(isset($aSurveyinfo['surveyls_numberformat'])) if(isset($aSurveyinfo['surveyls_numberformat']))
{ {
$aLSJavascriptVar=array(); $aLSJavascriptVar=array();

View file

@ -18,51 +18,62 @@
* @param int $fixnumbering * @param int $fixnumbering
* @todo can call this function (no $_GET, but getParam) AND do it with Yii * @todo can call this function (no $_GET, but getParam) AND do it with Yii
*/ */
function fixNumbering($fixnumbering, $iSurveyID) function fixNumbering($iQuestionID, $iSurveyID)
{ {
Yii::app()->loadHelper("database"); Yii::app()->loadHelper("database");
LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID); LimeExpressionManager::RevertUpgradeConditionsToRelevance($iSurveyID);
//Fix a question id - requires renumbering a question //Fix a question id - requires renumbering a question
$oldqid = (int) $fixnumbering; $iQuestionID = (int) $iQuestionID;
$lastqid=Question::model()->getMaxId('qid', true); // Always refresh as we insert new qid's $iMaxQID=Question::model()->getMaxId('qid', true); // Always refresh as we insert new qid's
$newqid=$lastqid+1; $iNewQID=$iMaxQID+1;
// Not sure we can do this in MSSQL ? // Not sure we can do this in MSSQL ?
$query = "UPDATE {{questions}} SET qid=$newqid WHERE qid=$oldqid"; $sQuery = "UPDATE {{questions}} SET qid=$iNewQID WHERE qid=$iQuestionID";
$result = db_execute_assosc($query); Yii::app()->db->createCommand($sQuery)->query();
// Update subquestions // Update subquestions
$query = "UPDATE {{questions}} SET parent_qid=$newqid WHERE parent_qid=$oldqid"; $sQuery = "UPDATE {{questions}} SET parent_qid=$iNewQID WHERE parent_qid=$iQuestionID";
$result = db_execute_assosc($query); Yii::app()->db->createCommand($sQuery)->query();
//Update conditions.. firstly conditions FOR this question //Update conditions.. firstly conditions FOR this question
$query = "UPDATE {{conditions}} SET qid=$newqid WHERE qid=$oldqid"; $sQuery = "UPDATE {{conditions}} SET qid=$iNewQID WHERE qid=$iQuestionID";
$result = db_execute_assosc($query); Yii::app()->db->createCommand($sQuery)->query();
//Update default values
$sQuery = "UPDATE {{defaultvalues}} SET qid=$iNewQID WHERE qid=$iQuestionID";
Yii::app()->db->createCommand($sQuery)->query();
$sQuery = "UPDATE {{defaultvalues}} SET sqid=$iNewQID WHERE sqid=$iQuestionID";
Yii::app()->db->createCommand($sQuery)->query();
//Update quotas
$sQuery = "UPDATE {{quota_members}} SET qid=$iNewQID WHERE qid=$iQuestionID";
Yii::app()->db->createCommand($sQuery)->query();
//Update url params
$sQuery = "UPDATE {{survey_url_parameters}} SET targetqid=$iNewQID WHERE targetqid=$iQuestionID";
Yii::app()->db->createCommand($sQuery)->query();
$sQuery = "UPDATE {{survey_url_parameters}} SET targetsqid=$iNewQID WHERE targetsqid=$iQuestionID";
Yii::app()->db->createCommand($sQuery)->query();
//Now conditions based upon this question //Now conditions based upon this question
$query = "SELECT cqid, cfieldname FROM {{conditions}} WHERE cqid=$oldqid"; $sQuery = "SELECT cqid, cfieldname FROM {{conditions}} WHERE cqid=$iQuestionID";
$result = dbExecuteAssoc($query); $sResult=Yii::app()->db->createCommand($sQuery)->query();
foreach ($result->readAll() as $row) foreach ($sResult->readAll() as $row){
{ $aSwitcher[]=array("cqid"=>$row['cqid'], "cfieldname"=>$row['cfieldname']);
$switcher[]=array("cqid"=>$row['cqid'], "cfieldname"=>$row['cfieldname']);
} }
if (isset($switcher)) if (isset($aSwitcher))
{ {
foreach ($switcher as $switch) foreach ($aSwitcher as $aSwitch)
{ {
$query = "UPDATE {{conditions}} $sQuery = "UPDATE {{conditions}}
SET cqid=$newqid, SET cqid=$iNewQID,
cfieldname='".str_replace("X".$oldqid, "X".$newqid, $switch['cfieldname'])."' cfieldname='".str_replace("X".$iQuestionID, "X".$iNewQID, $aSwitch['cfieldname'])."'
WHERE cqid=$oldqid"; WHERE cqid=$iQuestionID";
$result = db_execute_assosc($query); $sResult = db_execute_assosc($sQuery);
} }
} }
// TMSW Condition->Relevance: (1) Call LEM->ConvertConditionsToRelevance()when done. (2) Should relevance for old conditions be removed first?
//Now question_attributes //Now question_attributes
$query = "UPDATE {{question_attributes}} SET qid=$newqid WHERE qid=$oldqid"; $sQuery = "UPDATE {{question_attributes}} SET qid=$iNewQID WHERE qid=$iQuestionID";
$result = db_execute_assosc($query); Yii::app()->db->createCommand($sQuery)->query();
//Now answers //Now answers
$query = "UPDATE {{answers}} SET qid=$newqid WHERE qid=$oldqid"; $sQuery = "UPDATE {{answers}} SET qid=$iNewQID WHERE qid=$iQuestionID";
$result = db_execute_assosc($query); Yii::app()->db->createCommand($sQuery)->query();
LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID); LimeExpressionManager::UpgradeConditionsToRelevance($iSurveyID);
} }
@ -102,11 +113,11 @@ function checkQuestions($postsid, $iSurveyID, $qtypes)
//CHECK TO MAKE SURE ALL QUESTION TYPES THAT REQUIRE ANSWERS HAVE ACTUALLY GOT ANSWERS //CHECK TO MAKE SURE ALL QUESTION TYPES THAT REQUIRE ANSWERS HAVE ACTUALLY GOT ANSWERS
//THESE QUESTION TYPES ARE: //THESE QUESTION TYPES ARE:
// # "L" -> LIST // # "L" -> LIST
// # "O" -> LIST WITH COMMENT // # "O" -> LIST WITH COMMENT
// # "M" -> Multiple choice // # "M" -> Multiple choice
// # "P" -> Multiple choice with comments // # "P" -> Multiple choice with comments
// # "A", "B", "C", "E", "F", "H", "^" -> Various Array Types // # "A", "B", "C", "E", "F", "H", "^" -> Various Array Types
// # "R" -> RANKING // # "R" -> RANKING
// # "U" -> FILE CSV MORE // # "U" -> FILE CSV MORE
// # "I" -> LANGUAGE SWITCH // # "I" -> LANGUAGE SWITCH
@ -214,25 +225,13 @@ function checkQuestions($postsid, $iSurveyID, $qtypes)
} }
//CHECK THAT ALL THE CREATED FIELDS WILL BE UNIQUE //CHECK THAT ALL THE CREATED FIELDS WILL BE UNIQUE
$fieldmap = createFieldMap($iSurveyID,'full',false,false,getBaseLanguageFromSurveyID($iSurveyID)); $fieldmap = createFieldMap($iSurveyID,'full',true,false,getBaseLanguageFromSurveyID($iSurveyID),$aDuplicateQIDs);
if (isset($fieldmap)) if (count($aDuplicateQIDs))
{ {
foreach($fieldmap as $fielddata) foreach ($aDuplicateQIDs as $iQID=>$aDuplicate)
{ {
$fieldlist[]=$fielddata['fieldname']; $sFixLink = "[<a href='".Yii::app()->getController()->createUrl("/admin/survey/sa/activate/surveyid/{$iSurveyID}/fixnumbering/{$iQID}")."'>Click here to fix</a>]";
} $failedcheck[]=array($iQID, $aDuplicate['question'], ": Bad duplicate fieldname {$sFixLink}", $aDuplicate['gid']);
$fieldlist=array_reverse($fieldlist); //let's always change the later duplicate, not the earlier one
}
$checkKeysUniqueComparison = create_function('$value','if ($value > 1) return true;');
@$duplicates = array_keys (array_filter (array_count_values($fieldlist), $checkKeysUniqueComparison));
if (isset($duplicates))
{
foreach ($duplicates as $dup)
{
$badquestion=arraySearchByKey($dup, $fieldmap, "fieldname", 1);
$fix = "[<a href='$scriptname?action=activate&amp;sid=$iSurveyID&amp;fixnumbering=".$badquestion['qid']."'>Click Here to Fix</a>]";
$failedcheck[]=array($badquestion['qid'], $badquestion['question'], ": Bad duplicate fieldname $fix", $badquestion['gid']);
} }
} }
if(isset($failedcheck)) if(isset($failedcheck))
@ -289,7 +288,12 @@ function activateSurvey($iSurveyID, $simulate = false)
$createsurvey[$arow['fieldname']] = "decimal (30,10)"; $createsurvey[$arow['fieldname']] = "decimal (30,10)";
break; break;
case "S": //SHORT TEXT case "S": //SHORT TEXT
if (Yii::app()->db->driverName == 'mysql' || Yii::app()->db->driverName == 'mysqli') {$createsurvey[$arow['fieldname']] = "text";} if (Yii::app()->db->driverName == 'mysql' || Yii::app()->db->driverName == 'mysqli') {$createsurvey[$arow['fieldname']] = "text";}
elseif (Yii::app()->db->driverName=='mssql' || Yii::app()->db->driverName=='sqlsrv' || Yii::app()->db->driverName=='dblib')
{
$createsurvey[$arow['fieldname']] = "nvarchar(255)";
}
else {$createsurvey[$arow['fieldname']] = "string";} else {$createsurvey[$arow['fieldname']] = "string";}
break; break;
case "L": //LIST (RADIO) case "L": //LIST (RADIO)
@ -363,14 +367,19 @@ function activateSurvey($iSurveyID, $simulate = false)
} }
$arrSim[] = array($type); $arrSim[] = array($type);
} }
if (Yii::app()->db->driverName=='mssql' || Yii::app()->db->driverName=='sqlsrv' || Yii::app()->db->driverName=='dblib')
{
if ($createsurvey[$arow['fieldname']] == "text")
{
$createsurvey[$arow['fieldname']] = "ntext";
}
}
} }
if ($simulate){ if ($simulate){
return array('dbengine'=>$CI->db->databasetabletype, 'dbtype'=>Yii::app()->db->driverName, 'fields'=>$arrSim); return array('dbengine'=>$CI->db->databasetabletype, 'dbtype'=>Yii::app()->db->driverName, 'fields'=>$arrSim);
} }
// If last question is of type MCABCEFHP^QKJR let's get rid of the ending coma in createsurvey // If last question is of type MCABCEFHP^QKJR let's get rid of the ending coma in createsurvey
//$createsurvey = rtrim($createsurvey, ",\n")."\n"; // Does nothing if not ending with a comma //$createsurvey = rtrim($createsurvey, ",\n")."\n"; // Does nothing if not ending with a comma
@ -389,36 +398,32 @@ function activateSurvey($iSurveyID, $simulate = false)
{ {
if (isset($createsurvey['token'])) Yii::app()->db->createCommand()->createIndex("idx_survey_token_{$iSurveyID}_".rand(1,50000),$tabname,'token'); if (isset($createsurvey['token'])) Yii::app()->db->createCommand()->createIndex("idx_survey_token_{$iSurveyID}_".rand(1,50000),$tabname,'token');
} }
catch (CDbException $e) catch (CDbException $e)
{ {
} }
$anquery = "SELECT autonumber_start FROM {{surveys}} WHERE sid={$iSurveyID}"; $anquery = "SELECT autonumber_start FROM {{surveys}} WHERE sid={$iSurveyID}";
if ($anresult=Yii::app()->db->createCommand($anquery)->query()->readAll()) $iAutoNumberStart=Yii::app()->db->createCommand($anquery)->queryScalar();
//if there is an autonumber_start field, start auto numbering here
if ($iAutoNumberStart!==false && $iAutoNumberStart>0)
{ {
//if there is an autonumber_start field, start auto numbering here if (Yii::app()->db->driverName=='mssql' || Yii::app()->db->driverName=='sqlsrv' || Yii::app()->db->driverName=='dblib') {
foreach($anresult as $row) mssql_drop_primary_index('survey_'.$iSurveyID);
mssql_drop_constraint('id','survey_'.$iSurveyID);
$sQuery = "alter table {{survey_{$iSurveyID}}} drop column id ";
Yii::app()->db->createCommand($sQuery)->execute();
$sQuery = "alter table {{survey_{$iSurveyID}}} add [id] int identity({$iAutoNumberStart},1)";
Yii::app()->db->createCommand($sQuery)->execute();
}
elseif (Yii::app()->db->driverName=='pgsql')
{ {
if ($row['autonumber_start'] > 0) $sQuery = "SELECT setval(pg_get_serial_sequence('{{survey_{$iSurveyID}}}', 'id'),{$iAutoNumberStart},false);";
{ $result = @Yii::app()->db->createCommand($sQuery)->execute();
if (Yii::app()->db->driverName=='mssql' || Yii::app()->db->driverName=='sqlsrv' || Yii::app()->db->driverName=='dblib') { }
mssql_drop_primary_index('survey_'.$iSurveyID); else
mssql_drop_constraint('id','survey_'.$iSurveyID); {
$autonumberquery = "alter table {{survey_{$iSurveyID}}} drop column id "; $sQuery = "ALTER TABLE {{survey_{$iSurveyID}}} AUTO_INCREMENT = {$iAutoNumberStart}";
Yii::app()->db->createCommand($autonumberquery)->execute(); $result = @Yii::app()->db->createCommand($sQuery)->execute();
$autonumberquery = "alter table {{survey_{$iSurveyID}}} add [id] int identity({$row['autonumber_start']},1)";
Yii::app()->db->createCommand($autonumberquery)->execute();
}
elseif (Yii::app()->db->driverName=='pgsql')
{
}
else
{
$autonumberquery = "ALTER TABLE {{survey_{$iSurveyID}}} AUTO_INCREMENT = ".$row['autonumber_start'];
$result = @Yii::app()->db->createCommand($autonumberquery)->execute();
}
}
} }
} }

View file

@ -62,21 +62,26 @@
function _outputDBData($bAllowExportAllDb, $bEchoOutput, $sFileName, $oFile) function _outputDBData($bAllowExportAllDb, $bEchoOutput, $sFileName, $oFile)
{ {
$aTables = Yii::app()->db->getSchema()->getTables(); if ($bAllowExportAllDb){
foreach ($aTables as $sTableName => $oTableData) $aTables = Yii::app()->db->getSchema()->getTableNames();
}
else
{ {
if ($bAllowExportAllDb && Yii::app()->db->tablePrefix == substr($sTableName, 0, strlen(Yii::app()->db->tablePrefix))) { $aTables = Yii::app()->db->createCommand(dbSelectTablesLike(addcslashes(Yii::app()->db->tablePrefix,'_')."%"))->queryColumn();
$sOutput=_outputTableDescription($sTableName); }
if ($bEchoOutput) foreach ($aTables as $sTableName)
{ {
echo $sOutput; $oTableData=Yii::app()->db->getSchema()->getTable($sTableName);
} $sOutput=_outputTableDescription($sTableName);
if (!is_null($sFileName)) if ($bEchoOutput)
{ {
fwrite($oFile,$sOutput); echo $sOutput;
}
_outputTableData($sTableName, $oTableData, $bEchoOutput, $sFileName, $oFile);
} }
if (!is_null($sFileName))
{
fwrite($oFile,$sOutput);
}
_outputTableData($sTableName, $oTableData, $bEchoOutput, $sFileName, $oFile);
} }
} }
@ -115,7 +120,7 @@
$aRecords = Yii::app()->db->createCommand() $aRecords = Yii::app()->db->createCommand()
->select() ->select()
->from($sTableName) ->from($sTableName)
->limit(intval($iMaxNbRecords), ($i != 0 ? ($i * $iMaxNbRecords) + 1 : null)) ->limit(intval($iMaxNbRecords), ($i != 0 ? ($i * $iMaxNbRecords) : null))
->query()->readAll(); ->query()->readAll();
$sOutput.=_outputRecords($sTableName, $aFieldNames, $aRecords); $sOutput.=_outputRecords($sTableName, $aFieldNames, $aRecords);
@ -146,6 +151,8 @@
function _outputRecords($sTableName, $aFieldNames, $aRecords) function _outputRecords($sTableName, $aFieldNames, $aRecords)
{ {
$sLastFieldName=end($aFieldNames);
$aLastRecord=end($aRecords);
$i=0; $i=0;
$sOutput=''; $sOutput='';
foreach ($aRecords as $aRecord) foreach ($aRecords as $aRecord)
@ -164,21 +171,19 @@
{ {
if (isset($aRecord[$sFieldName]) && !is_null($aRecord[$sFieldName])) { if (isset($aRecord[$sFieldName]) && !is_null($aRecord[$sFieldName])) {
$sValue= addcslashes($aRecord[$sFieldName],"'"); $sOutput.=Yii::app()->db->quoteValue($aRecord[$sFieldName]);
$sValue = preg_replace("#\n#", "\\n", $sValue);
$sOutput.= "'" . $sValue . "'";
} }
else else
{ {
$sOutput.= 'NULL'; $sOutput.= 'NULL';
} }
if (end($aFieldNames) != $sFieldName) { if ($sFieldName != $sLastFieldName) {
$sOutput.= ', '; $sOutput.= ', ';
} }
} }
$i++; $i++;
if ($i==200 || (end($aRecords) == $aRecord)) if ($i==200 || ($aLastRecord == $aRecord))
{ {
$sOutput.= ');' . "\n"; $sOutput.= ');' . "\n";
$i=0; $i=0;
@ -219,4 +224,3 @@
return $sDbName; return $sDbName;
} }

View file

@ -37,19 +37,7 @@
} elseif ($oOptions->output == 'file') { } elseif ($oOptions->output == 'file') {
$this->handle = fopen($this->filename, 'w'); $this->handle = fopen($this->filename, 'w');
} }
$this->groupMap = array(); $this->groupMap = $this->setGroupMap($survey, $oOptions);
$index = 0;
foreach ($oOptions->selectedColumns as $column) {
if (isset($survey->fieldMap[$column])) {
$question = $survey->fieldMap[$column];
} else {
// Token field
$question = array('gid'=>0, 'qid'=>'');
}
$question['index'] = $index;
$this->groupMap[intval($question['gid'])][] = $question;
$index++;
}
} }
protected function writeHeader() protected function writeHeader()
@ -77,6 +65,7 @@
$this->writeHeader(); $this->writeHeader();
$this->first = false; $this->first = false;
} }
$this->tag('h1', sprintf(gT("Survey response")));
$this->openTag('div', array( $this->openTag('div', array(
'class' => 'response', 'class' => 'response',
'data-srid' => $values[0] 'data-srid' => $values[0]

View file

@ -8,6 +8,14 @@ class PdfWriter extends Writer
private $surveyName; private $surveyName;
private $clang; private $clang;
/**
* Map of questions groups
*
* @var array
* @access private
*/
private $aGroupMap = array();
public function init(SurveyObj $survey, $sLanguageCode, FormattingOptions $oOptions) public function init(SurveyObj $survey, $sLanguageCode, FormattingOptions $oOptions)
{ {
parent::init($survey, $sLanguageCode, $oOptions); parent::init($survey, $sLanguageCode, $oOptions);
@ -26,16 +34,11 @@ class PdfWriter extends Writer
// create new PDF document // create new PDF document
$this->pdf = new pdf(); $this->pdf = new pdf();
$this->pdf->SetFont($aPdfLanguageSettings['pdffont'], '', $aPdfLanguageSettings['pdffontsize']); $this->surveyName = $survey->info['surveyls_title'];
$this->pdf->AddPage(); $this->pdf->initAnswerPDF($survey->info, $aPdfLanguageSettings, Yii::app()->getConfig('sitename'), $this->surveyName);
$this->pdf->intopdf("PDF export ".date("Y.m.d-H:i", time()));
$this->pdf->setLanguageArray($aPdfLanguageSettings['lg']);
$this->separator="\t"; $this->separator="\t";
$this->rowCounter = 0; $this->rowCounter = 0;
$this->surveyName = $survey->languageSettings['surveyls_title']; $this->aGroupMap = $this->setGroupMap($survey, $oOptions);
$this->pdf->titleintopdf($this->surveyName, $survey->languageSettings['surveyls_description']);
} }
public function outputRecord($headers, $values, FormattingOptions $oOptions) public function outputRecord($headers, $values, FormattingOptions $oOptions)
@ -44,7 +47,6 @@ class PdfWriter extends Writer
if ($oOptions->answerFormat == 'short') if ($oOptions->answerFormat == 'short')
{ {
$pdfstring = ''; $pdfstring = '';
$this->pdf->titleintopdf($this->clang->gT("Survey response"));
foreach ($values as $value) foreach ($values as $value)
{ {
$pdfstring .= $value.' | '; $pdfstring .= $value.' | ';
@ -57,14 +59,28 @@ class PdfWriter extends Writer
{ {
$this->pdf->AddPage(); $this->pdf->AddPage();
} }
$this->pdf->Cell(0, 10, sprintf($this->clang->gT("Survey response %d"), $this->rowCounter), 1, 1); $this->pdf->addTitle(sprintf($this->clang->gT("Survey response %d"), $this->rowCounter));
foreach ($this->aGroupMap as $gid => $questions)
$columnCounter = 0;
foreach($headers as $header)
{ {
$this->pdf->intopdf($header); if ($gid != 0)
$this->pdf->intopdf($this->stripTagsFull($values[$columnCounter])); {
$columnCounter++; $this->pdf->addGidAnswer($questions[0]['group_name']);
}
foreach ($questions as $question)
{
if (isset($values[$question['index']]) && isset($headers[$question['index']]))
{
if ($question['type'] == 'N' || $question['type'] == 'K')
{
$sAuxValue=number_format(floatval($values[$question['index']]), 0, '', '');
$this->pdf->addAnswer($headers[$question['index']], $sAuxValue, false);
}
else
{
$this->pdf->addAnswer($headers[$question['index']], $values[$question['index']], false);
}
}
}
} }
} }
else else

View file

@ -36,6 +36,31 @@ abstract class Writer implements IWriter
} }
} }
/**
* Return map of questions groups
*
* @param Survey $survey
* @param FormattingOptions $oOptions
* @return array
*/
public function setGroupMap(SurveyObj $survey, FormattingOptions $oOptions)
{
$aGroupMap = array();
$index = 0;
foreach ($oOptions->selectedColumns as $column) {
if (isset($survey->fieldMap[$column])) {
$question = $survey->fieldMap[$column];
} else {
// Token field
$question = array('gid'=>0, 'qid'=>'');
}
$question['index'] = $index;
$aGroupMap[intval($question['gid'])][] = $question;
$index++;
}
return $aGroupMap;
}
/** /**
* Returns an abbreviated heading for the survey's question that matches * Returns an abbreviated heading for the survey's question that matches
* the $fieldName parameter (or false if a match is not found). * the $fieldName parameter (or false if a match is not found).
@ -395,6 +420,18 @@ abstract class Writer implements IWriter
} }
//Output the results. //Output the results.
$sFile=''; $sFile='';
// If empty survey, prepare an empty responses array, and output just 1 empty record with header.
if ($survey->responses->rowCount == 0)
{
foreach ($oOptions->selectedColumns as $column)
{
$elementArray[]="";
}
$this->outputRecord($headers, $elementArray, $oOptions);
}
// If no empty survey, render/export responses array.
foreach($survey->responses as $response) foreach($survey->responses as $response)
{ {
$elementArray = array(); $elementArray = array();

View file

@ -198,7 +198,7 @@
} }
$htmlcode .= "" $htmlcode .= ""
. "<a href=\"javascript:start_popup_editor('".$fieldname."','".addslashes($fieldtext)."','".$surveyID."','".$gID."','".$qID."','".$fieldtype."','".$action."')\" id='".$fieldname."_ctrl' class='editorLink'>\n" . "<a href=\"javascript:start_popup_editor('".$fieldname."','".addslashes(htmlspecialchars_decode($fieldtext,ENT_QUOTES))."','".$surveyID."','".$gID."','".$qID."','".$fieldtype."','".$action."')\" id='".$fieldname."_ctrl' class='editorLink'>\n"
. "\t<img alt=\"".$clang->gT("Start HTML editor in a popup window")."\" id='".$fieldname."_popupctrlena' src='".Yii::app()->getConfig('adminimageurl')."edithtmlpopup.png' $imgopts class='btneditanswerena' />\n" . "\t<img alt=\"".$clang->gT("Start HTML editor in a popup window")."\" id='".$fieldname."_popupctrlena' src='".Yii::app()->getConfig('adminimageurl')."edithtmlpopup.png' $imgopts class='btneditanswerena' />\n"
. "\t<img alt=\"".$clang->gT("Give focus to the HTML editor popup window")."\" id='".$fieldname."_popupctrldis' src='".Yii::app()->getConfig('adminimageurl')."edithtmlpopup_disabled.png' style='display:none' $imgopts class='btneditanswerdis' />\n" . "\t<img alt=\"".$clang->gT("Give focus to the HTML editor popup window")."\" id='".$fieldname."_popupctrldis' src='".Yii::app()->getConfig('adminimageurl')."edithtmlpopup_disabled.png' style='display:none' $imgopts class='btneditanswerdis' />\n"
. "</a>\n"; . "</a>\n";

View file

@ -194,14 +194,14 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
$countgroups=0; $countgroups=0;
if (isset($questionarray)) if (isset($questionarray))
{ {
$questionfieldnames=convertCSVRowToArray($questionarray[0],',','"'); $questionfieldnames=str_getcsv($questionarray[0],',','"');
unset($questionarray[0]); unset($questionarray[0]);
$countquestions = 0; $countquestions = 0;
} }
if (isset($answerarray)) if (isset($answerarray))
{ {
$answerfieldnames=convertCSVRowToArray($answerarray[0],',','"'); $answerfieldnames=str_getcsv($answerarray[0],',','"');
unset($answerarray[0]); unset($answerarray[0]);
$countanswers = count($answerarray); $countanswers = count($answerarray);
} }
@ -220,7 +220,7 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
$langcode = Survey::model()->findByPk($iNewSID)->language; $langcode = Survey::model()->findByPk($iNewSID)->language;
if (isset($grouparray)) if (isset($grouparray))
{ {
$groupfieldnames = convertCSVRowToArray($grouparray[0],',','"'); $groupfieldnames = str_getcsv($grouparray[0],',','"');
$langfieldnum = array_search("language", $groupfieldnames); $langfieldnum = array_search("language", $groupfieldnames);
$gidfieldnum = array_search("gid", $groupfieldnames); $gidfieldnum = array_search("gid", $groupfieldnames);
$groupssupportbaselang = doesImportArraySupportLanguage($grouparray,Array($gidfieldnum),$langfieldnum,$sBaseLanguage,true); $groupssupportbaselang = doesImportArraySupportLanguage($grouparray,Array($gidfieldnum),$langfieldnum,$sBaseLanguage,true);
@ -261,7 +261,7 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
if (count($labelsetsarray) > 1) if (count($labelsetsarray) > 1)
{ {
$labelsetfieldname = convertCSVRowToArray($labelsetsarray[0],',','"'); $labelsetfieldname = str_getcsv($labelsetsarray[0],',','"');
$langfieldnum = array_search("languages", $labelsetfieldname); $langfieldnum = array_search("languages", $labelsetfieldname);
$lidfilednum = array_search("lid", $labelsetfieldname); $lidfilednum = array_search("lid", $labelsetfieldname);
$labelsetssupportbaselang = doesImportArraySupportLanguage($labelsetsarray,Array($lidfilednum),$langfieldnum,$sBaseLanguage,true); $labelsetssupportbaselang = doesImportArraySupportLanguage($labelsetsarray,Array($lidfilednum),$langfieldnum,$sBaseLanguage,true);
@ -288,8 +288,8 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
$csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets $csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets
$count=0; $count=0;
foreach ($labelsetsarray as $lsa) { foreach ($labelsetsarray as $lsa) {
$fieldorders =convertCSVRowToArray($labelsetsarray[0],',','"'); $fieldorders =str_getcsv($labelsetsarray[0],',','"');
$fieldcontents=convertCSVRowToArray($lsa,',','"'); $fieldcontents=str_getcsv($lsa,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
$labelsetrowdata=array_combine($fieldorders,$fieldcontents); $labelsetrowdata=array_combine($fieldorders,$fieldcontents);
@ -308,8 +308,8 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
if ($labelsarray) { if ($labelsarray) {
$count=0; $count=0;
foreach ($labelsarray as $la) { foreach ($labelsarray as $la) {
$lfieldorders =convertCSVRowToArray($labelsarray[0],',','"'); $lfieldorders =str_getcsv($labelsarray[0],',','"');
$lfieldcontents=convertCSVRowToArray($la,',','"'); $lfieldcontents=str_getcsv($la,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
// Combine into one array with keys and values since its easier to handle // Combine into one array with keys and values since its easier to handle
@ -385,14 +385,14 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
if (isset($grouparray) && $grouparray) if (isset($grouparray) && $grouparray)
{ {
// do GROUPS // do GROUPS
$gafieldorders=convertCSVRowToArray($grouparray[0],',','"'); $gafieldorders=str_getcsv($grouparray[0],',','"');
unset($grouparray[0]); unset($grouparray[0]);
$newgid = 0; $newgid = 0;
$group_order = 0; // just to initialize this variable $group_order = 0; // just to initialize this variable
foreach ($grouparray as $ga) foreach ($grouparray as $ga)
{ {
$gacfieldcontents=convertCSVRowToArray($ga,',','"'); $gacfieldcontents=str_getcsv($ga,',','"');
$grouprowdata=array_combine($gafieldorders,$gacfieldcontents); $grouprowdata=array_combine($gafieldorders,$gacfieldcontents);
// Skip not supported languages // Skip not supported languages
@ -447,7 +447,7 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
foreach ($questionarray as $qa) foreach ($questionarray as $qa)
{ {
$qacfieldcontents=convertCSVRowToArray($qa,',','"'); $qacfieldcontents=str_getcsv($qa,',','"');
$questionrowdata=array_combine($questionfieldnames,$qacfieldcontents); $questionrowdata=array_combine($questionfieldnames,$qacfieldcontents);
$questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata); $questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata);
$questionrowdata["type"]=strtoupper($questionrowdata["type"]); $questionrowdata["type"]=strtoupper($questionrowdata["type"]);
@ -582,7 +582,7 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
{ {
foreach ($answerarray as $aa) foreach ($answerarray as $aa)
{ {
$answerfieldcontents=convertCSVRowToArray($aa,',','"'); $answerfieldcontents=str_getcsv($aa,',','"');
$answerrowdata=array_combine($answerfieldnames,$answerfieldcontents); $answerrowdata=array_combine($answerfieldnames,$answerfieldcontents);
if ($answerrowdata===false) if ($answerrowdata===false)
{ {
@ -682,11 +682,11 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
// Finally the question attributes - it is called just once and only if there was a question // Finally the question attributes - it is called just once and only if there was a question
if (isset($question_attributesarray) && $question_attributesarray) if (isset($question_attributesarray) && $question_attributesarray)
{//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES
$fieldorders=convertCSVRowToArray($question_attributesarray[0],',','"'); $fieldorders=str_getcsv($question_attributesarray[0],',','"');
unset($question_attributesarray[0]); unset($question_attributesarray[0]);
foreach ($question_attributesarray as $qar) { foreach ($question_attributesarray as $qar) {
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
$qarowdata=array_combine($fieldorders,$fieldcontents); $qarowdata=array_combine($fieldorders,$fieldcontents);
// replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this attribute is orphan -> error, skip this record) // replace the qid for the new one (if there is no new qid in the $aQIDReplacements array it mean that this attribute is orphan -> error, skip this record)
@ -710,10 +710,10 @@ function CSVImportGroup($sFullFilePath, $iNewSID)
$results['conditions']=0; $results['conditions']=0;
if (isset($conditionsarray) && $conditionsarray) if (isset($conditionsarray) && $conditionsarray)
{ {
$fieldorders=convertCSVRowToArray($conditionsarray[0],',','"'); $fieldorders=str_getcsv($conditionsarray[0],',','"');
unset($conditionsarray[0]); unset($conditionsarray[0]);
foreach ($conditionsarray as $car) { foreach ($conditionsarray as $car) {
$fieldcontents=convertCSVRowToArray($car,',','"'); $fieldcontents=str_getcsv($car,',','"');
$conditionrowdata=array_combine($fieldorders,$fieldcontents); $conditionrowdata=array_combine($fieldorders,$fieldcontents);
$oldqid = $conditionrowdata["qid"]; $oldqid = $conditionrowdata["qid"];
@ -1238,7 +1238,7 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
if (isset($questionarray)) if (isset($questionarray))
{ {
$questionfieldnames=convertCSVRowToArray($questionarray[0],',','"'); $questionfieldnames=str_getcsv($questionarray[0],',','"');
unset($questionarray[0]); unset($questionarray[0]);
$countquestions = count($questionarray)-1; $countquestions = count($questionarray)-1;
} }
@ -1246,7 +1246,7 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
if (isset($answerarray)) if (isset($answerarray))
{ {
$answerfieldnames=convertCSVRowToArray($answerarray[0],',','"'); $answerfieldnames=str_getcsv($answerarray[0],',','"');
unset($answerarray[0]); unset($answerarray[0]);
while (trim(reset($answerarray))=='') while (trim(reset($answerarray))=='')
{ {
@ -1298,7 +1298,7 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
if ($countlabelsets > 0) if ($countlabelsets > 0)
{ {
$labelsetfieldname = convertCSVRowToArray($labelsetsarray[0],',','"'); $labelsetfieldname = str_getcsv($labelsetsarray[0],',','"');
$langfieldnum = array_search("languages", $labelsetfieldname); $langfieldnum = array_search("languages", $labelsetfieldname);
$lidfilednum = array_search("lid", $labelsetfieldname); $lidfilednum = array_search("lid", $labelsetfieldname);
$labelsetssupportbaselang = doesImportArraySupportLanguage($labelsetsarray,Array($lidfilednum),$langfieldnum,$sBaseLanguage,true); $labelsetssupportbaselang = doesImportArraySupportLanguage($labelsetsarray,Array($lidfilednum),$langfieldnum,$sBaseLanguage,true);
@ -1316,8 +1316,8 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
$csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets $csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets
$count=0; $count=0;
foreach ($labelsetsarray as $lsa) { foreach ($labelsetsarray as $lsa) {
$fieldorders =convertCSVRowToArray($labelsetsarray[0],',','"'); $fieldorders =str_getcsv($labelsetsarray[0],',','"');
$fieldcontents=convertCSVRowToArray($lsa,',','"'); $fieldcontents=str_getcsv($lsa,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
$results['labelsets']++; $results['labelsets']++;
@ -1338,8 +1338,8 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
if ($labelsarray) { if ($labelsarray) {
$count=0; $count=0;
foreach ($labelsarray as $la) { foreach ($labelsarray as $la) {
$lfieldorders =convertCSVRowToArray($labelsarray[0],',','"'); $lfieldorders =str_getcsv($labelsarray[0],',','"');
$lfieldcontents=convertCSVRowToArray($la,',','"'); $lfieldcontents=str_getcsv($la,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
// Combine into one array with keys and values since its easier to handle // Combine into one array with keys and values since its easier to handle
@ -1432,7 +1432,7 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
foreach ($questionarray as $qa) foreach ($questionarray as $qa)
{ {
$qacfieldcontents=convertCSVRowToArray($qa,',','"'); $qacfieldcontents=str_getcsv($qa,',','"');
$questionrowdata=array_combine($questionfieldnames,$qacfieldcontents); $questionrowdata=array_combine($questionfieldnames,$qacfieldcontents);
// Skip not supported languages // Skip not supported languages
@ -1567,7 +1567,7 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
{ {
foreach ($answerarray as $aa) foreach ($answerarray as $aa)
{ {
$answerfieldcontents=convertCSVRowToArray($aa,',','"'); $answerfieldcontents=str_getcsv($aa,',','"');
$answerrowdata=array_combine($answerfieldnames,$answerfieldcontents); $answerrowdata=array_combine($answerfieldnames,$answerfieldcontents);
if ($answerrowdata===false) if ($answerrowdata===false)
{ {
@ -1660,10 +1660,10 @@ function CSVImportQuestion($sFullFilePath, $iNewSID, $newgid)
// Finally the question attributes - it is called just once and only if there was a question // Finally the question attributes - it is called just once and only if there was a question
if (isset($question_attributesarray) && $question_attributesarray) if (isset($question_attributesarray) && $question_attributesarray)
{//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES
$fieldorders =convertCSVRowToArray($question_attributesarray[0],',','"'); $fieldorders =str_getcsv($question_attributesarray[0],',','"');
unset($question_attributesarray[0]); unset($question_attributesarray[0]);
foreach ($question_attributesarray as $qar) { foreach ($question_attributesarray as $qar) {
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
$qarowdata=array_combine($fieldorders,$fieldcontents); $qarowdata=array_combine($fieldorders,$fieldcontents);
$qarowdata["qid"]=$newqid; $qarowdata["qid"]=$newqid;
unset($qarowdata["qaid"]); unset($qarowdata["qaid"]);
@ -2019,8 +2019,8 @@ function CSVImportLabelset($sFullFilePath, $options)
if (isset($labelsetsarray) && $labelsetsarray) { if (isset($labelsetsarray) && $labelsetsarray) {
$count=0; $count=0;
foreach ($labelsetsarray as $lsa) { foreach ($labelsetsarray as $lsa) {
$fieldorders =convertCSVRowToArray($labelsetsarray[0],',','"'); $fieldorders =str_getcsv($labelsetsarray[0],',','"');
$fieldcontents=convertCSVRowToArray($lsa,',','"'); $fieldcontents=str_getcsv($lsa,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
$labelsetrowdata=array_combine($fieldorders,$fieldcontents); $labelsetrowdata=array_combine($fieldorders,$fieldcontents);
@ -2040,11 +2040,11 @@ function CSVImportLabelset($sFullFilePath, $options)
if ($labelsarray) { if ($labelsarray) {
$count=0; $count=0;
$lfieldorders=convertCSVRowToArray($labelsarray[0],',','"'); $lfieldorders=str_getcsv($labelsarray[0],',','"');
unset($labelsarray[0]); unset($labelsarray[0]);
foreach ($labelsarray as $la) { foreach ($labelsarray as $la) {
$lfieldcontents=convertCSVRowToArray($la,',','"'); $lfieldcontents=str_getcsv($la,',','"');
// Combine into one array with keys and values since its easier to handle // Combine into one array with keys and values since its easier to handle
$labelrowdata=array_combine($lfieldorders,$lfieldcontents); $labelrowdata=array_combine($lfieldorders,$lfieldcontents);
$labellid=$labelrowdata['lid']; $labellid=$labelrowdata['lid'];
@ -2259,7 +2259,6 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$substitutions=array(); $substitutions=array();
$aQuestionCodeReplacements=array(); $aQuestionCodeReplacements=array();
$aQuotaReplacements=array(); $aQuotaReplacements=array();
$importresults['error']=false;
$importresults['importwarnings']=array(); $importresults['importwarnings']=array();
$importresults['question_attributes']=0; $importresults['question_attributes']=0;
@ -2597,8 +2596,8 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
if ($importresults['conditions']>0){$importresults['conditions']--;}; if ($importresults['conditions']>0){$importresults['conditions']--;};
if ($importresults['labelsets']>0){$importresults['labelsets']--;}; if ($importresults['labelsets']>0){$importresults['labelsets']--;};
if ($importresults['quota']>0){$importresults['quota']--;}; if ($importresults['quota']>0){$importresults['quota']--;};
$sfieldorders =convertCSVRowToArray($surveyarray[0],',','"'); $sfieldorders =str_getcsv($surveyarray[0],',','"');
$sfieldcontents=convertCSVRowToArray($surveyarray[1],',','"'); $sfieldcontents=str_getcsv($surveyarray[1],',','"');
$surveyrowdata=array_combine($sfieldorders,$sfieldcontents); $surveyrowdata=array_combine($sfieldorders,$sfieldcontents);
$iOldSID=$surveyrowdata["sid"]; $iOldSID=$surveyrowdata["sid"];
@ -2631,8 +2630,8 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$insert=$surveyarray[0]; $insert=$surveyarray[0];
$sfieldorders =convertCSVRowToArray($surveyarray[0],',','"'); $sfieldorders =str_getcsv($surveyarray[0],',','"');
$sfieldcontents=convertCSVRowToArray($surveyarray[1],',','"'); $sfieldcontents=str_getcsv($surveyarray[1],',','"');
$surveyrowdata=array_combine($sfieldorders,$sfieldcontents); $surveyrowdata=array_combine($sfieldorders,$sfieldcontents);
// Set new owner ID // Set new owner ID
$surveyrowdata['owner_id']=Yii::app()->session['loginID']; $surveyrowdata['owner_id']=Yii::app()->session['loginID'];
@ -2662,10 +2661,10 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$iNewSID = Survey::model()->insertNewSurvey($surveyrowdata) or safeDie ("<br />".$clang->gT("Import of this survey file failed")."<br />{$surveyarray[0]}<br /><br />\n" ); $iNewSID = Survey::model()->insertNewSurvey($surveyrowdata) or safeDie ("<br />".$clang->gT("Import of this survey file failed")."<br />{$surveyarray[0]}<br /><br />\n" );
// Now import the survey language settings // Now import the survey language settings
$fieldorders=convertCSVRowToArray($surveylsarray[0],',','"'); $fieldorders=str_getcsv($surveylsarray[0],',','"');
unset($surveylsarray[0]); unset($surveylsarray[0]);
foreach ($surveylsarray as $slsrow) { foreach ($surveylsarray as $slsrow) {
$fieldcontents=convertCSVRowToArray($slsrow,',','"'); $fieldcontents=str_getcsv($slsrow,',','"');
$surveylsrowdata=array_combine($fieldorders,$fieldcontents); $surveylsrowdata=array_combine($fieldorders,$fieldcontents);
// convert back the '\'.'n' char from the CSV file to true return char "\n" // convert back the '\'.'n' char from the CSV file to true return char "\n"
$surveylsrowdata=array_map('convertCSVReturnToReturn', $surveylsrowdata); $surveylsrowdata=array_map('convertCSVReturnToReturn', $surveylsrowdata);
@ -2699,8 +2698,7 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages); $aLanguagesSupported=array_merge($aLanguagesSupported,Survey::model()->findByPk($iNewSID)->additionalLanguages);
// DO SURVEY_RIGHTS // Create survey permissions
Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'],$iNewSID); Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'],$iNewSID);
$importresults['deniedcountls'] =0; $importresults['deniedcountls'] =0;
@ -2718,8 +2716,8 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets $csarray=buildLabelSetCheckSumArray(); // build checksums over all existing labelsets
$count=0; $count=0;
foreach ($labelsetsarray as $lsa) { foreach ($labelsetsarray as $lsa) {
$fieldorders =convertCSVRowToArray($labelsetsarray[0],',','"'); $fieldorders =str_getcsv($labelsetsarray[0],',','"');
$fieldcontents=convertCSVRowToArray($lsa,',','"'); $fieldcontents=str_getcsv($lsa,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
$labelsetrowdata=array_combine($fieldorders,$fieldcontents); $labelsetrowdata=array_combine($fieldorders,$fieldcontents);
@ -2737,8 +2735,8 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
if ($labelsarray) { if ($labelsarray) {
$count=0; $count=0;
foreach ($labelsarray as $la) { foreach ($labelsarray as $la) {
$lfieldorders =convertCSVRowToArray($labelsarray[0],',','"'); $lfieldorders =str_getcsv($labelsarray[0],',','"');
$lfieldcontents=convertCSVRowToArray($la,',','"'); $lfieldcontents=str_getcsv($la,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
// Combine into one array with keys and values since its easier to handle // Combine into one array with keys and values since its easier to handle
@ -2815,11 +2813,11 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
if (isset($grouparray) && $grouparray) if (isset($grouparray) && $grouparray)
{ {
// do GROUPS // do GROUPS
$gafieldorders=convertCSVRowToArray($grouparray[0],',','"'); $gafieldorders=str_getcsv($grouparray[0],',','"');
unset($grouparray[0]); unset($grouparray[0]);
foreach ($grouparray as $ga) foreach ($grouparray as $ga)
{ {
$gacfieldcontents=convertCSVRowToArray($ga,',','"'); $gacfieldcontents=str_getcsv($ga,',','"');
$grouprowdata=array_combine($gafieldorders,$gacfieldcontents); $grouprowdata=array_combine($gafieldorders,$gacfieldcontents);
//Now an additional integrity check if there are any groups not belonging into this survey //Now an additional integrity check if there are any groups not belonging into this survey
@ -2867,11 +2865,11 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
// Import questions // Import questions
if (isset($questionarray) && $questionarray) if (isset($questionarray) && $questionarray)
{ {
$qafieldorders=convertCSVRowToArray($questionarray[0],',','"'); $qafieldorders=str_getcsv($questionarray[0],',','"');
unset($questionarray[0]); unset($questionarray[0]);
foreach ($questionarray as $qa) foreach ($questionarray as $qa)
{ {
$qacfieldcontents=convertCSVRowToArray($qa,',','"'); $qacfieldcontents=str_getcsv($qa,',','"');
$questionrowdata=array_combine($qafieldorders,$qacfieldcontents); $questionrowdata=array_combine($qafieldorders,$qacfieldcontents);
$questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata); $questionrowdata=array_map('convertCSVReturnToReturn', $questionrowdata);
$questionrowdata["type"]=strtoupper($questionrowdata["type"]); $questionrowdata["type"]=strtoupper($questionrowdata["type"]);
@ -3044,12 +3042,12 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
//Do answers //Do answers
if (isset($answerarray) && $answerarray) if (isset($answerarray) && $answerarray)
{ {
$answerfieldnames = convertCSVRowToArray($answerarray[0],',','"'); $answerfieldnames = str_getcsv($answerarray[0],',','"');
unset($answerarray[0]); unset($answerarray[0]);
foreach ($answerarray as $aa) foreach ($answerarray as $aa)
{ {
$answerfieldcontents = convertCSVRowToArray($aa,',','"'); $answerfieldcontents = str_getcsv($aa,',','"');
$answerrowdata = array_combine($answerfieldnames,$answerfieldcontents); $answerrowdata = array_combine($answerfieldnames,$answerfieldcontents);
if (in_array($answerrowdata['qid'],$aIgnoredAnswers)) if (in_array($answerrowdata['qid'],$aIgnoredAnswers))
{ {
@ -3155,7 +3153,7 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
{ {
// safeDie($clang->gT("Error while saving: "). print_r($question->errors, true)); // safeDie($clang->gT("Error while saving: "). print_r($question->errors, true));
// //
// In PHP 5.2.10 a bug is triggered that resets the foreach loop when inserting a record // In PHP 5.2.10 and some later versions a bug is triggered that resets the foreach loop when inserting a record
// Problem is that it is the default PHP version on Ubuntu 12.04 LTS (which is currently very common in use) // Problem is that it is the default PHP version on Ubuntu 12.04 LTS (which is currently very common in use)
// For this reason we ignore insertion errors (because it is most likely a duplicate) // For this reason we ignore insertion errors (because it is most likely a duplicate)
// and continue with the next one // and continue with the next one
@ -3217,10 +3215,10 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
//We've built two arrays along the way - one containing the old SID, GID and QIDs - and their NEW equivalents //We've built two arrays along the way - one containing the old SID, GID and QIDs - and their NEW equivalents
//and one containing the old 'extended fieldname' and its new equivalent. These are needed to import conditions and question_attributes. //and one containing the old 'extended fieldname' and its new equivalent. These are needed to import conditions and question_attributes.
if (isset($question_attributesarray) && $question_attributesarray) {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES if (isset($question_attributesarray) && $question_attributesarray) {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUES
$fieldorders =convertCSVRowToArray($question_attributesarray[0],',','"'); $fieldorders =str_getcsv($question_attributesarray[0],',','"');
unset($question_attributesarray[0]); unset($question_attributesarray[0]);
foreach ($question_attributesarray as $qar) { foreach ($question_attributesarray as $qar) {
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
$qarowdata=array_combine($fieldorders,$fieldcontents); $qarowdata=array_combine($fieldorders,$fieldcontents);
$newqid=""; $newqid="";
$qarowdata["qid"]=$aQIDReplacements[$qarowdata["qid"]]; $qarowdata["qid"]=$aQIDReplacements[$qarowdata["qid"]];
@ -3231,11 +3229,11 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
} }
if (isset($assessmentsarray) && $assessmentsarray) {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUTES if (isset($assessmentsarray) && $assessmentsarray) {//ONLY DO THIS IF THERE ARE QUESTION_ATTRIBUTES
$fieldorders=convertCSVRowToArray($assessmentsarray[0],',','"'); $fieldorders=str_getcsv($assessmentsarray[0],',','"');
unset($assessmentsarray[0]); unset($assessmentsarray[0]);
foreach ($assessmentsarray as $qar) foreach ($assessmentsarray as $qar)
{ {
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
$asrowdata=array_combine($fieldorders,$fieldcontents); $asrowdata=array_combine($fieldorders,$fieldcontents);
if (isset($asrowdata['link'])) if (isset($asrowdata['link']))
{ {
@ -3257,19 +3255,12 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
} }
if (isset($quotaarray) && $quotaarray) {//ONLY DO THIS IF THERE ARE QUOTAS if (isset($quotaarray) && $quotaarray) {//ONLY DO THIS IF THERE ARE QUOTAS
$fieldorders=convertCSVRowToArray($quotaarray[0],',','"'); $fieldorders=str_getcsv($quotaarray[0],',','"');
unset($quotaarray[0]); unset($quotaarray[0]);
foreach ($quotaarray as $qar) foreach ($quotaarray as $qar)
{ {
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
$asrowdata=array_combine($fieldorders,$fieldcontents); $asrowdata=array_combine($fieldorders,$fieldcontents);
$iOldSID=$asrowdata["sid"];
foreach ($substitutions as $subs) {
if ($iOldSID==$subs[0]) {$iNewSID=$subs[3];}
}
$asrowdata["sid"]=$iNewSID; $asrowdata["sid"]=$iNewSID;
$oldid = $asrowdata["id"]; $oldid = $asrowdata["id"];
unset($asrowdata["id"]); unset($asrowdata["id"]);
@ -3283,27 +3274,20 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$count=0; $count=0;
foreach ($quotamembersarray as $qar) { foreach ($quotamembersarray as $qar) {
$fieldorders =convertCSVRowToArray($quotamembersarray[0],',','"'); $fieldorders =str_getcsv($quotamembersarray[0],',','"');
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
$asrowdata=array_combine($fieldorders,$fieldcontents); $asrowdata=array_combine($fieldorders,$fieldcontents);
$iOldSID=$asrowdata["sid"]; $iOldSID=$asrowdata["sid"];
$newqid="";
$newquotaid="";
$oldqid=$asrowdata['qid']; $oldqid=$asrowdata['qid'];
$oldquotaid=$asrowdata['quota_id']; $oldquotaid=$asrowdata['quota_id'];
foreach ($substitutions as $subs) {
if ($iOldSID==$subs[0]) {$iNewSID=$subs[3];}
if ($oldqid==$subs[2]) {$newqid=$subs[5];}
}
$newquotaid=$aQuotaReplacements[$oldquotaid]; $newquotaid=$aQuotaReplacements[$oldquotaid];
$asrowdata["sid"]=$iNewSID; $asrowdata["sid"]=$iNewSID;
$asrowdata["qid"]=$newqid; $asrowdata["qid"]=$aQIDReplacements[$oldqid];
$asrowdata["quota_id"]=$newquotaid; $asrowdata["quota_id"]=$newquotaid;
unset($asrowdata["id"]); unset($asrowdata["id"]);
@ -3316,8 +3300,8 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
$count=0; $count=0;
foreach ($quotalsarray as $qar) { foreach ($quotalsarray as $qar) {
$fieldorders =convertCSVRowToArray($quotalsarray[0],',','"'); $fieldorders =str_getcsv($quotalsarray[0],',','"');
$fieldcontents=convertCSVRowToArray($qar,',','"'); $fieldcontents=str_getcsv($qar,',','"');
if ($count==0) {$count++; continue;} if ($count==0) {$count++; continue;}
$asrowdata=array_combine($fieldorders,$fieldcontents); $asrowdata=array_combine($fieldorders,$fieldcontents);
@ -3354,12 +3338,12 @@ function CSVImportSurvey($sFullFilePath,$iDesiredSurveyId=NULL,$bTranslateLinks=
// Do conditions // Do conditions
if (isset($conditionsarray) && $conditionsarray) {//ONLY DO THIS IF THERE ARE CONDITIONS! if (isset($conditionsarray) && $conditionsarray) {//ONLY DO THIS IF THERE ARE CONDITIONS!
$fieldorders =convertCSVRowToArray($conditionsarray[0],',','"'); $fieldorders =str_getcsv($conditionsarray[0],',','"');
unset($conditionsarray[0]); unset($conditionsarray[0]);
// Exception for conditions based on attributes // Exception for conditions based on attributes
$aQIDReplacements[0]=0; $aQIDReplacements[0]=0;
foreach ($conditionsarray as $car) { foreach ($conditionsarray as $car) {
$fieldcontents=convertCSVRowToArray($car,',','"'); $fieldcontents=str_getcsv($car,',','"');
$conditionrowdata=array_combine($fieldorders,$fieldcontents); $conditionrowdata=array_combine($fieldorders,$fieldcontents);
unset($conditionrowdata["cid"]); unset($conditionrowdata["cid"]);
@ -4203,7 +4187,7 @@ function XMLImportSurvey($sFullFilePath,$sXMLdata=NULL,$sNewSurveyName=NULL,$iDe
$insertdata['sid']=$iNewSID; // remap the survey id $insertdata['sid']=$iNewSID; // remap the survey id
if (isset($insertdata['targetsqid']) && $insertdata['targetsqid']!='') if (isset($insertdata['targetsqid']) && $insertdata['targetsqid']!='')
{ {
$insertdata['targetsqid'] =$aSQIDReplacements[(int)$insertdata['targetsqid']]; // remap the qid $insertdata['targetsqid'] =$aQIDReplacements[(int)$insertdata['targetsqid']]; // remap the qid
} }
if (isset($insertdata['targetqid']) && $insertdata['targetqid']!='') if (isset($insertdata['targetqid']) && $insertdata['targetqid']!='')
{ {
@ -4215,7 +4199,7 @@ function XMLImportSurvey($sFullFilePath,$sXMLdata=NULL,$sNewSurveyName=NULL,$iDe
} }
} }
// Set survey rights // Set survey permissions
Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'],$iNewSID); Permission::model()->giveAllSurveyPermissions(Yii::app()->session['loginID'],$iNewSID);
$aOldNewFieldmap=reverseTranslateFieldNames($iOldSID,$iNewSID,$aGIDReplacements,$aQIDReplacements); $aOldNewFieldmap=reverseTranslateFieldNames($iOldSID,$iNewSID,$aGIDReplacements,$aQIDReplacements);
$results['FieldReMap']=$aOldNewFieldmap; $results['FieldReMap']=$aOldNewFieldmap;
@ -4328,7 +4312,10 @@ function XMLImportTokens($sFullFilePath,$iSurveyID,$sCreateMissingAttributeField
$results['tokens']++; $results['tokens']++;
} }
switchMSSQLIdentityInsert('tokens_'.$iSurveyID,false); switchMSSQLIdentityInsert('tokens_'.$iSurveyID,false);
if (Yii::app()->db->getDriverName() == 'pgsql')
{
try {Yii::app()->db->createCommand("SELECT pg_catalog.setval(pg_get_serial_sequence('{{tokens_".$iSurveyID."}}', 'tid'), (SELECT MAX(tid) FROM {{tokens_".$iSurveyID."}}))")->execute();} catch(Exception $oException){};
}
return $results; return $results;
} }
@ -4389,7 +4376,10 @@ function XMLImportResponses($sFullFilePath,$iSurveyID,$aFieldReMap=array())
} }
switchMSSQLIdentityInsert('survey_'.$iSurveyID,false); switchMSSQLIdentityInsert('survey_'.$iSurveyID,false);
if (Yii::app()->db->getDriverName() == 'pgsql')
{
try {Yii::app()->db->createCommand("SELECT pg_catalog.setval(pg_get_serial_sequence('{{survey_".$iSurveyID."}}', 'id'), (SELECT MAX(id) FROM {{survey_".$iSurveyID."}}))")->execute();} catch(Exception $oException){};
}
return $results; return $results;
} }
@ -4510,6 +4500,7 @@ function CSVImportResponses($sFullFilePath,$iSurveyId,$aOptions=array())
$aResponsesError=array(); $aResponsesError=array();
$aExistingsId=array(); $aExistingsId=array();
$iMaxId=0; // If we set the id, keep the max
// Some specific header (with options) // Some specific header (with options)
$iIdKey=array_search('id', $aCsvHeader); // the id is allways needed and used a lot $iIdKey=array_search('id', $aCsvHeader); // the id is allways needed and used a lot
if(is_int($iIdKey)){unset($aKeyForFieldNames['id']);} if(is_int($iIdKey)){unset($aKeyForFieldNames['id']);}
@ -4565,6 +4556,7 @@ function CSVImportResponses($sFullFilePath,$iSurveyId,$aOptions=array())
if(!$bExistingsId) // If not exist : allways import it if(!$bExistingsId) // If not exist : allways import it
{ {
$oSurvey->id=$aResponses[$iIdKey]; $oSurvey->id=$aResponses[$iIdKey];
$iMaxId=($aResponses[$iIdKey]>$iMaxId)?$aResponses[$iIdKey]:$iMaxId;
} }
elseif($aOptions['sExistingId']=='replace' || $aOptions['sExistingId']=='replaceanswers')// Set it depending with some options elseif($aOptions['sExistingId']=='replace' || $aOptions['sExistingId']=='replaceanswers')// Set it depending with some options
{ {
@ -4597,6 +4589,11 @@ function CSVImportResponses($sFullFilePath,$iSurveyId,$aOptions=array())
$oTransaction = Yii::app()->db->beginTransaction(); $oTransaction = Yii::app()->db->beginTransaction();
try try
{ {
if (isset($oSurvey->id) && !is_null($oSurvey->id))
{
switchMSSQLIdentityInsert('survey_'.$iSurveyId, true);
$bSwitched=true;
}
if($oSurvey->save()) if($oSurvey->save())
{ {
$oTransaction->commit(); $oTransaction->commit();
@ -4614,6 +4611,10 @@ function CSVImportResponses($sFullFilePath,$iSurveyId,$aOptions=array())
$oTransaction->rollBack(); $oTransaction->rollBack();
$aResponsesError[]=$aResponses[$iIdReponsesKey]; $aResponsesError[]=$aResponses[$iIdReponsesKey];
} }
if (isset($bSwitched) && $bSwitched==true){
switchMSSQLIdentityInsert('survey_'.$iSurveyId, false);
$bSwitched=false;
}
} }
catch(Exception $oException) catch(Exception $oException)
{ {
@ -4626,6 +4627,19 @@ function CSVImportResponses($sFullFilePath,$iSurveyId,$aOptions=array())
} }
} }
// Fix max next id (for pgsql)
// mysql dot need fix, but what for mssql ?
// Do a model function for this can be a good idea (see activate_helper/activateSurvey)
if (Yii::app()->db->driverName=='pgsql')
{
$sSequenceName= Yii::app()->db->getSchema()->getTable("{{survey_{$iSurveyId}}}")->sequenceName;
$iActualSerial=Yii::app()->db->createCommand("SELECT last_value FROM {$sSequenceName}")->queryScalar();
if($iActualSerial<$iMaxId)
{
$sQuery = "SELECT setval(pg_get_serial_sequence('{{survey_{$iSurveyId}}}', 'id'),{$iMaxId},false);";
$result = @Yii::app()->db->createCommand($sQuery)->execute();
}
}
// End of import // End of import
// Construction of returned information // Construction of returned information
@ -4850,7 +4864,7 @@ function TSVImportSurvey($sFullFilePath)
$surveyinfo['active']='N'; $surveyinfo['active']='N';
// unset($surveyinfo['datecreated']); // unset($surveyinfo['datecreated']);
$iNewSID = Survey::model()->insertNewSurvey($surveyinfo) ; //or safeDie($clang->gT("Error").": Failed to insert survey<br />"); $iNewSID = Survey::model()->insertNewSurvey($surveyinfo) ; //or safeDie($clang->gT("Error").": Failed to insert survey<br />");
if ($iNewSID==false) if (!$iNewSID)
{ {
$results['error'] = Survey::model()->getErrors(); $results['error'] = Survey::model()->getErrors();
$results['bFailed'] = true; $results['bFailed'] = true;
@ -4969,7 +4983,7 @@ function TSVImportSurvey($sFullFilePath)
$insertdata['help'] = (isset($row['help']) ? $row['help'] : ''); $insertdata['help'] = (isset($row['help']) ? $row['help'] : '');
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang); $insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
$insertdata['mandatory'] = (isset($row['mandatory']) ? $row['mandatory'] : ''); $insertdata['mandatory'] = (isset($row['mandatory']) ? $row['mandatory'] : '');
$insertdata['other'] = (isset($row['other']) ? $row['other'] : 'N'); $lastother = $insertdata['other'] = (isset($row['other']) ? $row['other'] : 'N'); // Keep trace of other settings for sub question
$insertdata['same_default'] = (isset($row['same_default']) ? $row['same_default'] : 0); $insertdata['same_default'] = (isset($row['same_default']) ? $row['same_default'] : 0);
$insertdata['parent_qid'] = 0; $insertdata['parent_qid'] = 0;
@ -5062,17 +5076,17 @@ function TSVImportSurvey($sFullFilePath)
$results['defaultvalues']++; $results['defaultvalues']++;
} }
break; break;
case 'SQ': case 'SQ':
$sqname = (isset($row['name']) ? $row['name'] : 'SQ' . $sqseq); $sqname = (isset($row['name']) ? $row['name'] : 'SQ' . $sqseq);
if ($qtype == 'O' || $qtype == '|') if ($qtype == 'O' || $qtype == '|')
{ {
; // these are fake rows to show naming of comment and filecount fields ; // these are fake rows to show naming of comment and filecount fields
} }
elseif ($sqname == 'other' && ($qtype == '!' || $qtype == 'L')) elseif ($sqname == 'other' && $lastother=="Y") // If last question have other to Y : it's not a real SQ row
{
if($qtype=="!" || $qtype=="L")
{ {
// only want to set default value for 'other' in these cases - not a real SQ row // only used to set default value for 'other' in these cases
// TODO - this isn't working
if (isset($row['default'])) if (isset($row['default']))
{ {
$insertdata=array(); $insertdata=array();
@ -5081,12 +5095,14 @@ function TSVImportSurvey($sFullFilePath)
$insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang); $insertdata['language'] = (isset($row['language']) ? $row['language'] : $baselang);
$insertdata['defaultvalue'] = $row['default']; $insertdata['defaultvalue'] = $row['default'];
$result = DefaultValue::model()->insertRecords($insertdata); $result = DefaultValue::model()->insertRecords($insertdata);
if(!$result){ if(!$result)
{
$results['importwarnings'][] = $clang->gT("Warning")." : ".$clang->gT("Failed to insert default value").". ".$clang->gT("Text file row number ").$rownumber; $results['importwarnings'][] = $clang->gT("Warning")." : ".$clang->gT("Failed to insert default value").". ".$clang->gT("Text file row number ").$rownumber;
break; break;
} }
$results['defaultvalues']++; $results['defaultvalues']++;
} }
}
} }
else else
{ {

View file

@ -200,12 +200,13 @@ function createChart($iQuestionID, $iSurveyID, $type=null, $lbl, $gdata, $grawda
if ($legendsize[1]<320) $gheight=420; else $gheight=$legendsize[1]+100; if ($legendsize[1]<320) $gheight=420; else $gheight=$legendsize[1]+100;
$graph = new pChart(690+$legendsize[0],$gheight); $graph = new pChart(690+$legendsize[0],$gheight);
$graph->drawFilledRectangle(0,0,690+$legendsize[0],$gheight,254,254,254,false);
$graph->loadColorPalette($homedir.DIRECTORY_SEPARATOR.'styles'.DIRECTORY_SEPARATOR.$admintheme.DIRECTORY_SEPARATOR.'limesurvey.pal'); $graph->loadColorPalette($homedir.DIRECTORY_SEPARATOR.'styles'.DIRECTORY_SEPARATOR.$admintheme.DIRECTORY_SEPARATOR.'limesurvey.pal');
$graph->setFontProperties($rootdir.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile,$chartfontsize); $graph->setFontProperties($rootdir.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile,$chartfontsize);
$graph->setGraphArea(50,30,500,$gheight-60); $graph->setGraphArea(50,30,500,$gheight-60);
$graph->drawFilledRoundedRectangle(7,7,523+$legendsize[0],$gheight-7,5,254,255,254); $graph->drawFilledRoundedRectangle(7,7,523+$legendsize[0],$gheight-7,5,254,255,254);
$graph->drawRoundedRectangle(5,5,525+$legendsize[0],$gheight-5,5,230,230,230); $graph->drawRoundedRectangle(5,5,525+$legendsize[0],$gheight-5,5,230,230,230);
$graph->drawGraphArea(255,255,255,TRUE); $graph->drawGraphArea(254,254,254,TRUE);
$graph->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_START0,150,150,150,TRUE,90,0,TRUE,5,false); $graph->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_START0,150,150,150,TRUE,90,0,TRUE,5,false);
$graph->drawGrid(4,TRUE,230,230,230,50); $graph->drawGrid(4,TRUE,230,230,230,50);
// Draw the 0 line // Draw the 0 line
@ -217,7 +218,7 @@ function createChart($iQuestionID, $iSurveyID, $type=null, $lbl, $gdata, $grawda
//$Test->setLabel($DataSet->GetData(),$DataSet->GetDataDescription(),"Serie4","1","Important point!"); //$Test->setLabel($DataSet->GetData(),$DataSet->GetDataDescription(),"Serie4","1","Important point!");
// Finish the graph // Finish the graph
$graph->setFontProperties($rootdir.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile, $chartfontsize); $graph->setFontProperties($rootdir.DIRECTORY_SEPARATOR.'fonts'.DIRECTORY_SEPARATOR.$chartfontfile, $chartfontsize);
$graph->drawLegend(510,30,$DataSet->GetDataDescription(),255,255,255); $graph->drawLegend(510,30,$DataSet->GetDataDescription(),250,250,250);
$cache->WriteToCache("graph".$iSurveyID.$language.$iQuestionID,$DataSet->GetData(),$graph); $cache->WriteToCache("graph".$iSurveyID.$language.$iQuestionID,$DataSet->GetData(),$graph);
$cachefilename=basename($cache->GetFileFromCache("graph".$iSurveyID.$language.$iQuestionID,$DataSet->GetData())); $cachefilename=basename($cache->GetFileFromCache("graph".$iSurveyID.$language.$iQuestionID,$DataSet->GetData()));
@ -292,6 +293,7 @@ function createChart($iQuestionID, $iSurveyID, $type=null, $lbl, $gdata, $grawda
$gheight=ceil($gheight); $gheight=ceil($gheight);
$graph = new pChart(690,$gheight); $graph = new pChart(690,$gheight);
$graph->drawFilledRectangle(0,0,690,$gheight,254,254,254,false);
$graph->loadColorPalette($homedir.'/styles/'.$admintheme.'/limesurvey.pal'); $graph->loadColorPalette($homedir.'/styles/'.$admintheme.'/limesurvey.pal');
$graph->drawFilledRoundedRectangle(7,7,687,$gheight-3,5,254,255,254); $graph->drawFilledRoundedRectangle(7,7,687,$gheight-3,5,254,255,254);
$graph->drawRoundedRectangle(5,5,689,$gheight-1,5,230,230,230); $graph->drawRoundedRectangle(5,5,689,$gheight-1,5,230,230,230);
@ -2362,7 +2364,7 @@ class statistics_helper {
$this->sheet->writeNumber($this->xlsRow,1,$grawdata[$i]); $this->sheet->writeNumber($this->xlsRow,1,$grawdata[$i]);
$this->sheet->writeNumber($this->xlsRow,2,$percentage/100, $this->xlsPercents); $this->sheet->writeNumber($this->xlsRow,2,$percentage/100, $this->xlsPercents);
if ($aggregatedPercentage !== 'na') { if ($aggregatedPercentage !== 'na') {
$this->sheet->writeNumber($this->xlsRow,3,$percentage/100, $this->xlsPercents); $this->sheet->writeNumber($this->xlsRow,3,$aggregatedPercentage/100, $this->xlsPercents);
} }
break; break;

View file

@ -46,6 +46,34 @@ function createTokenTable($iSurveyID, $aAttributeFields=array())
{ {
$fields[$sAttributeField]='string'; $fields[$sAttributeField]='string';
} }
if (Yii::app()->db->driverName=='mssql' || Yii::app()->db->driverName=='sqlsrv' || Yii::app()->db->driverName=='dblib')
{
$fields = array(
'tid' => 'pk',
'participant_id' => 'varchar(50)',
'firstname' => 'nvarchar(40)',
'lastname' => 'nvarchar(40)',
'email' => 'ntext',
'emailstatus' => 'ntext',
'token' => 'varchar(35)',
'language' => 'varchar(25)',
'blacklisted' => 'varchar(17)',
'sent' => "varchar(17) DEFAULT 'N'",
'remindersent' => "varchar(17) DEFAULT 'N'",
'remindercount' => 'integer DEFAULT 0',
'completed' => "varchar(17) DEFAULT 'N'",
'usesleft' => 'integer DEFAULT 1',
'validfrom' => 'datetime',
'validuntil' => 'datetime',
'mpid' => 'integer'
);
foreach ($aAttributeFields as $sAttributeField)
{
$fields[$sAttributeField]='nvarchar(255)';
}
}
try{ try{
$sTableName="{{tokens_".intval($iSurveyID)."}}"; $sTableName="{{tokens_".intval($iSurveyID)."}}";
createTable($sTableName, $fields); createTable($sTableName, $fields);

View file

@ -12,22 +12,6 @@
*/ */
Yii::import('application.helpers.sanitize_helper', true); Yii::import('application.helpers.sanitize_helper', true);
/**
* Simple function to sort the permissions by title
*
* @param mixed $aPermissionA Permission A to compare
* @param mixed $aPermissionB Permission B to compare
*/
function comparePermission($aPermissionA,$aPermissionB)
{
if($aPermissionA['title'] >$aPermissionB['title']) {
return 1;
}
else {
return -1;
}
}
/** /**
* Translation helper function. * Translation helper function.
* @param string $string * @param string $string
@ -151,12 +135,8 @@ function getSurveyList($returnarray=false, $surveyid=false)
if(is_null($cached)) { if(is_null($cached)) {
$args = array('order'=>'surveyls_title'); $args = array('order'=>'surveyls_title');
if (!Permission::model()->hasGlobalPermission('superadmin','read')) $surveyidresult = Survey::model()->permission(Yii::app()->user->getId())->with('defaultlanguage')->findAll($args);
{
$surveyidresult = Survey::model()->permission(Yii::app()->user->getId())->with(array('languagesettings'=>array('condition'=>'surveyls_language=language')))->findAll($args);
} else {
$surveyidresult = Survey::model()->with(array('languagesettings'=>array('condition'=>'surveyls_language=language')))->findAll($args);
}
$surveynames = array(); $surveynames = array();
foreach ($surveyidresult as $result) foreach ($surveyidresult as $result)
@ -1630,6 +1610,29 @@ function validateEmailAddress($sEmailAddress){
return false; return false;
} }
/**
* Validate an list of email addresses - either as array or as semicolon-limited text
* @returns List with valid email addresses - invalid email addresses are filtered - false if none of the email addresses are valid
*
* @param mixed $sEmailAddresses Email address to check
*/
function validateEmailAddresses($aEmailAddressList){
$aOutList=false;
if (!is_array($aEmailAddressList))
{
$aEmailAddressList=explode(';',$aEmailAddressList);
}
foreach ($aEmailAddressList as $sEmailAddress)
{
$sEmailAddress= trim($sEmailAddress);
if (validateEmailAddress($sEmailAddress)){
$aOutList=$sEmailAddress;
}
}
return $aOutList;
}
function validateTemplateDir($sTemplateName) function validateTemplateDir($sTemplateName)
{ {
$usertemplaterootdir = Yii::app()->getConfig('usertemplaterootdir'); $usertemplaterootdir = Yii::app()->getConfig('usertemplaterootdir');
@ -1793,8 +1796,7 @@ return $allfields;
* @param string $sQuestionLanguage The language to use * @param string $sQuestionLanguage The language to use
* @return array * @return array
*/ */
function createFieldMap($surveyid, $style='short', $force_refresh=false, $questionid=false, $sLanguage) { function createFieldMap($surveyid, $style='short', $force_refresh=false, $questionid=false, $sLanguage, &$aDuplicateQIDs=array()) {
global $aDuplicateQIDs;
$sLanguage = sanitize_languagecode($sLanguage); $sLanguage = sanitize_languagecode($sLanguage);
$surveyid = sanitize_int($surveyid); $surveyid = sanitize_int($surveyid);
@ -1837,12 +1839,6 @@ function createFieldMap($surveyid, $style='short', $force_refresh=false, $questi
$fieldmap["startlanguage"]['group_name']=""; $fieldmap["startlanguage"]['group_name']="";
} }
// Select which question IDs have default values
$_aDefaultValues = DefaultValue::model()->with(array('question' => array('condition' => 'question.sid=' . $surveyid)))->findAll();
$aDefaultValues = array();
foreach ($_aDefaultValues as $k => $v)
$aDefaultValues[] = $v->qid;
//Check for any additional fields for this survey and create necessary fields (token and datestamp and ipaddr) //Check for any additional fields for this survey and create necessary fields (token and datestamp and ipaddr)
$prow = Survey::model()->findByPk($surveyid)->getAttributes(); //Checked $prow = Survey::model()->findByPk($surveyid)->getAttributes(); //Checked
@ -3415,7 +3411,7 @@ function questionAttributes($returnByName=false)
'category'=>$clang->gT('Slider'), 'category'=>$clang->gT('Slider'),
'sortorder'=>10, 'sortorder'=>10,
'inputtype'=>'text', 'inputtype'=>'text',
"help"=>$clang->gT('Slider minimum value'), "help"=>$clang->gT('You can use Expression manager, but this must be a number before showing the page else set to 0. If minimum value is not set, this value is used.'),
"caption"=>$clang->gT('Slider minimum value')); "caption"=>$clang->gT('Slider minimum value'));
$qattributes["slider_max"]=array( $qattributes["slider_max"]=array(
@ -3423,7 +3419,7 @@ function questionAttributes($returnByName=false)
'category'=>$clang->gT('Slider'), 'category'=>$clang->gT('Slider'),
'sortorder'=>11, 'sortorder'=>11,
'inputtype'=>'text', 'inputtype'=>'text',
"help"=>$clang->gT('Slider maximum value'), "help"=>$clang->gT('You can use Expression manager, but this must be a number before showing the page else set to 100. If maximum value is not set, this value is used.'),
"caption"=>$clang->gT('Slider maximum value')); "caption"=>$clang->gT('Slider maximum value'));
$qattributes["slider_accuracy"]=array( $qattributes["slider_accuracy"]=array(
@ -3431,7 +3427,7 @@ function questionAttributes($returnByName=false)
'category'=>$clang->gT('Slider'), 'category'=>$clang->gT('Slider'),
'sortorder'=>30, 'sortorder'=>30,
'inputtype'=>'text', 'inputtype'=>'text',
"help"=>$clang->gT('Slider accuracy'), "help"=>$clang->gT('You can use Expression manager, but this must be a number before showing the page else set to 1.'),
"caption"=>$clang->gT('Slider accuracy')); "caption"=>$clang->gT('Slider accuracy'));
$qattributes["slider_default"]=array( $qattributes["slider_default"]=array(
@ -3439,7 +3435,7 @@ function questionAttributes($returnByName=false)
'category'=>$clang->gT('Slider'), 'category'=>$clang->gT('Slider'),
'sortorder'=>50, 'sortorder'=>50,
'inputtype'=>'text', 'inputtype'=>'text',
"help"=>$clang->gT('Slider start as this value (this will set the initial value).'), "help"=>$clang->gT('Slider start as this value (this will set the initial value). You can use Expression manager, but this must be a number before showing the page.'),
"caption"=>$clang->gT('Slider initial value')); "caption"=>$clang->gT('Slider initial value'));
$qattributes["slider_middlestart"]=array( $qattributes["slider_middlestart"]=array(
@ -3817,7 +3813,7 @@ function questionAttributes($returnByName=false)
'category'=>$clang->gT('Other'), 'category'=>$clang->gT('Other'),
'sortorder'=>134, 'sortorder'=>134,
"inputtype"=>"text", "inputtype"=>"text",
'default'=>"png, gif, doc, odt", 'default'=>"png, gif, jpg, doc, odt",
"help"=>$clang->gT("Allowed file types in comma separated format. e.g. pdf,doc,odt"), "help"=>$clang->gT("Allowed file types in comma separated format. e.g. pdf,doc,odt"),
"caption"=>$clang->gT("Allowed file types")); "caption"=>$clang->gT("Allowed file types"));
@ -3883,14 +3879,6 @@ function categorySort($a, $b)
return $result; return $result;
} }
// make sure the given string (which comes from a POST or GET variable)
// is safe to use in MySQL. This does nothing if gpc_magic_quotes is on.
function autoEscape($str) {
if (!get_magic_quotes_gpc()) {
return addslashes ($str);
}
return $str;
}
// the opposite of the above: takes a POST or GET variable which may or // the opposite of the above: takes a POST or GET variable which may or
// may not have been 'auto-quoted', and return the *unquoted* version. // may not have been 'auto-quoted', and return the *unquoted* version.
@ -4426,13 +4414,6 @@ function CSVEscape($sString)
return '"' . str_replace('"','""', $sString) . '"'; return '"' . str_replace('"','""', $sString) . '"';
} }
function convertCSVRowToArray($string, $separator, $quotechar)
{
$fields=preg_split('/' . $separator . '(?=([^"]*"[^"]*")*(?![^"]*"))/',trim($string));
$fields=array_map('CSVUnquote',$fields);
return $fields;
}
function createPassword() function createPassword()
{ {
$aCharacters = "ABCDEGHJIKLMNOPQURSTUVWXYZabcdefhjmnpqrstuvwxyz23456789"; $aCharacters = "ABCDEGHJIKLMNOPQURSTUVWXYZabcdefhjmnpqrstuvwxyz23456789";
@ -4769,7 +4750,7 @@ function translateLinks($sType, $iOldSurveyID, $iNewSurveyID, $sString)
$replace = Yii::app()->getConfig("publicurl")."upload/labels/{$iNewSurveyID}/"; $replace = Yii::app()->getConfig("publicurl")."upload/labels/{$iNewSurveyID}/";
return preg_replace('#'.$pattern.'#', $replace, $sString); return preg_replace('#'.$pattern.'#', $replace, $sString);
} }
else // unkown type else // unknown type
{ {
return $sString; return $sString;
} }
@ -5487,17 +5468,17 @@ function enforceSSLMode()
* *
* @param int $iSurveyId - Survey identification number * @param int $iSurveyId - Survey identification number
* @param int $quotaid - quota id for which you want to compute the completed field * @param int $quotaid - quota id for which you want to compute the completed field
* @return mixed - Integer of matching entries in the result DB or 'N/A' * @return string - Integer of matching entries in the result DB or 'N/A'
*/ */
function getQuotaCompletedCount($iSurveyId, $quotaid) function getQuotaCompletedCount($iSurveyId, $quotaid)
{ {
$result = "N/A"; $result = "N/A";
if(!tableExists("survey_{$iSurveyId}")) // Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}' are not updated even after Yii::app()->db->schema->refresh(); if(!tableExists("survey_{$iSurveyId}")) // Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}' are not updated even after Yii::app()->db->schema->refresh();
return $result; return $result;
$aColumnName=SurveyDynamic::model($iSurveyId)->getTableSchema()->getColumnNames();
$quota_info = getQuotaInformation($iSurveyId, Survey::model()->findByPk($iSurveyId)->language, $quotaid); $quota_info = getQuotaInformation($iSurveyId, Survey::model()->findByPk($iSurveyId)->language, $quotaid);
$quota = $quota_info[0]; $quota = $quota_info[0];
if (Yii::app()->db->schema->getTable('{{survey_' . $iSurveyId . '}}') && if (count($quota['members']) > 0) // Existence of table already tested
count($quota['members']) > 0)
{ {
// Keep a list of fields for easy reference // Keep a list of fields for easy reference
$fields_list = array(); $fields_list = array();
@ -5507,26 +5488,28 @@ function getQuotaCompletedCount($iSurveyId, $quotaid)
foreach ($quota['members'] as $member) foreach ($quota['members'] as $member)
{ {
$criteria = new CDbCriteria; if(in_array($member['fieldname'],$aColumnName))
$fields_list[$member['fieldname']][] = $member['value'];
foreach ($member['fieldnames'] as $fieldname) else
{ return $result;// We return N/A even for activated survey : $member['fieldname'] don't exist anymore (deleted question for example)
if (!in_array($fieldname, $fields_list))
$fields_list[] = $fieldname;
// Yii does not quote column names (duh!) so we have to do it.
$criteria->addColumnCondition(array(Yii::app()->db->quoteColumnName($fieldname) => $member['value']), 'OR');
}
$fields_query[$fieldname] = $criteria;
} }
$criteria = new CDbCriteria; $criteria = new CDbCriteria;
$criteria->condition="submitdate IS NOT NULL";
foreach ($fields_list as $fieldname) foreach ($fields_list as $fieldname=>$aValue)
$criteria->mergeWith($fields_query[$fieldname]); {
$criteria->mergeWith(array('condition'=>"submitdate IS NOT NULL")); if(count($aValue)==1)
$result = SurveyDynamic::model($iSurveyId)->count($criteria); {
$criteria->compare(Yii::app()->db->quoteColumnName($fieldname),$aValue[0]);// NO need params
}
else
{
$criteria->addInCondition(Yii::app()->db->quoteColumnName($fieldname),$aValue); // NO need params : addInCondition bind automatically
}
}
// Ensure to return a string, Yii count return a string (see http://www.yiiframework.com/doc/api/1.1/CActiveRecord#count-detail)
// But seems under certain condition, count return integer see http://bugs.limesurvey.org/view.php?id=9587#c31917
$result = strval(SurveyDynamic::model($iSurveyId)->count($criteria));
} }
return $result; return $result;
@ -5609,16 +5592,16 @@ function getFullResponseTable($iSurveyID, $iResponseID, $sLanguageCode, $bHonorC
continue; continue;
} }
if (isset($fname['subquestion'])) if (isset($fname['subquestion']))
$subquestion = "{$fname['subquestion']}"; $subquestion = "[{$fname['subquestion']}]";
if (isset($fname['subquestion1'])) if (isset($fname['subquestion1']))
$subquestion = "{$fname['subquestion1']}"; $subquestion = "[{$fname['subquestion1']}]";
if (isset($fname['subquestion2'])) if (isset($fname['subquestion2']))
$subquestion .= "[{$fname['subquestion2']}]"; $subquestion .= "[{$fname['subquestion2']}]";
$answer = getExtendedAnswer($iSurveyID,$fname['fieldname'], $idrow[$fname['fieldname']],$oLanguage); $answer = getExtendedAnswer($iSurveyID,$fname['fieldname'], $idrow[$fname['fieldname']],$oLanguage);
$aResultTable[$fname['fieldname']]=array('',$subquestion,$answer); $aResultTable[$fname['fieldname']]=array($question,$subquestion,$answer);
} }
return $aResultTable; return $aResultTable;
} }
@ -5638,6 +5621,61 @@ function isNumericInt($mStr)
} }
/**
* Implode and sort content array for very long arrays
*
* @param string $sDelimeter
* @param array $aArray
* @return string String showing array content
*/
function short_implode($sDelimeter, $sHyphen, $aArray)
{
if (sizeof($aArray) < Yii::app()->getConfig('minlengthshortimplode'))
{
sort($aArray);
return implode($sDelimeter, $aArray);
}
else
{
sort($aArray);
$iIndexA = 0;
$iIndexB = 1;
while ($iIndexA < sizeof($aArray))
{
if ($iIndexA == 0)
{
$sResult = $aArray[$iIndexA];
}
else
{
if (strlen($sResult) > Yii::app()->getConfig('maxstringlengthshortimplode') - strlen($sDelimeter) - 3)
{
return $sResult.$sDelimeter.'...';
}
else
{
$sResult = $sResult.$sDelimeter.$aArray[$iIndexA];
}
}
$iIndexB = $iIndexA+1;
if ($iIndexB < sizeof($aArray))
{
while ($iIndexB < sizeof($aArray) && $aArray[$iIndexB] - 1 == $aArray[$iIndexB-1])
{
$iIndexB++;
}
if ($iIndexA < $iIndexB - 1)
{
$sResult = $sResult.$sHyphen.$aArray[$iIndexB-1];
}
}
$iIndexA = $iIndexB;
}
return $sResult;
}
}
/** /**
* Include Keypad headers * Include Keypad headers
*/ */
@ -5664,7 +5702,6 @@ function includeKeypad()
function getQuotaInformation($surveyid,$language,$iQuotaID='all') function getQuotaInformation($surveyid,$language,$iQuotaID='all')
{ {
Yii::log('getQuotaInformation'); Yii::log('getQuotaInformation');
global $clienttoken;
$baselang = Survey::model()->findByPk($surveyid)->language; $baselang = Survey::model()->findByPk($surveyid)->language;
$aAttributes=array('sid' => $surveyid); $aAttributes=array('sid' => $surveyid);
if ($iQuotaID != 'all') if ($iQuotaID != 'all')
@ -5687,18 +5724,8 @@ function getQuotaInformation($surveyid,$language,$iQuotaID='all')
foreach ($result as $_survey_quotas) foreach ($result as $_survey_quotas)
{ {
$survey_quotas = array_merge($_survey_quotas->attributes,$_survey_quotas->languagesettings[0]->attributes);// We have only one language, then we can use first only $survey_quotas = array_merge($_survey_quotas->attributes,$_survey_quotas->languagesettings[0]->attributes);// We have only one language, then we can use first only
// !!! Doubting this
# foreach ($_survey_quotas->defaultlanguage as $k => $v)
# $survey_quotas[$k] = $v;
array_push($quota_info,array('Name' => $survey_quotas['name'],
'Limit' => $survey_quotas['qlimit'],
'Action' => $survey_quotas['action'],
'Message' => $survey_quotas['quotals_message'],
'Url' => $survey_quotas['quotals_url'],
'UrlDescrip' => $survey_quotas['quotals_urldescrip'],
'AutoloadUrl' => $survey_quotas['autoload_url']));
array_push($quota_info,$survey_quotas);
$result_qe = QuotaMember::model()->findAllByAttributes(array('quota_id'=>$survey_quotas['id'])); $result_qe = QuotaMember::model()->findAllByAttributes(array('quota_id'=>$survey_quotas['id']));
$quota_info[$x]['members'] = array(); $quota_info[$x]['members'] = array();
if (count($result_qe) > 0) if (count($result_qe) > 0)
@ -5706,42 +5733,47 @@ function getQuotaInformation($surveyid,$language,$iQuotaID='all')
foreach ($result_qe as $quota_entry) foreach ($result_qe as $quota_entry)
{ {
$quota_entry = $quota_entry->attributes; $quota_entry = $quota_entry->attributes;
$result_quest=Question::model()->findByAttributes(array('qid'=>$quota_entry['qid'], 'language'=>$baselang)); $oMemberQuestion=Question::model()->findByAttributes(array('qid'=>$quota_entry['qid'], 'language'=>$baselang));
$qtype=$result_quest->attributes; if($oMemberQuestion)
$fieldnames = "0";
if ($qtype['type'] == "I" || $qtype['type'] == "G" || $qtype['type'] == "Y")
{ {
$fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid']); $fieldname = "0";
$value = $quota_entry['code'];
}
if($qtype['type'] == "L" || $qtype['type'] == "O" || $qtype['type'] =="!") if ($oMemberQuestion->type == "I" || $oMemberQuestion->type == "G" || $oMemberQuestion->type == "Y")
{ {
$fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid']); $fieldname= $surveyid.'X'.$oMemberQuestion->gid.'X'.$quota_entry['qid'];
$value = $quota_entry['code']; $value = $quota_entry['code'];
} }
if($qtype['type'] == "M") if($oMemberQuestion->type == "L" || $oMemberQuestion->type == "O" || $oMemberQuestion->type =="!")
{ {
$fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid'].$quota_entry['code']); $fieldname=$surveyid.'X'.$oMemberQuestion->gid.'X'.$quota_entry['qid'];
$value = "Y"; $value = $quota_entry['code'];
} }
if($qtype['type'] == "A" || $qtype['type'] == "B") if($oMemberQuestion->type == "M")
{ {
$temp = explode('-',$quota_entry['code']); // Need to remove invalid $quota_entry['code']
$fieldnames=array(0 => $surveyid.'X'.$qtype['gid'].'X'.$quota_entry['qid'].$temp[0]); $fieldname=$surveyid.'X'.$oMemberQuestion->gid.'X'.$quota_entry['qid'].$quota_entry['code'];
$value = $temp[1]; $value = "Y";
} }
array_push($quota_info[$x]['members'],array('Title' => $qtype['title'], if($oMemberQuestion->type == "A" || $oMemberQuestion->type == "B")
'type' => $qtype['type'], {
'code' => $quota_entry['code'], $temp = explode('-',$quota_entry['code']);
'value' => $value, $fieldname=$surveyid.'X'.$oMemberQuestion->gid.'X'.$quota_entry['qid'].$temp[0];
'qid' => $quota_entry['qid'], $value = $temp[1];
'fieldnames' => $fieldnames)); }
array_push($quota_info[$x]['members'],array(
'Title' => $oMemberQuestion->title,
'type' => $oMemberQuestion->type,
'code' => $quota_entry['code'],
'value' => $value,
'qid' => $quota_entry['qid'],
'fieldname' => $fieldname
)
);
}
} }
} }
$x++; $x++;
@ -5966,9 +5998,9 @@ function replaceExpressionCodes ($iSurveyID, $aCodeMap)
if (strlen($sOldCode)>1 && !is_numeric($sOldCode[0])) if (strlen($sOldCode)>1 && !is_numeric($sOldCode[0]))
{ {
$sOldCode=preg_quote($sOldCode,'/'); $sOldCode=preg_quote($sOldCode,'/');
$arQuestion->relevance=preg_replace("/\b{$sOldCode}/",$sNewCode,$arQuestion->relevance,-1,$iCount); $arQuestion->relevance=preg_replace("~{[^}]*\K{$sOldCode}(?=[^}]*?})~",$sNewCode,$arQuestion->relevance,-1,$iCount);
$bModified = $bModified || $iCount; $bModified = $bModified || $iCount;
$arQuestion->question=preg_replace("/\b{$sOldCode}/",$sNewCode,$arQuestion->question,-1,$iCount); $arQuestion->question=preg_replace("~{[^}]*\K{$sOldCode}(?=[^}]*?})~",$sNewCode,$arQuestion->question,-1,$iCount);
$bModified = $bModified || $iCount; $bModified = $bModified || $iCount;
} }
} }
@ -5984,9 +6016,9 @@ function replaceExpressionCodes ($iSurveyID, $aCodeMap)
foreach ($aCodeMap as $sOldCode=>$sNewCode) foreach ($aCodeMap as $sOldCode=>$sNewCode)
{ {
$sOldCode=preg_quote($sOldCode,'/'); $sOldCode=preg_quote($sOldCode,'/');
$arGroup->grelevance=preg_replace("/\b{$sOldCode}/",$sNewCode,$arGroup->grelevance,-1,$iCount); $arGroup->grelevance=preg_replace("~{[^}]*\K{$sOldCode}(?=[^}]*?})~",$sNewCode,$arGroup->grelevance,-1,$iCount);
$bModified = $bModified || $iCount; $bModified = $bModified || $iCount;
$arGroup->description=preg_replace("/\b{$sOldCode}/",$sNewCode,$arGroup->description,-1,$iCount); $arGroup->description=preg_replace("~{[^}]*\K{$sOldCode}(?=[^}]*?})~",$sNewCode,$arGroup->description,-1,$iCount);
$bModified = $bModified || $iCount; $bModified = $bModified || $iCount;
} }
if ($bModified) if ($bModified)
@ -7109,7 +7141,7 @@ function doesImportArraySupportLanguage($csvarray,$idkeysarray,$langfieldnum,$l
foreach ($csvarray as $csvrow) foreach ($csvarray as $csvrow)
{ {
$rowcontents = convertCSVRowToArray($csvrow,',','"'); $rowcontents = str_getcsv($csvrow,',','"');
$rowid = ""; $rowid = "";
foreach ($idkeysarray as $idfieldnum) foreach ($idkeysarray as $idfieldnum)
{ {
@ -7248,16 +7280,32 @@ function getSurveyUserGroupList($outputformat='htmloptions',$surveyid)
/** /**
* This function fixes the group ID and type on all subquestions * This function fixes the group ID and type on all subquestions
* * Optimized for minimum memory usage even on huge databases
*/ */
function fixSubquestions() function fixSubquestions()
{ {
$surveyidresult=Yii::app()->db->createCommand("select sq.qid, sq.parent_qid, sq.gid as sqgid, q.gid, sq.type as sqtype, q.type $surveyidresult=Yii::app()->db->createCommand()
from {{questions}} sq JOIN {{questions}} q on sq.parent_qid=q.qid ->select('sq.qid, q.gid , q.type ')
where sq.parent_qid>0 and (sq.gid!=q.gid or sq.type!=q.type)")->query(); ->from('{{questions}} sq')
foreach($surveyidresult->readAll() as $sv) ->join('{{questions}} q','sq.parent_qid=q.qid')
->where('sq.parent_qid>0 AND (sq.gid!=q.gid or sq.type!=q.type)')
->limit(10000)
->query();
$aRecords=$surveyidresult->readAll();
while (count($aRecords)>0)
{ {
Yii::app()->db->createCommand("update {{questions}} set type='{$sv['type']}', gid={$sv['gid']} where qid={$sv['qid']}")->query(); foreach($aRecords as $sv)
{
Yii::app()->db->createCommand("update {{questions}} set type='{$sv['type']}', gid={$sv['gid']} where qid={$sv['qid']}")->execute();
}
$surveyidresult=Yii::app()->db->createCommand()
->select('sq.qid, q.gid , q.type ')
->from('{{questions}} sq')
->join('{{questions}} q','sq.parent_qid=q.qid')
->where('sq.parent_qid>0 AND (sq.gid!=q.gid or sq.type!=q.type)')
->limit(10000)
->query();
$aRecords=$surveyidresult->readAll();
} }
} }
@ -7267,6 +7315,10 @@ function fixSubquestions()
*/ */
function ls_json_encode($content) function ls_json_encode($content)
{ {
if (is_string($content) && get_magic_quotes_gpc())
{
$content=stripslashes($content);
}
$ans = json_encode($content); $ans = json_encode($content);
$ans = str_replace(array('{','}'),array('{ ',' }'), $ans); $ans = str_replace(array('{','}'),array('{ ',' }'), $ans);
return $ans; return $ans;
@ -7493,5 +7545,44 @@ function array_diff_assoc_recursive($array1, $array2) {
return min(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize'))); return min(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize')));
} }
/**
* Decodes token attribute data because due to bugs in the past it can be written in JSON or be serialized - future format should be JSON as serialized data can be exploited
*
* @param string $oTokenAttributeData The original token attributes as stored in the database
*/
function decodeTokenAttributes($oTokenAttributeData){
if (trim($oTokenAttributeData)=='') return array();
if (substr($oTokenAttributeData,0,1)!='{' && substr($oTokenAttributeData,0,1)!='[')
{
$sSerialType=getSerialClass($oTokenAttributeData);
if ($sSerialType=='array') // Safe to decode
{
$aReturnData=@unserialize($oTokenAttributeData);
}
else // Something else, might be unsafe
{
return array();
}
}
else
{
$aReturnData=@json_decode($oTokenAttributeData,true);
}
if ($aReturnData===false || $aReturnData===null) return array();
return $aReturnData;
}
/**
* Determines the data type of serialized data
*
* @param mixed $sSerial The serialized data to examine
*/
function getSerialClass($sSerial) {
$aTypes = array('s' => 'string', 'a' => 'array', 'b' => 'bool', 'i' => 'int', 'd' => 'float', 'N;' => 'NULL');
$aParts = explode(':', $sSerial, 4);
return isset($aTypes[$aParts[0]]) ? $aTypes[$aParts[0]] : ( isset($aParts[2]) ? trim($aParts[2], '"') : null);
}
// Closing PHP tag intentionally omitted - yes, it is okay // Closing PHP tag intentionally omitted - yes, it is okay

View file

@ -434,7 +434,8 @@ function SPSSFieldMap($iSurveyID, $prefix = 'V') {
$fieldtype = 'A'; $fieldtype = 'A';
$val_size = 255; $val_size = 255;
} elseif ($fieldname == 'lastpage') { } elseif ($fieldname == 'lastpage') {
$hide = 1; $fieldtype = 'F';
$val_size = 7; //Arbitrarilty restrict to 9,999,999 (7 digits) pages
} }
#Get qid (question id) #Get qid (question id)
@ -1506,10 +1507,12 @@ function concat()
function group_export($action, $iSurveyID, $gid) function group_export($action, $iSurveyID, $gid)
{ {
viewHelper::disableHtmlLogging();
$fn = "limesurvey_group_$gid.lsg"; $fn = "limesurvey_group_$gid.lsg";
$xml = getXMLWriter(); $xml = getXMLWriter();
header("Content-Type: text/html/force-download"); header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=$fn"); header("Content-Disposition: attachment; filename=$fn");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
@ -1611,7 +1614,7 @@ function questionExport($action, $iSurveyID, $gid, $qid)
$fn = "limesurvey_question_$qid.lsq"; $fn = "limesurvey_question_$qid.lsq";
$xml = getXMLWriter(); $xml = getXMLWriter();
header("Content-Type: text/html/force-download"); header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=$fn"); header("Content-Disposition: attachment; filename=$fn");
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
@ -1692,57 +1695,66 @@ function questionGetXMLStructure($xml,$gid,$qid)
function tokensExport($iSurveyID) function tokensExport($iSurveyID)
{ {
$sEmailFiter=trim(App()->request->getPost('filteremail'));
$iTokenStatus=App()->request->getPost('tokenstatus');
$iInvitationStatus=App()->request->getPost('invitationstatus');
$iReminderStatus=App()->request->getPost('reminderstatus');
$sTokenLanguage=App()->request->getPost('tokenlanguage');
$oSurvey=Survey::model()->findByPk($iSurveyID);
$bIsNotAnonymous= ($oSurvey->anonymized=='N' && $oSurvey->active=='Y');// db table exist (survey_$iSurveyID) ?
$bquery = "SELECT * FROM {{tokens_$iSurveyID}} where 1=1"; $bquery = "SELECT * FROM {{tokens_$iSurveyID}} where 1=1";
$databasetype = Yii::app()->db->getDriverName(); $databasetype = Yii::app()->db->getDriverName();
if (trim($_POST['filteremail'])!='') if ($sEmailFiter!='')
{ {
if (in_array($databasetype, array('mssql', 'sqlsrv', 'dblib'))) if (in_array($databasetype, array('mssql', 'sqlsrv', 'dblib')))
{ {
$bquery .= ' and CAST(email as varchar) like '.dbQuoteAll('%'.$_POST['filteremail'].'%', true); $bquery .= ' and CAST(email as varchar) like '.dbQuoteAll('%'.$sEmailFiter.'%', true);
} }
else else
{ {
$bquery .= ' and email like '.dbQuoteAll('%'.$_POST['filteremail'].'%', true); $bquery .= ' and email like '.dbQuoteAll('%'.$sEmailFiter.'%', true);
} }
} }
if ($_POST['tokenstatus']==1) if ($iTokenStatus==1)
{ {
$bquery .= " and completed<>'N'"; $bquery .= " and completed<>'N'";
} }
if ($_POST['tokenstatus']==2) elseif ($iTokenStatus==2)
{ {
$bquery .= " and completed='N'"; $bquery .= " and completed='N'";
if ($thissurvey['anonymized']=='N') if ($bIsNotAnonymous)
{ {
$bquery .=" and token not in (select token from {{survey_$iSurveyID}} group by token)"; $bquery .=" and token not in (select token from {{survey_$iSurveyID}} group by token)";
} }
} }
if ($_POST['tokenstatus']==3 && $thissurvey['anonymized']=='N') if ($iTokenStatus==3 && $bIsNotAnonymous)
{ {
$bquery .= " and completed='N' and token in (select token from {{survey_$iSurveyID}} group by token)"; $bquery .= " and completed='N' and token in (select token from {{survey_$iSurveyID}} group by token)";
} }
if ($_POST['invitationstatus']==1) if ($iInvitationStatus==1)
{ {
$bquery .= " and sent<>'N'"; $bquery .= " and sent<>'N'";
} }
if ($_POST['invitationstatus']==2) if ($iInvitationStatus==2)
{ {
$bquery .= " and sent='N'"; $bquery .= " and sent='N'";
} }
if ($_POST['reminderstatus']==1) if ($iReminderStatus==1)
{ {
$bquery .= " and remindersent<>'N'"; $bquery .= " and remindersent<>'N'";
} }
if ($_POST['reminderstatus']==2) if ($iReminderStatus==2)
{ {
$bquery .= " and remindersent='N'"; $bquery .= " and remindersent='N'";
} }
if ($_POST['tokenlanguage']!='') if ($sTokenLanguage!='')
{ {
$bquery .= " and language=".dbQuoteAll($_POST['tokenlanguage']); $bquery .= " and language=".dbQuoteAll($sTokenLanguage);
} }
$bquery .= " ORDER BY tid"; $bquery .= " ORDER BY tid";
Yii::app()->loadHelper('database'); Yii::app()->loadHelper('database');

View file

@ -227,6 +227,7 @@ class ExpressionManager {
'sum' => array('array_sum', 'LEMsum', gT('Calculate the sum of values in an array'), 'number sum(arg1, arg2, ... argN)', '', -2), 'sum' => array('array_sum', 'LEMsum', gT('Calculate the sum of values in an array'), 'number sum(arg1, arg2, ... argN)', '', -2),
'sumifop' => array('exprmgr_sumifop', 'LEMsumifop', gT('Sum the values of answered questions in the list which pass the critiera (arg op value)'), 'number sumifop(op, value, arg1, arg2, ... argN)', '', -3), 'sumifop' => array('exprmgr_sumifop', 'LEMsumifop', gT('Sum the values of answered questions in the list which pass the critiera (arg op value)'), 'number sumifop(op, value, arg1, arg2, ... argN)', '', -3),
'tan' => array('tan', 'Math.tan', gT('Tangent'), 'number tan(arg)', 'http://www.php.net/manual/en/function.tan.php', 1), 'tan' => array('tan', 'Math.tan', gT('Tangent'), 'number tan(arg)', 'http://www.php.net/manual/en/function.tan.php', 1),
'convert_value' => array('exprmgr_convert_value', 'LEMconvert_value', gT('Convert a numerical value using a inputTable and outputTable of numerical values'), 'number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList)', '', 4),
'time' => array('time', 'time', gT('Return current UNIX timestamp'), 'number time()', 'http://www.php.net/manual/en/function.time.php', 0), 'time' => array('time', 'time', gT('Return current UNIX timestamp'), 'number time()', 'http://www.php.net/manual/en/function.time.php', 0),
'trim' => array('trim', 'trim', gT('Strip whitespace (or other characters) from the beginning and end of a string'), 'string trim(string [, charlist])', 'http://www.php.net/manual/en/function.trim.php', 1,2), 'trim' => array('trim', 'trim', gT('Strip whitespace (or other characters) from the beginning and end of a string'), 'string trim(string [, charlist])', 'http://www.php.net/manual/en/function.trim.php', 1,2),
'ucwords' => array('ucwords', 'ucwords', gT('Uppercase the first character of each word in a string'), 'string ucwords(string)', 'http://www.php.net/manual/en/function.ucwords.php', 1), 'ucwords' => array('ucwords', 'ucwords', gT('Uppercase the first character of each word in a string'), 'string ucwords(string)', 'http://www.php.net/manual/en/function.ucwords.php', 1),
@ -1294,7 +1295,7 @@ class ExpressionManager {
} }
else else
{ {
$stringParts[] = is_numeric($code) ? $code : ("'" . addcslashes($code,"'") . "'"); // htmlspecialchars($code,ENT_QUOTES,'UTF-8',false) . "'"); $stringParts[] = "'" . addcslashes($code,"'") . "'";
} }
} }
break; break;
@ -2576,6 +2577,52 @@ function exprmgr_sumifop($args)
return $result; return $result;
} }
/**
* Find the closest matching numerical input values in a list an replace it by the
* corresponding value within another list
*
* @author Johannes Weberhofer, 2013
*
* @param numeric $fValueToReplace
* @param numeric $iStrict - 1 for exact matches only otherwise interpolation the
* closest value should be returned
* @param string $sTranslateFromList - comma seperated list of numeric values to translate from
* @param string $sTranslateToList - comma seperated list of numeric values to translate to
* @return numeric
*/
function exprmgr_convert_value($fValueToReplace, $iStrict, $sTranslateFromList, $sTranslateToList)
{
if ( (is_numeric($fValueToReplace)) && ($iStrict!=null) && ($sTranslateFromList!=null) && ($sTranslateToList!=null) )
{
$aFromValues = explode( ',', $sTranslateFromList);
$aToValues = explode( ',', $sTranslateToList);
if ( (count($aFromValues) > 0) && (count($aFromValues) == count($aToValues)) )
{
$fMinimumDiff = null;
$iNearestIndex = 0;
for ( $i = 0; $i < count($aFromValues); $i++) {
if ( !is_numeric($aFromValues[$i])) {
// break processing when non-numeric variables are about to be processed
return null;
}
$fCurrentDiff = abs($aFromValues[$i] - $fValueToReplace);
if ($fCurrentDiff === 0) {
return $aToValues[$i];
} else if ($i === 0) {
$fMinimumDiff = $fCurrentDiff;
} else if ( $fMinimumDiff > $fCurrentDiff ) {
$fMinimumDiff = $fCurrentDiff;
$iNearestIndex = $i;
}
}
if ( $iStrict !== 1 ) {
return $aToValues[$iNearestIndex];
}
}
}
return null;
}
/** /**
* If $test is true, return $ok, else return $error * If $test is true, return $ok, else return $error
* @param <type> $test * @param <type> $test
@ -2596,14 +2643,17 @@ function exprmgr_if($test,$ok,$error)
} }
/** /**
* Return true if the variable is an integer * Return true if the variable is an integer for LimeSurvey
* Can not really use is_int due to SQL DECIMAL system
* @param string $arg * @param string $arg
* @return boolean * @return boolean
* @link http://php.net/is_int#82857 * @link http://php.net/is_int#82857
*/ */
function exprmgr_int($arg) function exprmgr_int($arg)
{ {
return (ctype_digit((string)$arg));// Accept empty value too before PHP 5.1 see http://php.net/ctype-digit#refsect1-function.ctype-digit-changelog if(strpos($arg,"."))
$arg=preg_replace("/\.$/","",rtrim(strval($arg),"0"));// DECIMAL from SQL return always .00000000, the remove all 0 and one . , see #09550
return (ctype_digit($arg));// Accept empty value too before PHP 5.1 see http://php.net/ctype-digit#refsect1-function.ctype-digit-changelog
} }
/** /**
* Join together $args[0-N] with ', ' * Join together $args[0-N] with ', '

View file

@ -708,8 +708,8 @@
*/ */
public static function SetDirtyFlag() public static function SetDirtyFlag()
{ {
$_SESSION['LEMdirtyFlag'] = true; $_SESSION['LEMdirtyFlag'] = true;// For fieldmap and other. question help {HELP} is taken from fieldmap
$_SESSION['LEMforceRefresh'] = true; $_SESSION['LEMforceRefresh'] = true;// For Expression manager string
} }
/** /**
@ -741,7 +741,7 @@
} }
if ($_SESSION['LEMlang'] != $lang) { if ($_SESSION['LEMlang'] != $lang) {
// then changing languages, so clear cache // then changing languages, so clear cache
self::SetDirtyFlag(); self::SetDirtyFlag();
} }
$_SESSION['LEMlang'] = $lang; $_SESSION['LEMlang'] = $lang;
} }
@ -758,20 +758,27 @@
// Cheat and upgrade question attributes here too. // Cheat and upgrade question attributes here too.
self::UpgradeQuestionAttributes(true,$surveyId,$qid); self::UpgradeQuestionAttributes(true,$surveyId,$qid);
$releqns = self::ConvertConditionsToRelevance($surveyId,$qid); if (is_null($surveyId))
$num = count($releqns); {
if ($num == 0) { $sQuery='SELECT sid FROM {{surveys}}';
return NULL; $aSurveyIDs = Yii::app()->db->createCommand($sQuery)->queryColumn();
}
else{
$aSurveyIDs=array($surveyId);
}
foreach ($aSurveyIDs as $surveyId )
{
$releqns = self::ConvertConditionsToRelevance($surveyId,$qid);
if ( !empty( $releqns) ) {
foreach ($releqns as $key=>$value)
{
$sQuery = "UPDATE {{questions}} SET relevance=".Yii::app()->db->quoteValue($value)." WHERE qid=".$key;
Yii::app()->db->createCommand($sQuery)->execute();
}
}
} }
$queries = array();
foreach ($releqns as $key=>$value) {
$query = "UPDATE {{questions}} SET relevance=".Yii::app()->db->quoteValue($value)." WHERE qid=".$key;
dbExecuteAssoc($query);
$queries[] = $query;
}
LimeExpressionManager::SetDirtyFlag(); LimeExpressionManager::SetDirtyFlag();
return $queries;
} }
/** /**
@ -875,14 +882,15 @@
$_cqid = $row['cqid']; $_cqid = $row['cqid'];
$_subqid = -1; $_subqid = -1;
} }
// fix fieldnames // fix fieldnames
if ($row['type'] == '' && preg_match('/^{.+}$/',$row['cfieldname'])) { if (empty($row['type']) && preg_match('/^{.+}$/',$row['cfieldname']))
{
$fieldname = substr($row['cfieldname'],1,-1); // {TOKEN:xxxx} $fieldname = substr($row['cfieldname'],1,-1); // {TOKEN:xxxx}
$subqid = $fieldname; $subqid = $fieldname;
$value = $row['value']; $value = $row['value'];
} }
else if ($row['type'] == 'M' || $row['type'] == 'P') { elseif ($row['type'] == 'M' || $row['type'] == 'P')
{
if (substr($row['cfieldname'],0,1) == '+') { if (substr($row['cfieldname'],0,1) == '+') {
// if prefixed with +, then a fully resolved name // if prefixed with +, then a fully resolved name
$fieldname = substr($row['cfieldname'],1) . '.NAOK'; $fieldname = substr($row['cfieldname'],1) . '.NAOK';
@ -896,11 +904,13 @@
$value = 'Y'; $value = 'Y';
} }
} }
else { else
{
$fieldname = $row['cfieldname'] . '.NAOK'; $fieldname = $row['cfieldname'] . '.NAOK';
$subqid = $fieldname; $subqid = $fieldname;
$value = $row['value']; $value = $row['value'];
} }
if ($_subqid != -1 && $_subqid != $subqid) if ($_subqid != -1 && $_subqid != $subqid)
{ {
$relAndList[] = '(' . implode(' or ', $relOrList) . ')'; $relAndList[] = '(' . implode(' or ', $relOrList) . ')';
@ -912,17 +922,19 @@
if (preg_match('/^@\d+X\d+X\d+.*@$/',$value)) { if (preg_match('/^@\d+X\d+X\d+.*@$/',$value)) {
$value = substr($value,1,-1); $value = substr($value,1,-1);
} }
else if (preg_match('/^{.+}$/',$value)) { elseif (preg_match('/^{.+}$/',$value))
$value = substr($value,1,-1); {
$value = substr($value,1,-1);
}
elseif ($row['method'] == 'RX')
{
if (!preg_match('#^/.*/$#',$value))
{
$value = '"/' . $value . '/"'; // if not surrounded by slashes, add them.
} }
else if ($row['method'] == 'RX') { }
if (!preg_match('#^/.*/$#',$value)) else {
{ $value = '"' . $value . '"';
$value = '"/' . $value . '/"'; // if not surrounded by slashes, add them.
}
}
else {
$value = '"' . $value . '"';
} }
// add equation // add equation
@ -983,9 +995,11 @@
} }
} }
if ($row['cqid'] == 0 || substr($row['cfieldname'],0,1) == '+') { if (($row['cqid'] == 0 && !preg_match('/^{TOKEN:([^}]*)}$/',$row['cfieldname'])) || substr($row['cfieldname'],0,1) == '+')
$_cqid = -1; // forces this statement to be ANDed instead of being part of a cqid OR group {
$_cqid = -1; // forces this statement to be ANDed instead of being part of a cqid OR group (except for TOKEN fields)
} }
} }
// output last one // output last one
if ($_qid != -1) if ($_qid != -1)
@ -1001,10 +1015,12 @@
$relevanceEqn = implode(' or ', $scenarios); $relevanceEqn = implode(' or ', $scenarios);
$relevanceEqns[$_qid] = $relevanceEqn; $relevanceEqns[$_qid] = $relevanceEqn;
} }
if (is_null($qid)) { if (is_null($qid))
{
return $relevanceEqns; return $relevanceEqns;
} }
else { else
{
if (isset($relevanceEqns[$qid])) if (isset($relevanceEqns[$qid]))
{ {
$result = array(); $result = array();
@ -1315,11 +1331,7 @@
foreach($subqs as $sq) foreach($subqs as $sq)
{ {
$sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK";
if(($qinfo['mandatory']=='Y')){ $sq_equs[] = '( is_numeric('.$sq_name.') || is_empty('.$sq_name.') )';// Leave mandatory to mandatory attribute (see #09369)
$sq_equs[] = 'is_numeric('.$sq_name.')';
}else{
$sq_equs[] = '( is_numeric('.$sq_name.') || is_empty('.$sq_name.') )';
}
if($type=="K") if($type=="K")
$subqValidSelector = $sq['jsVarName_on']; $subqValidSelector = $sq['jsVarName_on'];
else else
@ -1400,11 +1412,7 @@
foreach($subqs as $sq) foreach($subqs as $sq)
{ {
$sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK";
if(($qinfo['mandatory']=='Y')){ $sq_equs[] = '('.$sq_name.'!="INVALID")';
$sq_equs[] = '('.$sq_name.'!="INVALID")';
}else{
$sq_equs[] = '('.$sq_name.'!="INVALID")';
}
} }
if (!isset($validationEqn[$questionNum])) if (!isset($validationEqn[$questionNum]))
{ {
@ -1510,12 +1518,7 @@
} }
$sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK";
$sq_name = '(is_empty(' . $sq_name . ') || ('. $sq_name . ' >= date("Y-m-d H:i", strtotime(' . $date_min . ')) ))';// Leave mandatory to mandatory attribute
if(($qinfo['mandatory']=='Y')){
$sq_name = '('. $sq_name . ' >= ' . $date_min . ')';
}else{
$sq_name = '(is_empty(' . $sq_name . ') || ('. $sq_name . ' >= ' . $date_min . '))';
}
$subqValidSelector = ''; $subqValidSelector = '';
break; break;
default: default:
@ -1584,12 +1587,7 @@
} }
$sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK";
$sq_name = '(is_empty(' . $sq_name . ') || is_empty(' . $date_max . ') || ('. $sq_name . ' <= date("Y-m-d H:i", strtotime(' . $date_max . ')) ))';// Leave mandatory to mandatory attribute
if(($qinfo['mandatory']=='Y')){
$sq_name = '(is_empty(' . $date_max . ') || ('. $sq_name . ' <= ' . $date_max . '))';
}else{
$sq_name = '(is_empty(' . $sq_name . ') || is_empty(' . $date_max . ') || ('. $sq_name . ' <= ' . $date_max . '))';
}
$subqValidSelector = ''; $subqValidSelector = '';
break; break;
default: default:
@ -2076,19 +2074,11 @@
case 'K': //MULTIPLE NUMERICAL QUESTION case 'K': //MULTIPLE NUMERICAL QUESTION
if ($this->sgqaNaming) if ($this->sgqaNaming)
{ {
if(($qinfo['mandatory']=='Y')){ $sq_name = '(is_empty(' . $sq['rowdivid'] . '.NAOK) || '. $sq['rowdivid'] . '.NAOK >= (' . $min_num_value_n . '))';
$sq_name = '('. $sq['rowdivid'] . '.NAOK >= (' . $min_num_value_n . '))';
}else{
$sq_name = '(is_empty(' . $sq['rowdivid'] . '.NAOK) || '. $sq['rowdivid'] . '.NAOK >= (' . $min_num_value_n . '))';
}
} }
else else
{ {
if(($qinfo['mandatory']=='Y')){ $sq_name = '(is_empty(' . $sq['varName'] . '.NAOK) || '. $sq['varName'] . '.NAOK >= (' . $min_num_value_n . '))';
$sq_name = '('. $sq['varName'] . '.NAOK >= (' . $min_num_value_n . '))';
}else{
$sq_name = '(is_empty(' . $sq['varName'] . '.NAOK) || '. $sq['varName'] . '.NAOK >= (' . $min_num_value_n . '))';
}
} }
$subqValidSelector = $sq['jsVarName_on']; $subqValidSelector = $sq['jsVarName_on'];
break; break;
@ -2103,11 +2093,7 @@
} }
else else
{ {
if(($qinfo['mandatory']=='Y')){ $sq_name = '(is_empty(' . $sq['varName'] . '.NAOK) || '. $sq['varName'] . '.NAOK >= (' . $min_num_value_n . '))';
$sq_name = '('. $sq['varName'] . '.NAOK >= (' . $min_num_value_n . '))';
}else{
$sq_name = '(is_empty(' . $sq['varName'] . '.NAOK) || '. $sq['varName'] . '.NAOK >= (' . $min_num_value_n . '))';
}
} }
$subqValidSelector = ''; $subqValidSelector = '';
break; break;
@ -2543,11 +2529,7 @@
$subqValidSelector = $sq['jsVarName_on']; $subqValidSelector = $sq['jsVarName_on'];
case 'N': //NUMERICAL QUESTION TYPE case 'N': //NUMERICAL QUESTION TYPE
$sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK";
if(($qinfo['mandatory']=='Y')){ $sq_eqn = 'is_int('.$sq_name.') || is_empty('.$sq_name.')';
$sq_eqn = 'is_int('.$sq_name.')';
}else{
$sq_eqn = 'is_int('.$sq_name.') || is_empty('.$sq_name.')';
}
break; break;
default: default:
break; break;
@ -2595,11 +2577,7 @@
foreach($subqs as $sq) foreach($subqs as $sq)
{ {
$sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK"; $sq_name = ($this->sgqaNaming)?$sq['rowdivid'].".NAOK":$sq['varName'].".NAOK";
if(($qinfo['mandatory']=='Y')){ $sq_equs[] = '( is_numeric('.$sq_name.') || is_empty('.$sq_name.') )';
$sq_equs[] = 'is_numeric('.$sq_name.')';
}else{
$sq_equs[] = '( is_numeric('.$sq_name.') || is_empty('.$sq_name.') )';
}
} }
if (!isset($validationEqn[$questionNum])) if (!isset($validationEqn[$questionNum]))
{ {
@ -3144,11 +3122,22 @@
{ {
$_minV = (($min_num_value_n == '') ? "''" : $min_num_value_n); $_minV = (($min_num_value_n == '') ? "''" : $min_num_value_n);
$_maxV = (($max_num_value_n == '') ? "''" : $max_num_value_n); $_maxV = (($max_num_value_n == '') ? "''" : $max_num_value_n);
$qtips['value_range']= if ($type!='N')
"{if(!is_empty($_minV) && is_empty($_maxV), sprintf('".$this->gT("Each answer must be at least %s")."',fixnum($_minV)), '')}" . {
"{if(is_empty($_minV) && !is_empty($_maxV), sprintf('".$this->gT("Each answer must be at most %s")."',fixnum($_maxV)), '')}" . $qtips['value_range']=
"{if(!is_empty($_minV) && ($_minV) == ($_maxV),sprintf('".$this->gT("Each answer must be %s")."', fixnum($_minV)), '')}" . "{if(!is_empty($_minV) && is_empty($_maxV), sprintf('".$this->gT("Each answer must be at least %s")."',fixnum($_minV)), '')}" .
"{if(!is_empty($_minV) && !is_empty($_maxV) && ($_minV) != ($_maxV), sprintf('".$this->gT("Each answer must be between %s and %s")."', fixnum($_minV), fixnum($_maxV)), '')}"; "{if(is_empty($_minV) && !is_empty($_maxV), sprintf('".$this->gT("Each answer must be at most %s")."',fixnum($_maxV)), '')}" .
"{if(!is_empty($_minV) && ($_minV) == ($_maxV),sprintf('".$this->gT("Each answer must be %s")."', fixnum($_minV)), '')}" .
"{if(!is_empty($_minV) && !is_empty($_maxV) && ($_minV) != ($_maxV), sprintf('".$this->gT("Each answer must be between %s and %s")."', fixnum($_minV), fixnum($_maxV)), '')}";
}
else
{
$qtips['value_range']=
"{if(!is_empty($_minV) && is_empty($_maxV), sprintf('".$this->gT("Your answer must be at least %s")."',fixnum($_minV)), '')}" .
"{if(is_empty($_minV) && !is_empty($_maxV), sprintf('".$this->gT("Your answer must be at most %s")."',fixnum($_maxV)), '')}" .
"{if(!is_empty($_minV) && ($_minV) == ($_maxV),sprintf('".$this->gT("Your answer must be %s")."', fixnum($_minV)), '')}" .
"{if(!is_empty($_minV) && !is_empty($_maxV) && ($_minV) != ($_maxV), sprintf('".$this->gT("Your answer must be between %s and %s")."', fixnum($_minV), fixnum($_maxV)), '')}";
}
} }
// min/max value for dates // min/max value for dates
@ -4063,21 +4052,21 @@
if (Survey::model()->hasTokens($surveyid) && isset($_SESSION[$this->sessid]['token']) && $_SESSION[$this->sessid]['token'] != '') if (Survey::model()->hasTokens($surveyid) && isset($_SESSION[$this->sessid]['token']) && $_SESSION[$this->sessid]['token'] != '')
{ {
//Gather survey data for tokenised surveys, for use in presenting questions //Gather survey data for tokenised surveys, for use in presenting questions
$this->knownVars['TOKEN:TOKEN'] = array( $this->knownVars['TOKEN:TOKEN'] = array(
'code'=>$_SESSION[$this->sessid]['token'], 'code'=>$_SESSION[$this->sessid]['token'],
'jsName_on'=>'', 'jsName_on'=>'',
'jsName'=>'', 'jsName'=>'',
'readWrite'=>'N', 'readWrite'=>'N',
); );
$token = Token::model($surveyid)->findByToken($_SESSION[$this->sessid]['token']); $token = Token::model($surveyid)->findByToken($_SESSION[$this->sessid]['token']);
foreach ($token as $key => $val) foreach ($token as $key => $val)
{ {
$this->knownVars["TOKEN:" . strtoupper($key)] = array( $this->knownVars["TOKEN:" . strtoupper($key)] = array(
'code' => $anonymized ? '' : $val, 'code' => $anonymized ? '' : $val,
'jsName_on' => '', 'jsName_on' => '',
'jsName' => '', 'jsName' => '',
'readWrite' => 'N', 'readWrite' => 'N',
); );
} }
} }
@ -4883,8 +4872,8 @@
'at_start'=>true, 'at_start'=>true,
'finished'=>false, 'finished'=>false,
'message'=>$message, 'message'=>$message,
'unansweredSQs'=>(isset($result['unansweredSQs']) ? $result['unansweredSQs'] : ''), 'unansweredSQs'=>'',
'invalidSQs'=>(isset($result['invalidSQs']) ? $result['invalidSQs'] : ''), 'invalidSQs'=>'',
); );
return $LEM->lastMoveResult; return $LEM->lastMoveResult;
} }
@ -4922,7 +4911,7 @@
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
'seq'=>$LEM->currentQuestionSeq, 'seq'=>$LEM->currentQuestionSeq,
'qseq'=>$LEM->currentQuestionSeq, 'qseq'=>$LEM->currentQuestionSeq,
'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), 'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false),// This can never happen ?
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false),
'unansweredSQs'=>$result['unansweredSQs'], 'unansweredSQs'=>$result['unansweredSQs'],
'invalidSQs'=>$result['invalidSQs'], 'invalidSQs'=>$result['invalidSQs'],
@ -5029,6 +5018,7 @@
if (is_null($result)) { if (is_null($result)) {
continue; // this is an invalid group - skip it continue; // this is an invalid group - skip it
} }
$message .= $result['message']; $message .= $result['message'];
$updatedValues = array_merge($updatedValues,$result['updatedValues']); $updatedValues = array_merge($updatedValues,$result['updatedValues']);
if (!$result['relevant'] || $result['hidden']) if (!$result['relevant'] || $result['hidden'])
@ -5066,20 +5056,20 @@
$updatedValues = array_merge($updatedValues,$result['updatedValues']); $updatedValues = array_merge($updatedValues,$result['updatedValues']);
$gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq]; $gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq];
$grel = $gRelInfo['result']; $grel = $gRelInfo['result'];
if ($grel && !is_null($result) && ($result['mandViolation'] || !$result['valid'])) if ($grel && !is_null($result) && ($result['mandViolation'] || !$result['valid']))
{ {
// redisplay the current question // redisplay the current question
$message .= $LEM->_UpdateValuesInDatabase($updatedValues,false); $message .= $LEM->_UpdateValuesInDatabase($updatedValues,false);
$LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now)); $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now));
// We have an error : always show real last move result
$LEM->lastMoveResult = array( $LEM->lastMoveResult = array(
'finished'=>false, 'finished'=>false,
'message'=>$message, 'message'=>$message,
'qseq'=>$LEM->currentQuestionSeq, 'qseq'=>$LEM->currentQuestionSeq,
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
'seq'=>$LEM->currentQuestionSeq, 'seq'=>$LEM->currentQuestionSeq,
'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), 'mandViolation'=> $result['mandViolation'],
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> $result['valid'],
'unansweredSQs'=>$result['unansweredSQs'], 'unansweredSQs'=>$result['unansweredSQs'],
'invalidSQs'=>$result['invalidSQs'], 'invalidSQs'=>$result['invalidSQs'],
); );
@ -5091,6 +5081,7 @@
$LEM->currentQset = array(); // reset active list of questions $LEM->currentQset = array(); // reset active list of questions
if (++$LEM->currentQuestionSeq >= $LEM->numQuestions) if (++$LEM->currentQuestionSeq >= $LEM->numQuestions)
{ {
// Redisplay the last question with error existing result
$message .= $LEM->_UpdateValuesInDatabase($updatedValues,true); $message .= $LEM->_UpdateValuesInDatabase($updatedValues,true);
$LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now)); $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now));
$LEM->lastMoveResult = array( $LEM->lastMoveResult = array(
@ -5099,8 +5090,8 @@
'qseq'=>$LEM->currentQuestionSeq, 'qseq'=>$LEM->currentQuestionSeq,
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
'seq'=>$LEM->currentQuestionSeq, 'seq'=>$LEM->currentQuestionSeq,
'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), 'mandViolation'=> (isset($result['mandViolation']) ? $result['mandViolation'] : false),
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> (isset($result['valid']) ? $result['valid'] : false),
'unansweredSQs'=>(isset($result['unansweredSQs']) ? $result['unansweredSQs'] : ''), 'unansweredSQs'=>(isset($result['unansweredSQs']) ? $result['unansweredSQs'] : ''),
'invalidSQs'=>(isset($result['invalidSQs']) ? $result['invalidSQs'] : ''), 'invalidSQs'=>(isset($result['invalidSQs']) ? $result['invalidSQs'] : ''),
); );
@ -5123,7 +5114,6 @@
$updatedValues = array_merge($updatedValues,$result['updatedValues']); $updatedValues = array_merge($updatedValues,$result['updatedValues']);
$gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq]; $gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq];
$grel = $gRelInfo['result']; $grel = $gRelInfo['result'];
if (!$grel || !$result['relevant'] || $result['hidden']) if (!$grel || !$result['relevant'] || $result['hidden'])
{ {
// then skip this question - assume already saved? // then skip this question - assume already saved?
@ -5132,6 +5122,7 @@
else else
{ {
// display new question // display new question
// If it's new question : no mandatory error in lastMoveResult
$message .= $LEM->_UpdateValuesInDatabase($updatedValues,false); $message .= $LEM->_UpdateValuesInDatabase($updatedValues,false);
$LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now)); $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now));
$LEM->lastMoveResult = array( $LEM->lastMoveResult = array(
@ -5140,8 +5131,8 @@
'qseq'=>$LEM->currentQuestionSeq, 'qseq'=>$LEM->currentQuestionSeq,
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
'seq'=>$LEM->currentQuestionSeq, 'seq'=>$LEM->currentQuestionSeq,
'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), 'mandViolation'=> false,
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> true,
'unansweredSQs'=>$result['unansweredSQs'], 'unansweredSQs'=>$result['unansweredSQs'],
'invalidSQs'=>$result['invalidSQs'], 'invalidSQs'=>$result['invalidSQs'],
); );
@ -5189,7 +5180,14 @@
} }
if ($this->surveyOptions['refurl'] == true) if ($this->surveyOptions['refurl'] == true)
{ {
$sdata['refurl'] = getenv("HTTP_REFERER"); if (isset($_SESSION[$this->sessid]['refurl']))
{
$sdata['refurl'] = $_SESSION[$this->sessid]['refurl'];
}
else
{
$sdata['refurl'] = getenv("HTTP_REFERER");
}
} }
$sdata = array_filter($sdata); $sdata = array_filter($sdata);
@ -5205,6 +5203,8 @@
else else
{ {
$message .= $this->gT("Unable to insert record into survey table"); // TODO - add SQL error? $message .= $this->gT("Unable to insert record into survey table"); // TODO - add SQL error?
echo submitfailed(''); // TODO - report SQL error?
} }
//Insert Row for Timings, if needed //Insert Row for Timings, if needed
if ($this->surveyOptions['savetimings']) { if ($this->surveyOptions['savetimings']) {
@ -5324,23 +5324,10 @@
SavedControl::model()->updateByPk($_SESSION[$this->sessid]['scid'], array('saved_thisstep'=>$thisstep)); SavedControl::model()->updateByPk($_SESSION[$this->sessid]['scid'], array('saved_thisstep'=>$thisstep));
} }
// Check Quotas // Check Quotas
$bQuotaMatched = false; $aQuotas = checkCompletedQuota($this->sid,'return');
$aQuotas = checkQuota('return', $this->sid); if ($aQuotas && !empty($aQuotas))
if ($aQuotas !== false)
{ {
if ($aQuotas != false) checkCompletedQuota($this->sid); // will create a page and quit: why not use it directly ?
{
foreach ($aQuotas as $aQuota)
{
if (isset($aQuota['status']) && $aQuota['status'] == 'matched') {
$bQuotaMatched = true;
}
}
}
}
if ($bQuotaMatched)
{
checkQuota('enforce',$this->sid); // will create a page and quit.
} }
else else
{ {
@ -5423,7 +5410,7 @@
$message = ''; $message = '';
$LEM->currentQset = array(); // reset active list of questions $LEM->currentQset = array(); // reset active list of questions
$result = $LEM->_ValidateSurvey(); $result = $LEM->_ValidateSurvey($force);
$message .= $result['message']; $message .= $result['message'];
$updatedValues = array_merge($updatedValues,$result['updatedValues']); $updatedValues = array_merge($updatedValues,$result['updatedValues']);
$finished=false; $finished=false;
@ -5497,7 +5484,7 @@
return $LEM->lastMoveResult; return $LEM->lastMoveResult;
} }
$result = $LEM->_ValidateGroup($LEM->currentGroupSeq); $result = $LEM->_ValidateGroup($LEM->currentGroupSeq,$force);
if (is_null($result)) { if (is_null($result)) {
return NULL; // invalid group - either bad number, or no questions within it return NULL; // invalid group - either bad number, or no questions within it
} }
@ -5508,19 +5495,20 @@
// then skip this group - assume already saved? // then skip this group - assume already saved?
continue; continue;
} }
elseif (!($result['mandViolation'] || !$result['valid']) && $LEM->currentGroupSeq < $seq) { elseif (!($result['mandViolation'] || !$result['valid']) && $LEM->currentGroupSeq < $seq)
// if there is a violation while moving forward, need to stop and ask that set of questions {
// if there are no violations, can skip this group as long as changed values are saved. // if there is a violation while moving forward, need to stop and ask that set of questions
continue; // if there are no violations, can skip this group as long as changed values are saved.
continue;
}
else
{
// display new group
if(!$preview){ // Save only if not in preview mode
$message .= $LEM->_UpdateValuesInDatabase($updatedValues,false);
$LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now));
} }
else $LEM->lastMoveResult = array(
{
// display new group
if(!$preview){ // Save only if not in preview mode
$message .= $LEM->_UpdateValuesInDatabase($updatedValues,false);
$LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now));
}
$LEM->lastMoveResult = array(
'finished'=>false, 'finished'=>false,
'message'=>$message, 'message'=>$message,
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
@ -5529,8 +5517,8 @@
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false),
'unansweredSQs'=>$result['unansweredSQs'], 'unansweredSQs'=>$result['unansweredSQs'],
'invalidSQs'=>$result['invalidSQs'], 'invalidSQs'=>$result['invalidSQs'],
); );
return $LEM->lastMoveResult; return $LEM->lastMoveResult;
} }
} }
break; break;
@ -5545,7 +5533,7 @@
$message = ''; $message = '';
if (!$force && $LEM->currentQuestionSeq != -1 && $seq > $LEM->currentQuestionSeq) if (!$force && $LEM->currentQuestionSeq != -1 && $seq > $LEM->currentQuestionSeq)
{ {
$result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq); $result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq,$force);
$message .= $result['message']; $message .= $result['message'];
$updatedValues = array_merge($updatedValues,$result['updatedValues']); $updatedValues = array_merge($updatedValues,$result['updatedValues']);
$gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq]; $gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq];
@ -5561,8 +5549,8 @@
'qseq'=>$LEM->currentQuestionSeq, 'qseq'=>$LEM->currentQuestionSeq,
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
'seq'=>$LEM->currentQuestionSeq, 'seq'=>$LEM->currentQuestionSeq,
'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), 'mandViolation'=> $result['mandViolation'],
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> $result['valid'],
'unansweredSQs'=>$result['unansweredSQs'], 'unansweredSQs'=>$result['unansweredSQs'],
'invalidSQs'=>$result['invalidSQs'], 'invalidSQs'=>$result['invalidSQs'],
); );
@ -5585,8 +5573,8 @@
'qseq'=>$LEM->currentQuestionSeq, 'qseq'=>$LEM->currentQuestionSeq,
'gseq'=>$LEM->currentGroupSeq, 'gseq'=>$LEM->currentGroupSeq,
'seq'=>$LEM->currentQuestionSeq, 'seq'=>$LEM->currentQuestionSeq,
'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), 'mandViolation'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['mandViolation'] : false), // Can set always false ?
'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), // Return always false ?
'unansweredSQs'=>(isset($result['unansweredSQs']) ? $result['unansweredSQs'] : ''), 'unansweredSQs'=>(isset($result['unansweredSQs']) ? $result['unansweredSQs'] : ''),
'invalidSQs'=>(isset($result['invalidSQs']) ? $result['invalidSQs'] : ''), 'invalidSQs'=>(isset($result['invalidSQs']) ? $result['invalidSQs'] : ''),
); );
@ -5607,7 +5595,7 @@
$LEM->ProcessAllNeededRelevance($LEM->currentQuestionSeq); $LEM->ProcessAllNeededRelevance($LEM->currentQuestionSeq);
$LEM->_CreateSubQLevelRelevanceAndValidationEqns($LEM->currentQuestionSeq); $LEM->_CreateSubQLevelRelevanceAndValidationEqns($LEM->currentQuestionSeq);
$result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq); $result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq,$force);
$message .= $result['message']; $message .= $result['message'];
$updatedValues = array_merge($updatedValues,$result['updatedValues']); $updatedValues = array_merge($updatedValues,$result['updatedValues']);
$gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq]; $gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq];
@ -5655,7 +5643,7 @@
* Check the entire survey * Check the entire survey
* @return <type> * @return <type>
*/ */
private function _ValidateSurvey() private function _ValidateSurvey($force=false)
{ {
$LEM =& $this; $LEM =& $this;
@ -5674,7 +5662,7 @@
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
for ($i=0;$i<$LEM->numGroups;++$i) { for ($i=0;$i<$LEM->numGroups;++$i) {
$LEM->currentGroupSeq=$i; $LEM->currentGroupSeq=$i;
$gStatus = $LEM->_ValidateGroup($i); $gStatus = $LEM->_ValidateGroup($i,$force);
if (is_null($gStatus)) { if (is_null($gStatus)) {
continue; // invalid group, so skip it continue; // invalid group, so skip it
} }
@ -5726,10 +5714,11 @@
/** /**
* Check a group and all of the questions it contains * Check a group and all of the questions it contains
* @param <type> $groupSeq - the index-0 sequence number for this group * @param integer $groupSeq - the index-0 sequence number for this group
* @param boolean $force : force validation to true, even if there are error
* @return <array> - detailed information about this group * @return <array> - detailed information about this group
*/ */
function _ValidateGroup($groupSeq) function _ValidateGroup($groupSeq,$force=false)
{ {
$LEM =& $this; $LEM =& $this;
@ -5765,7 +5754,7 @@
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
for ($i=$groupSeqInfo['qstart'];$i<=$groupSeqInfo['qend']; ++$i) for ($i=$groupSeqInfo['qstart'];$i<=$groupSeqInfo['qend']; ++$i)
{ {
$qStatus = $LEM->_ValidateQuestion($i); $qStatus = $LEM->_ValidateQuestion($i,$force);
$updatedValues = array_merge($updatedValues,$qStatus['updatedValues']); $updatedValues = array_merge($updatedValues,$qStatus['updatedValues']);
@ -5895,11 +5884,12 @@
* (c) relevance status - including sub-question-level relevance * (c) relevance status - including sub-question-level relevance
* (d) answered - if $_SESSION[$LEM->sessid][sgqa]=='' or NULL, then it is not answered * (d) answered - if $_SESSION[$LEM->sessid][sgqa]=='' or NULL, then it is not answered
* (e) validity - whether relevant questions pass their validity tests * (e) validity - whether relevant questions pass their validity tests
* @param <type> $questionSeq - the 0-index sequence number for this question * @param integer $questionSeq - the 0-index sequence number for this question
* @param boolean $force : force validation to true, even if there are error, this allow to save in DB even with error
* @return <array> of information about this question and its sub-questions * @return <array> of information about this question and its sub-questions
*/ */
function _ValidateQuestion($questionSeq) function _ValidateQuestion($questionSeq,$force=false)
{ {
$LEM =& $this; $LEM =& $this;
$qInfo = $LEM->questionSeq2relevance[$questionSeq]; // this array is by group and question sequence $qInfo = $LEM->questionSeq2relevance[$questionSeq]; // this array is by group and question sequence
@ -5913,7 +5903,12 @@
$gRelInfo = $LEM->gRelInfo[$qInfo['gseq']]; $gRelInfo = $LEM->gRelInfo[$qInfo['gseq']];
$grel = $gRelInfo['result']; $grel = $gRelInfo['result'];
//Allways set a $_SESSION
$allSQs = explode('|', $LEM->qid2code[$qid]);
foreach($allSQs as $answer){
if(!isset($_SESSION[$LEM->sessid][$answer]))
$_SESSION[$LEM->sessid][$answer]=null;
}
/////////////////////////// ///////////////////////////
// IS QUESTION RELEVANT? // // IS QUESTION RELEVANT? //
/////////////////////////// ///////////////////////////
@ -5966,6 +5961,7 @@
$prettyPrintSQRelEqn=''; $prettyPrintSQRelEqn='';
$prettyPrintValidTip=''; $prettyPrintValidTip='';
$anyUnanswered = false; $anyUnanswered = false;
if (!$qrel) if (!$qrel)
{ {
// All sub-questions are irrelevant // All sub-questions are irrelevant
@ -6282,9 +6278,9 @@
{ {
$rowCount=0; $rowCount=0;
$numUnanswered=0; $numUnanswered=0;
foreach ($sgqas as $s) foreach ($sgqas as $s)// For each sub question (double), test if one is checked
{ {
if (strpos($s, $sq['rowdivid']) !== false) if (strpos($s, $sq['rowdivid']."_") !== false)// Filterd by Y : SGQASYCODE_SXCODE
{ {
++$rowCount; ++$rowCount;
if (array_search($s,$unansweredSQs) !== false) { if (array_search($s,$unansweredSQs) !== false) {
@ -6364,6 +6360,7 @@
break; break;
} }
} }
/////////////////////////////////////////////// ///////////////////////////////////////////////
// DETECT ANY VIOLATIONS OF VALIDATION RULES // // DETECT ANY VIOLATIONS OF VALIDATION RULES //
/////////////////////////////////////////////// ///////////////////////////////////////////////
@ -6418,11 +6415,11 @@
} }
} }
} }
if (!$qvalid) if (!$qvalid)
{ {
$invalidSQs = $LEM->qid2code[$qid]; // TODO - currently invalidates all - should only invalidate those that truly fail validation rules. $invalidSQs = $LEM->qid2code[$qid]; // TODO - currently invalidates all - should only invalidate those that truly fail validation rules.
} }
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// OPTIONALLY DISPLAY (DETAILED) DEBUGGING INFORMATION // // OPTIONALLY DISPLAY (DETAILED) DEBUGGING INFORMATION //
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
@ -6527,26 +6524,27 @@
$LEM->updatedValues[$sgqa] = NULL; $LEM->updatedValues[$sgqa] = NULL;
} }
} }
else if ($qInfo['type'] == '*') elseif ($qInfo['type'] == '*')
{ {
// Process relevant equations, even if hidden, and write the result to the database // Process relevant equations, even if hidden, and write the result to the database
$result = flattenText($LEM->ProcessString($qInfo['eqn'], $qInfo['qid'],NULL,false,1,1,false,false)); $result = flattenText($LEM->ProcessString($qInfo['eqn'], $qInfo['qid'],NULL,false,1,1,false,false));
$sgqa = $LEM->qid2code[$qid]; // there will be only one, since Equation $sgqa = $LEM->qid2code[$qid]; // there will be only one, since Equation
// Store the result of the Equation in the SESSION // Store the result of the Equation in the SESSION
$_SESSION[$LEM->sessid][$sgqa] = $result; $_SESSION[$LEM->sessid][$sgqa] = $result;
$_update = array( $_update = array(
'type'=>'*', 'type'=>'*',
'value'=>$result, 'value'=>$result,
); );
$updatedValues[$sgqa] = $_update; $updatedValues[$sgqa] = $_update;
$LEM->updatedValues[$sgqa] = $_update; $LEM->updatedValues[$sgqa] = $_update;
if (($LEM->debugLevel & LEM_DEBUG_VALIDATION_DETAIL) == LEM_DEBUG_VALIDATION_DETAIL) if (($LEM->debugLevel & LEM_DEBUG_VALIDATION_DETAIL) == LEM_DEBUG_VALIDATION_DETAIL)
{ {
$prettyPrintEqn = $LEM->em->GetPrettyPrintString(); $prettyPrintEqn = $LEM->em->GetPrettyPrintString();
$debug_qmessage .= '** Process Hidden but Relevant Equation [' . $sgqa . '](' . $prettyPrintEqn . ') => ' . $result . "<br />\n"; $debug_qmessage .= '** Process Hidden but Relevant Equation [' . $sgqa . '](' . $prettyPrintEqn . ') => ' . $result . "<br />\n";
} }
} }
if ( $LEM->surveyOptions['deletenonvalues'] ) if ( $LEM->surveyOptions['deletenonvalues'] )
{ {
foreach ($irrelevantSQs as $sq) foreach ($irrelevantSQs as $sq)
@ -6561,12 +6559,12 @@
// Regardless of whether relevant or hidden, if there is a default value and $_SESSION[$LEM->sessid][$sgqa] is NULL, then use the default value in $_SESSION, but don't write to database // Regardless of whether relevant or hidden, if there is a default value and $_SESSION[$LEM->sessid][$sgqa] is NULL, then use the default value in $_SESSION, but don't write to database
// Also, set this AFTER testing relevance // Also, set this AFTER testing relevance
$sgqas = explode('|',$LEM->qid2code[$qid]); $sgqas = explode('|',$LEM->qid2code[$qid]);
foreach ($sgqas as $sgqa) foreach ($sgqas as $sgqa)
{ {
if (!is_null($LEM->knownVars[$sgqa]['default']) && !isset($_SESSION[$LEM->sessid][$sgqa])) { if (!is_null($LEM->knownVars[$sgqa]['default']) && !isset($_SESSION[$LEM->sessid][$sgqa])) {
// add support for replacements // add support for replacements
$defaultVal = $LEM->ProcessString($LEM->knownVars[$sgqa]['default'], NULL, NULL, false, 1, 1, false, false, true); $_SESSION[$LEM->sessid][$sgqa] = $LEM->ProcessString($LEM->knownVars[$sgqa]['default'], NULL, NULL, false, 1, 1, false, false, true);
$_SESSION[$LEM->sessid][$sgqa] = $defaultVal;
} }
} }
@ -6581,19 +6579,19 @@
'relEqn' => $prettyPrintRelEqn, 'relEqn' => $prettyPrintRelEqn,
'sgqa' => $LEM->qid2code[$qid], 'sgqa' => $LEM->qid2code[$qid],
'unansweredSQs' => implode('|',$unansweredSQs), 'unansweredSQs' => implode('|',$unansweredSQs),
'valid' => $qvalid, 'valid' => $force || $qvalid,
'validEqn' => $validationEqn, 'validEqn' => $validationEqn,
'prettyValidEqn' => $prettyPrintValidEqn, 'prettyValidEqn' => $prettyPrintValidEqn,
'validTip' => $validTip, 'validTip' => $validTip,
'prettyValidTip' => $prettyPrintValidTip, 'prettyValidTip' => $prettyPrintValidTip,
'validJS' => $validationJS, 'validJS' => $validationJS,
'invalidSQs' => (isset($invalidSQs) ? $invalidSQs : ''), 'invalidSQs' => (isset($invalidSQs) && !$force) ? $invalidSQs : '',
'relevantSQs' => implode('|',$relevantSQs), 'relevantSQs' => implode('|',$relevantSQs),
'irrelevantSQs' => implode('|',$irrelevantSQs), 'irrelevantSQs' => implode('|',$irrelevantSQs),
'subQrelEqn' => implode('<br />',$prettyPrintSQRelEqns), 'subQrelEqn' => implode('<br />',$prettyPrintSQRelEqns),
'mandViolation' => $qmandViolation, 'mandViolation' => (!$force) ? $qmandViolation : false,
'anyUnanswered' => $anyUnanswered, 'anyUnanswered' => $anyUnanswered,
'mandTip' => $mandatoryTip, 'mandTip' => (!$force) ? $mandatoryTip : '',
'message' => $debug_qmessage, 'message' => $debug_qmessage,
'updatedValues' => $updatedValues, 'updatedValues' => $updatedValues,
'sumEqn' => (isset($sumEqn) ? $sumEqn : ''), 'sumEqn' => (isset($sumEqn) ? $sumEqn : ''),
@ -6625,7 +6623,6 @@
'mandViolation' => $qmandViolation, 'mandViolation' => $qmandViolation,
'valid' => $qvalid, 'valid' => $qvalid,
); );
$_SESSION[$LEM->sessid]['relevanceStatus'][$qid] = $qrel; $_SESSION[$LEM->sessid]['relevanceStatus'][$qid] = $qrel;
return $qStatus; return $qStatus;
} }
@ -7869,14 +7866,14 @@ EOT;
<script type='text/javascript'> <script type='text/javascript'>
<!-- <!--
var LEMradix='.'; var LEMradix='.';
function checkconditions(value, name, type, evt_type) function checkconditions(value, name, type, evt_type)
{ {
if (typeof evt_type === 'undefined') if (typeof evt_type === 'undefined')
{ {
evt_type = 'onchange'; evt_type = 'onchange';
} }
ExprMgr_process_relevance_and_tailoring(evt_type,name,type); ExprMgr_process_relevance_and_tailoring(evt_type,name,type);
} }
// --> // -->
</script> </script>
EOD; EOD;
@ -8015,103 +8012,93 @@ EOD;
private static function getConditionsForEM($surveyid=NULL, $qid=NULL) private static function getConditionsForEM($surveyid=NULL, $qid=NULL)
{ {
if (!is_null($qid)) { if (!is_null($qid)) {
$where = " c.qid = ".$qid." and "; $where = " c.qid = ".$qid." AND ";
} }
else if (!is_null($surveyid)) { else if (!is_null($surveyid))
$where = " c.qid in (select qid from {{questions}} where sid = ".$surveyid.") and "; {
} $where = " qa.sid = {$surveyid} AND ";
else { }
$where = ""; else
{
$where = "";
} }
$query = "select distinct c.*" $query = "SELECT DISTINCT c.*, q.sid, q.type
.", q.sid, q.type" FROM {{conditions}} AS c
." from {{conditions}} as c" LEFT JOIN {{questions}} q ON c.cqid=q.qid
.", {{questions}} as q" LEFT JOIN {{questions}} qa ON c.qid=qa.qid
." where " . $where WHERE {$where} 1=1
." c.cqid=q.qid" UNION
." union " SELECT DISTINCT c.*, q.sid, NULL AS TYPE
." select c.*, q.sid, '' as type" FROM {{conditions}} AS c
." from {{conditions}} as c" LEFT JOIN {{questions}} q ON c.cqid=q.qid
.", {{questions}} as q" LEFT JOIN {{questions}} qa ON c.qid=qa.qid
." where ". $where WHERE {$where} c.cqid = 0";
." c.cqid = 0 and c.qid = q.qid";
$databasetype = Yii::app()->db->getDriverName(); $databasetype = Yii::app()->db->getDriverName();
if ($databasetype=='mssql' || $databasetype=='dblib') if ($databasetype=='mssql' || $databasetype=='dblib')
{ {
$query .= " order by sid, c.qid, scenario, cqid, cfieldname, value"; $query .= " order by c.qid, sid, scenario, cqid, cfieldname, value";
} }
else else
{ {
$query .= " order by sid, qid, scenario, cqid, cfieldname, value"; $query .= " order by qid, sid, scenario, cqid, cfieldname, value";
} }
$data = dbExecuteAssoc($query); return Yii::app()->db->createCommand($query)->query();
return $data;
} }
/** /**
* Deprecate obsolete question attributes. * Deprecate obsolete question attributes.
* @param boolean $changedb - if true, updates parameters and deletes old ones * @param boolean $changedb - if true, updates parameters and deletes old ones
* @param type $surveyid - if set, then only for that survey * @param type $iSureyID - if set, then only for that survey
* @param type $onlythisqid - if set, then only for this question ID * @param type $onlythisqid - if set, then only for this question ID
*/ */
public static function UpgradeQuestionAttributes($changeDB=false,$surveyid=NULL,$onlythisqid=NULL) public static function UpgradeQuestionAttributes($changeDB=false,$iSurveyID=NULL,$onlythisqid=NULL)
{ {
$LEM =& LimeExpressionManager::singleton(); $LEM =& LimeExpressionManager::singleton();
$qattrs = $LEM->getQuestionAttributesForEM($surveyid,$onlythisqid,$_SESSION['LEMlang']); if (is_null($iSurveyID))
{
$qupdates = array(); $sQuery='SELECT sid FROM {{surveys}}';
$aSurveyIDs = Yii::app()->db->createCommand($sQuery)->queryColumn();
}
else{
$aSurveyIDs=array($iSurveyID);
}
$attibutemap = array( $attibutemap = array(
'max_num_value_sgqa' => 'max_num_value', 'max_num_value_sgqa' => 'max_num_value',
'min_num_value_sgqa' => 'min_num_value', 'min_num_value_sgqa' => 'min_num_value',
'num_value_equals_sgqa' => 'equals_num_value', 'num_value_equals_sgqa' => 'equals_num_value',
); );
$reverseAttributeMap = array_flip($attibutemap); $reverseAttributeMap = array_flip($attibutemap);
foreach ($aSurveyIDs as $iSurveyID)
foreach ($qattrs as $qid => $qattr)
{ {
$updates = array(); $qattrs = $LEM->getQuestionAttributesForEM($iSurveyID,$onlythisqid,$_SESSION['LEMlang']);
foreach ($attibutemap as $src=>$target) foreach ($qattrs as $qid => $qattr)
{ {
if (isset($qattr[$src]) && trim($qattr[$src]) != '') $updates = array();
foreach ($attibutemap as $src=>$target)
{ {
$updates[$target] = $qattr[$src]; if (isset($qattr[$src]) && trim($qattr[$src]) != '')
{
$updates[$target] = $qattr[$src];
}
}
if ($changeDB)
{
foreach ($updates as $key=>$value)
{
$query = "UPDATE {{question_attributes}} SET value=".Yii::app()->db->quoteValue($value)." WHERE qid={$qid} and attribute=".Yii::app()->db->quoteValue($key);
Yii::app()->db->createCommand($query)->execute();
$query = "DELETE FROM {{question_attributes}} WHERE qid={$qid} and attribute=".Yii::app()->db->quoteValue($reverseAttributeMap[$key]);
Yii::app()->db->createCommand($query)->execute();
}
} }
} }
if (count($updates) > 0)
{
$qupdates[$qid] = $updates;
}
} }
if ($changeDB)
{
$queries = array();
foreach ($qupdates as $qid=>$updates)
{
foreach ($updates as $key=>$value)
{
$query = "UPDATE {{question_attributes}} SET value=".Yii::app()->db->quoteValue($value)." WHERE qid=".$qid." and attribute=".Yii::app()->db->quoteValue($key);
$queries[] = $query;
$query = "DELETE FROM {{question_attributes}} WHERE qid=".$qid." and attribute=".Yii::app()->db->quoteValue($reverseAttributeMap[$key]);
$queries[] = $query;
}
}
// now update the datbase
foreach ($queries as $query)
{
dbExecuteAssoc($query);
}
return $queries;
}
else
{
return $qupdates;
}
} }
/** /**
@ -8297,32 +8284,33 @@ EOD;
function getGroupInfoForEM($surveyid,$lang=NULL) function getGroupInfoForEM($surveyid,$lang=NULL)
{ {
if (!is_null($lang)) { if (is_null($lang) && isset($_SESSION['LEMlang']))
$lang = " and a.language='".$lang."'"; {
$lang = $_SESSION['LEMlang'];
} }
$query = "SELECT a.group_name, a.description, a.gid, a.group_order, a.grelevance" elseif(is_null($lang))
." FROM {{groups}} AS a" {
." WHERE a.sid=".$surveyid $lang=Survey::model()->findByPk($surveyid)->language;
.$lang }
." ORDER BY group_order"; $oQuestionGroups=QuestionGroup::model()->findAll(array('condition'=>"sid=:sid and language=:language",'order'=>'group_order','params'=>array(":sid"=>$surveyid,':language'=>$lang)));
$data = dbExecuteAssoc($query);
$qinfo = array(); $qinfo = array();
$_order=0; $_order=0;
foreach ($data as $d) foreach ($oQuestionGroups as $oQuestionGroup)
{ {
$gid[$d['gid']] = array( $gid[$oQuestionGroup->gid] = array(
'group_order' => $_order, 'group_order' => $_order,
'gid' => $d['gid'], 'gid' => $oQuestionGroup->gid,
'group_name' => $d['group_name'], 'group_name' => $oQuestionGroup->group_name,
'description' => $d['description'], 'description' => $oQuestionGroup->description,
'grelevance' => (!($this->sPreviewMode=='question' || $this->sPreviewMode=='group')) ? $d['grelevance']:1, 'grelevance' => (!($this->sPreviewMode=='question' || $this->sPreviewMode=='group')) ? $oQuestionGroup->grelevance:1,
); );
$qinfo[$_order] = $gid[$d['gid']]; $qinfo[$_order] = $gid[$oQuestionGroup->gid];
++$_order; ++$_order;
} }
if (isset($_SESSION['survey_'.$surveyid]) && isset($_SESSION['survey_'.$surveyid]['grouplist'])) { // Needed for Randomization group.
$groupRemap= (!$this->sPreviewMode && !empty($_SESSION['survey_'.$surveyid]['groupReMap']) && !empty($_SESSION['survey_'.$surveyid]['grouplist']));
if ($groupRemap)
{
$_order=0; $_order=0;
$qinfo = array(); $qinfo = array();
foreach ($_SESSION['survey_'.$surveyid]['grouplist'] as $info) foreach ($_SESSION['survey_'.$surveyid]['grouplist'] as $info)
@ -8332,7 +8320,6 @@ EOD;
++$_order; ++$_order;
} }
} }
return $qinfo; return $qinfo;
} }
@ -8918,7 +8905,6 @@ EOD;
); );
$varNamesUsed = array(); // keeps track of whether variables have been declared $varNamesUsed = array(); // keeps track of whether variables have been declared
if (!is_null($qid)) if (!is_null($qid))
{ {
$surveyMode='question'; $surveyMode='question';
@ -9109,6 +9095,10 @@ EOD;
case 'max_num_of_files': case 'max_num_of_files':
case 'multiflexible_max': case 'multiflexible_max':
case 'multiflexible_min': case 'multiflexible_min':
case 'slider_accuracy':
case 'slider_min':
case 'slider_max':
case 'slider_default':
$value = '{' . $value . '}'; $value = '{' . $value . '}';
break; break;
case 'other_replace_text': case 'other_replace_text':

View file

@ -13,44 +13,53 @@
function loadanswers() function loadanswers()
{ {
Yii::trace('start', 'survey.loadanswers');
global $surveyid; global $surveyid;
global $thissurvey, $thisstep; global $thissurvey, $thisstep;
global $clienttoken; global $clienttoken;
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$scid=returnGlobal('scid',true); $scid=Yii::app()->request->getQuery('scid');
if (Yii::app()->request->getParam('loadall') == "reload") if (Yii::app()->request->getParam('loadall') == "reload")
{ {
$query = "SELECT * FROM {{saved_control}} INNER JOIN {$thissurvey['tablename']} $sLoadName=Yii::app()->request->getParam('loadname');
ON {{saved_control}}.srid = {$thissurvey['tablename']}.id $sLoadPass=Yii::app()->request->getParam('loadpass');
WHERE {{saved_control}}.sid=$surveyid\n"; $oCriteria= new CDbCriteria;
if (isset($scid)) //Would only come from email $oCriteria->join="LEFT JOIN {{saved_control}} ON t.id={{saved_control}}.srid";
$oCriteria->condition="{{saved_control}}.sid=:sid";
$aParams=array(':sid'=>$surveyid);
if (isset($scid)) //Would only come from email : we don't need it ....
{ {
$query .= "AND {{saved_control}}.scid={$scid}\n"; $oCriteria->addCondition("{{saved_control}}.scid=:scid");
$aParams[':scid']=$scid;
} }
$query .="AND {{saved_control}}.identifier = '".autoEscape($_SESSION['survey_'.$surveyid]['holdname'])."' "; $oCriteria->addCondition("{{saved_control}}.identifier=:identifier");
$aParams[':identifier']=$sLoadName;
if (in_array(Yii::app()->db->getDriverName(), array('mssql', 'sqlsrv', 'dblib'))) if (in_array(Yii::app()->db->getDriverName(), array('mssql', 'sqlsrv', 'dblib')))
{ {
$query .="AND CAST({{saved_control}}.access_code as varchar(32))= '".md5($_SESSION['survey_'.$surveyid]['holdpass'])."'\n"; // To be validated with mssql, think it's not needed
$oCriteria->addCondition(" CAST({{saved_control}}.access_code as varchar(32))=:access_code");
} }
else else
{ {
$query .="AND {{saved_control}}.access_code = '".md5($_SESSION['survey_'.$surveyid]['holdpass'])."'\n";// md5 don't need to be escaped $oCriteria->addCondition("{{saved_control}}.access_code=:access_code");
} }
$aParams[':access_code']=md5($sLoadPass);
} }
elseif (isset($_SESSION['survey_'.$surveyid]['srid'])) elseif (isset($_SESSION['survey_'.$surveyid]['srid']))
{ {
$query = "SELECT * FROM {$thissurvey['tablename']} $oCriteria= new CDbCriteria;
WHERE {$thissurvey['tablename']}.id=".$_SESSION['survey_'.$surveyid]['srid']."\n"; $oCriteria->condition="id=:id";
$aParams=array(':id'=>$_SESSION['survey_'.$surveyid]['srid']);
} }
else else
{ {
return; return;
} }
$aRow = Yii::app()->db->createCommand($query)->queryRow();// TODO : use Yii for query $oCriteria->params=$aParams;
if (!$aRow) $oResponses=SurveyDynamic::model($surveyid)->find($oCriteria);
if (!$oResponses)
{ {
return false; return false;
} }
@ -59,8 +68,22 @@ function loadanswers()
//A match has been found. Let's load the values! //A match has been found. Let's load the values!
//If this is from an email, build surveysession first //If this is from an email, build surveysession first
$_SESSION['survey_'.$surveyid]['LEMtokenResume']=true; $_SESSION['survey_'.$surveyid]['LEMtokenResume']=true;
// If survey come from reload (GET or POST); some value need to be found on saved_control, not on survey
if (Yii::app()->request->getParam('loadall') == "reload")
{
$oSavedSurvey=SavedControl::model()->find("identifier=:identifier AND access_code=:access_code",array(":identifier"=>$sLoadName,":access_code"=>md5($sLoadPass)));
// We don't need to control if we have one, because we do the test before
$_SESSION['survey_'.$surveyid]['scid'] = $oSavedSurvey->scid;
$_SESSION['survey_'.$surveyid]['step'] = ($oSavedSurvey->saved_thisstep>1)?$oSavedSurvey->saved_thisstep:1;
$thisstep=$_SESSION['survey_'.$surveyid]['step']-1;// deprecated ?
$_SESSION['survey_'.$surveyid]['srid'] = $oSavedSurvey->srid;// Seems OK without
$_SESSION['survey_'.$surveyid]['refurl'] = $oSavedSurvey->refurl;
}
// Get if survey is been answered // Get if survey is been answered
$submitdate=$aRow['submitdate']; $submitdate=$oResponses->submitdate;
$aRow=$oResponses->attributes;
foreach ($aRow as $column => $value) foreach ($aRow as $column => $value)
{ {
if ($column == "token") if ($column == "token")
@ -68,12 +91,7 @@ function loadanswers()
$clienttoken=$value; $clienttoken=$value;
$token=$value; $token=$value;
} }
elseif ($column == "saved_thisstep" && $thissurvey['alloweditaftercompletion'] != 'Y' ) elseif ($column =='lastpage' && !isset($_SESSION['survey_'.$surveyid]['step']))
{
$_SESSION['survey_'.$surveyid]['step']=($value>1? $value:1) ;
$thisstep=$_SESSION['survey_'.$surveyid]['step']-1;
}
elseif ($column =='lastpage' && isset($_GET['token']))
{ {
if(is_null($submitdate) || $submitdate=="N") if(is_null($submitdate) || $submitdate=="N")
{ {
@ -95,14 +113,6 @@ function loadanswers()
UpdateSessionGroupList($value); // to refresh the language strings in the group list session variable UpdateSessionGroupList($value); // to refresh the language strings in the group list session variable
UpdateFieldArray(); // to refresh question titles and question text UpdateFieldArray(); // to refresh question titles and question text
}*/ }*/
elseif ($column == "scid")
{
$_SESSION['survey_'.$surveyid]['scid']=$value;
}
elseif ($column == "srid")
{
$_SESSION['survey_'.$surveyid]['srid']=$value;
}
elseif ($column == "datestamp") elseif ($column == "datestamp")
{ {
$_SESSION['survey_'.$surveyid]['datestamp']=$value; $_SESSION['survey_'.$surveyid]['datestamp']=$value;
@ -133,8 +143,8 @@ function loadanswers()
} // if (in_array( } // if (in_array(
} // else } // else
} // foreach } // foreach
return true;
} }
return true;
} }
function makegraph($currentstep, $total) function makegraph($currentstep, $total)
@ -465,9 +475,9 @@ function submittokens($quotaexit=false)
$today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust")); $today = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i", Yii::app()->getConfig("timeadjust"));
// check how many uses the token has left // check how many uses the token has left
$token = Token::model($surveyid)->findByAttributes(array('token' => $clienttoken)); $token = Token::model($surveyid)->findByAttributes(array('token' => $clienttoken));
if ($quotaexit==true) if ($quotaexit==true)
{ {
$token->completed = 'Q'; $token->completed = 'Q';
$token->usesleft--; $token->usesleft--;
@ -510,7 +520,6 @@ function submittokens($quotaexit=false)
// if($token->completed == "Y" || $token->completed == $today) // if($token->completed == "Y" || $token->completed == $today)
// { // {
$from = "{$thissurvey['adminname']} <{$thissurvey['adminemail']}>"; $from = "{$thissurvey['adminname']} <{$thissurvey['adminemail']}>";
$to = $token->email;
$subject=$thissurvey['email_confirm_subj']; $subject=$thissurvey['email_confirm_subj'];
$aReplacementVars=array(); $aReplacementVars=array();
@ -534,7 +543,7 @@ function submittokens($quotaexit=false)
$dateformatdatat=getDateFormatData($thissurvey['surveyls_dateformat']); $dateformatdatat=getDateFormatData($thissurvey['surveyls_dateformat']);
$numberformatdatat = getRadixPointData($thissurvey['surveyls_numberformat']); $numberformatdatat = getRadixPointData($thissurvey['surveyls_numberformat']);
$redata=array('thissurvey'=>$thissurvey); $redata=array('thissurvey'=>$thissurvey);
$subject=templatereplace($subject,$aReplacementVars,$redata); $subject=templatereplace($subject,$aReplacementVars,$redata,'',false,null,array(),true);
$subject=html_entity_decode($subject,ENT_QUOTES,$emailcharset); $subject=html_entity_decode($subject,ENT_QUOTES,$emailcharset);
@ -549,7 +558,7 @@ function submittokens($quotaexit=false)
$message=$thissurvey['email_confirm']; $message=$thissurvey['email_confirm'];
//$message=ReplaceFields($message, $fieldsarray, true); //$message=ReplaceFields($message, $fieldsarray, true);
$message=templatereplace($message,$aReplacementVars,$redata); $message=templatereplace($message,$aReplacementVars,$redata,'',false,null,array(),true);
if (!$ishtml) if (!$ishtml)
{ {
$message=strip_tags(breakToNewline(html_entity_decode($message,ENT_QUOTES,$emailcharset))); $message=strip_tags(breakToNewline(html_entity_decode($message,ENT_QUOTES,$emailcharset)));
@ -560,7 +569,8 @@ function submittokens($quotaexit=false)
} }
//Only send confirmation email if there is a valid email address //Only send confirmation email if there is a valid email address
if (validateEmailAddress($to)) { $sToAddress=validateEmailAddresses($token->email);
if ($sToAddress) {
$aAttachments = unserialize($thissurvey['attachments']); $aAttachments = unserialize($thissurvey['attachments']);
$aRelevantAttachments = array(); $aRelevantAttachments = array();
@ -579,7 +589,7 @@ function submittokens($quotaexit=false)
} }
} }
} }
SendEmailMessage($message, $subject, $to, $from, $sitename, $ishtml, null, $aRelevantAttachments); SendEmailMessage($message, $subject, $sToAddress, $from, $sitename, $ishtml, null, $aRelevantAttachments);
} }
// } else { // } else {
// Leave it to send optional confirmation at closed token // Leave it to send optional confirmation at closed token
@ -610,7 +620,7 @@ function sendSubmitNotifications($surveyid)
$aReplacementVars=array(); $aReplacementVars=array();
if ($thissurvey['allowsave'] == "Y" && isset($_SESSION['survey_'.$surveyid]['scid'])) if ($thissurvey['allowsave'] == "Y" && isset($_SESSION['survey_'.$surveyid]['scid']) && isset($_SESSION['survey_'.$surveyid]['holdname']))
{ {
$aReplacementVars['RELOADURL']="".Yii::app()->getController()->createUrl("/survey/index/sid/{$surveyid}/loadall/reload/scid/".$_SESSION['survey_'.$surveyid]['scid']."/loadname/".urlencode($_SESSION['survey_'.$surveyid]['holdname'])."/loadpass/".urlencode($_SESSION['survey_'.$surveyid]['holdpass'])."/lang/".urlencode($clang->langcode)); $aReplacementVars['RELOADURL']="".Yii::app()->getController()->createUrl("/survey/index/sid/{$surveyid}/loadall/reload/scid/".$_SESSION['survey_'.$surveyid]['scid']."/loadname/".urlencode($_SESSION['survey_'.$surveyid]['holdname'])."/loadpass/".urlencode($_SESSION['survey_'.$surveyid]['holdpass'])."/lang/".urlencode($clang->langcode));
if ($bIsHTML) if ($bIsHTML)
@ -648,6 +658,7 @@ function sendSubmitNotifications($surveyid)
$aRecipient=explode(";", ReplaceFields($thissurvey['emailnotificationto'],array('ADMINEMAIL' =>$thissurvey['adminemail'] ), true)); $aRecipient=explode(";", ReplaceFields($thissurvey['emailnotificationto'],array('ADMINEMAIL' =>$thissurvey['adminemail'] ), true));
foreach($aRecipient as $sRecipient) foreach($aRecipient as $sRecipient)
{ {
$sRecipient=trim($sRecipient);
if(validateEmailAddress($sRecipient)) if(validateEmailAddress($sRecipient))
{ {
$aEmailNotificationTo[]=$sRecipient; $aEmailNotificationTo[]=$sRecipient;
@ -666,6 +677,7 @@ function sendSubmitNotifications($surveyid)
$aRecipient=explode(";", ReplaceFields($thissurvey['emailresponseto'],array('ADMINEMAIL' =>$thissurvey['adminemail'] ), true)); $aRecipient=explode(";", ReplaceFields($thissurvey['emailresponseto'],array('ADMINEMAIL' =>$thissurvey['adminemail'] ), true));
foreach($aRecipient as $sRecipient) foreach($aRecipient as $sRecipient)
{ {
$sRecipient=trim($sRecipient);
if(validateEmailAddress($sRecipient)) if(validateEmailAddress($sRecipient))
{ {
$aEmailResponseTo[]=$sRecipient; $aEmailResponseTo[]=$sRecipient;
@ -681,18 +693,17 @@ function sendSubmitNotifications($surveyid)
{ {
if (substr($sFieldname,0,4)=='gid_') if (substr($sFieldname,0,4)=='gid_')
{ {
$ResultTableHTML .= "\t<tr class='printanswersgroup'><td colspan='2'>".strip_tags($fname[0])."</td></tr>\n";
$ResultTableHTML .= "\t<tr class='printanswersgroup'><td colspan='2'>{$fname[0]}</td></tr>\n";
$ResultTableText .="\n{$fname[0]}\n\n"; $ResultTableText .="\n{$fname[0]}\n\n";
} }
elseif (substr($sFieldname,0,4)=='qid_') elseif (substr($sFieldname,0,4)=='qid_')
{ {
$ResultTableHTML .= "\t<tr class='printanswersquestionhead'><td colspan='2'>{$fname[0]}</td></tr>\n"; $ResultTableHTML .= "\t<tr class='printanswersquestionhead'><td colspan='2'>".strip_tags($fname[0])."</td></tr>\n";
$ResultTableText .="\n{$fname[0]}\n"; $ResultTableText .="\n{$fname[0]}\n";
} }
else else
{ {
$ResultTableHTML .= "\t<tr class='printanswersquestion'><td>{$fname[0]} {$fname[1]}</td><td class='printanswersanswertext'>{$fname[2]}</td></tr>"; $ResultTableHTML .= "\t<tr class='printanswersquestion'><td>".strip_tags("{$fname[0]} {$fname[1]}")."</td><td class='printanswersanswertext'>".CHtml::encode($fname[2])."</td></tr>\n";
$ResultTableText .=" {$fname[0]} {$fname[1]}: {$fname[2]}\n"; $ResultTableText .=" {$fname[0]} {$fname[1]}: {$fname[2]}\n";
} }
} }
@ -765,8 +776,8 @@ function sendSubmitNotifications($surveyid)
} }
if (count($aEmailResponseTo)>0) if (count($aEmailResponseTo)>0)
{ {
$sMessage=templatereplace($thissurvey['email_admin_responses'],$aReplacementVars,$redata,'frontend_helper[1414]',($thissurvey['anonymized'] == "Y")); $sMessage=templatereplace($thissurvey['email_admin_responses'],$aReplacementVars,$redata,'frontend_helper[1414]',($thissurvey['anonymized'] == "Y"),NULL, array(), true);
$sSubject=templatereplace($thissurvey['email_admin_responses_subj'],$aReplacementVars,$redata,'frontend_helper[1415]',($thissurvey['anonymized'] == "Y")); $sSubject=templatereplace($thissurvey['email_admin_responses_subj'],$aReplacementVars,$redata,'frontend_helper[1415]',($thissurvey['anonymized'] == "Y"),NULL, array(), true);
foreach ($aEmailResponseTo as $sRecipient) foreach ($aEmailResponseTo as $sRecipient)
{ {
if (!SendEmailMessage($sMessage, $sSubject, $sRecipient, $sFrom, $sitename, true, getBounceEmail($surveyid), $aRelevantAttachments)) if (!SendEmailMessage($sMessage, $sSubject, $sRecipient, $sFrom, $sitename, true, getBounceEmail($surveyid), $aRelevantAttachments))
@ -834,6 +845,7 @@ function submitfailed($errormsg='')
*/ */
function buildsurveysession($surveyid,$preview=false) function buildsurveysession($surveyid,$preview=false)
{ {
Yii::trace('start', 'survey.buildsurveysession');
global $secerror, $clienttoken; global $secerror, $clienttoken;
global $tokensexist; global $tokensexist;
//global $surveyid; //global $surveyid;
@ -844,7 +856,7 @@ function buildsurveysession($surveyid,$preview=false)
$languagechanger=makeLanguageChangerSurvey($sLangCode); $languagechanger=makeLanguageChangerSurvey($sLangCode);
if(!$preview) if(!$preview)
$preview=Yii::app()->getConfig('previewmode'); $preview=Yii::app()->getConfig('previewmode');
$thissurvey = getSurveyInfo($surveyid,$sLangCode); $thissurvey = getSurveyInfo($surveyid,$sLangCode);
$_SESSION['survey_'.$surveyid]['templatename']=validateTemplateDir($thissurvey['template']); $_SESSION['survey_'.$surveyid]['templatename']=validateTemplateDir($thissurvey['template']);
$_SESSION['survey_'.$surveyid]['templatepath']=getTemplatePath($_SESSION['survey_'.$surveyid]['templatename']).DIRECTORY_SEPARATOR; $_SESSION['survey_'.$surveyid]['templatepath']=getTemplatePath($_SESSION['survey_'.$surveyid]['templatename']).DIRECTORY_SEPARATOR;
@ -1001,12 +1013,12 @@ function buildsurveysession($surveyid,$preview=false)
//check if token actually does exist //check if token actually does exist
// check also if it is allowed to change survey after completion // check also if it is allowed to change survey after completion
if ($thissurvey['alloweditaftercompletion'] == 'Y' ) { if ($thissurvey['alloweditaftercompletion'] == 'Y' ) {
$oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=>$clienttoken)); $oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=>$clienttoken));
} else { } else {
$oTokenEntry = Token::model($surveyid)->usable()->incomplete()->findByAttributes(array('token' => $clienttoken)); $oTokenEntry = Token::model($surveyid)->usable()->incomplete()->findByAttributes(array('token' => $clienttoken));
} }
if (!isset($oTokenEntry)) if (!isset($oTokenEntry))
{ {
//TOKEN DOESN'T EXIST OR HAS ALREADY BEEN USED. EXPLAIN PROBLEM AND EXIT //TOKEN DOESN'T EXIST OR HAS ALREADY BEEN USED. EXPLAIN PROBLEM AND EXIT
@ -1038,15 +1050,15 @@ function buildsurveysession($surveyid,$preview=false)
isset($_SESSION['survey_'.$surveyid]['secanswer']) && isset($_SESSION['survey_'.$surveyid]['secanswer']) &&
$loadsecurity == $_SESSION['survey_'.$surveyid]['secanswer']) $loadsecurity == $_SESSION['survey_'.$surveyid]['secanswer'])
{ {
if ($thissurvey['alloweditaftercompletion'] == 'Y' ) if ($thissurvey['alloweditaftercompletion'] == 'Y' )
{ {
$oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=> $clienttoken)); $oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=> $clienttoken));
} }
else else
{ {
$oTokenEntry = Token::model($surveyid)->incomplete()->findByAttributes(array( $oTokenEntry = Token::model($surveyid)->incomplete()->findByAttributes(array(
'token' => $clienttoken 'token' => $clienttoken
)); ));
} }
if (!isset($oTokenEntry)) if (!isset($oTokenEntry))
{ {
@ -1168,26 +1180,16 @@ function buildsurveysession($surveyid,$preview=false)
unset($_SESSION['survey_'.$surveyid]['groupReMap']); unset($_SESSION['survey_'.$surveyid]['groupReMap']);
$_SESSION['survey_'.$surveyid]['fieldnamesInfo'] = Array(); $_SESSION['survey_'.$surveyid]['fieldnamesInfo'] = Array();
// Multi lingual support order : by REQUEST, if not by Token->language else by survey default language
//RL: multilingual support
if (isset($_GET['token']) && tableExists('{{tokens_'.$surveyid.'}}'))
{
//get language from token (if one exists)
$tkquery2 = "SELECT * FROM {{tokens_".$surveyid."}} WHERE token='".$clienttoken."' AND (completed = 'N' or completed='')";
//echo $tkquery2;
$result = dbExecuteAssoc($tkquery2) or safeDie ("Couldn't get tokens<br />$tkquery<br />"); //Checked
foreach ($result->readAll() as $rw)
{
$tklanguage=$rw['language'];
}
}
if (returnGlobal('lang',true)) if (returnGlobal('lang',true))
{ {
$language_to_set=returnGlobal('lang',true); $language_to_set=returnGlobal('lang',true);
} elseif (isset($tklanguage)) }
elseif (isset($oTokenEntry) && $oTokenEntry)
{ {
$language_to_set=$tklanguage; // If survey have token : we have a $oTokenEntry
// Can use $oTokenEntry = Token::model($surveyid)->findByAttributes(array('token'=>$clienttoken)); if we move on another function : this par don't validate the token validity
$language_to_set=$oTokenEntry->language;
} }
else else
{ {
@ -1240,7 +1242,7 @@ function buildsurveysession($surveyid,$preview=false)
} }
if ($totalquestions == 0) //break out and crash if there are no questions! if ($totalquestions == 0) //break out and crash if there are no questions!
{ {
sendCacheHeaders(); sendCacheHeaders();
doHeader(); doHeader();
@ -1263,7 +1265,7 @@ function buildsurveysession($surveyid,$preview=false)
} }
//Perform a case insensitive natural sort on group name then question title of a multidimensional array //Perform a case insensitive natural sort on group name then question title of a multidimensional array
// usort($arows, 'groupOrderThenQuestionOrder'); // usort($arows, 'groupOrderThenQuestionOrder');
//3. SESSION VARIABLE - insertarray //3. SESSION VARIABLE - insertarray
//An array containing information about used to insert the data into the db at the submit stage //An array containing information about used to insert the data into the db at the submit stage
@ -1480,17 +1482,17 @@ function buildsurveysession($surveyid,$preview=false)
$_SESSION['survey_'.$surveyid]['insertarray'][]=$field['fieldname']; $_SESSION['survey_'.$surveyid]['insertarray'][]=$field['fieldname'];
//fieldarray ARRAY CONTENTS - //fieldarray ARRAY CONTENTS -
// [0]=questions.qid, // [0]=questions.qid,
// [1]=fieldname, // [1]=fieldname,
// [2]=questions.title, // [2]=questions.title,
// [3]=questions.question // [3]=questions.question
// [4]=questions.type, // [4]=questions.type,
// [5]=questions.gid, // [5]=questions.gid,
// [6]=questions.mandatory, // [6]=questions.mandatory,
// [7]=conditionsexist, // [7]=conditionsexist,
// [8]=usedinconditions // [8]=usedinconditions
// [8]=usedinconditions // [8]=usedinconditions
// [9]=used in group.php for question count // [9]=used in group.php for question count
// [10]=new group id for question in randomization group (GroupbyGroup Mode) // [10]=new group id for question in randomization group (GroupbyGroup Mode)
if (!isset($_SESSION['survey_'.$surveyid]['fieldarray'][$field['sid'].'X'.$field['gid'].'X'.$field['qid']])) if (!isset($_SESSION['survey_'.$surveyid]['fieldarray'][$field['sid'].'X'.$field['gid'].'X'.$field['qid']]))
{ {
@ -1544,22 +1546,22 @@ function buildsurveysession($surveyid,$preview=false)
$startingValues=array(); $startingValues=array();
if (isset($_GET)) if (isset($_GET))
{ {
foreach ($_GET as $k=>$v) foreach ($_GET as $k=>$v)
{ {
if (!in_array($k,$reservedGetValues) && isset($_SESSION['survey_'.$surveyid]['fieldmap'][$k])) if (!in_array($k,$reservedGetValues) && isset($_SESSION['survey_'.$surveyid]['fieldmap'][$k]))
{ {
$startingValues[$k] = $v; $startingValues[$k] = $v;
} }
else else
{ // Search question codes to use those for prefilling. { // Search question codes to use those for prefilling.
foreach($_SESSION['survey_'.$surveyid]['fieldmap'] as $sgqa => $details) foreach($_SESSION['survey_'.$surveyid]['fieldmap'] as $sgqa => $details)
{ {
if ($details['title'] == $k) if ($details['title'] == $k)
{ {
$startingValues[$sgqa] = $v; $startingValues[$sgqa] = $v;
} }
} }
} }
} }
} }
$_SESSION['survey_'.$surveyid]['startingValues']=$startingValues; $_SESSION['survey_'.$surveyid]['startingValues']=$startingValues;
@ -1598,6 +1600,7 @@ function buildsurveysession($surveyid,$preview=false)
} }
} }
} }
Yii::trace('end', 'survey.buildsurveysession');
} }
/** /**
@ -1881,12 +1884,12 @@ function UpdateGroupList($surveyid, $language)
*/ */
function UpdateFieldArray() function UpdateFieldArray()
{ {
global $surveyid; global $surveyid;
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
if (isset($_SESSION['survey_'.$surveyid]['fieldarray'])) if (isset($_SESSION['survey_'.$surveyid]['fieldarray']))
{ {
foreach ($_SESSION['survey_'.$surveyid]['fieldarray'] as $key => $value) foreach ($_SESSION['survey_'.$surveyid]['fieldarray'] as $key => $value)
{ {
$questionarray = &$_SESSION['survey_'.$surveyid]['fieldarray'][$key]; $questionarray = &$_SESSION['survey_'.$surveyid]['fieldarray'][$key];
$query = "SELECT title, question FROM {{questions}} WHERE qid=".$questionarray[0]." AND language='".$_SESSION['survey_'.$surveyid]['s_lang']."'"; $query = "SELECT title, question FROM {{questions}} WHERE qid=".$questionarray[0]." AND language='".$_SESSION['survey_'.$surveyid]['s_lang']."'";
@ -1902,217 +1905,147 @@ function UpdateFieldArray()
} }
/** /**
* checkQuota() returns quota information for the current survey * checkCompletedQuota() returns matched quotas information for the current response
* @param string $checkaction - action the function must take after completing: * @param integer $surveyid - Survey identification number
* enforce: Enforce the Quota action * @param bool $return - set to true to return information, false do the quota
* return: Return the updated quota array from getQuotaAnswers() * @return array - nested array, Quotas->Members->Fields, includes quota information matched in session.
* @param string $surveyid - Survey identification number
* @return array - nested array, Quotas->Members->Fields, includes quota status and which members matched in session.
*/ */
function checkQuota($checkaction,$surveyid) function checkCompletedQuota($surveyid,$return=false)
{ {
global $clienttoken ;
if (!isset($_SESSION['survey_'.$surveyid]['srid'])) if (!isset($_SESSION['survey_'.$surveyid]['srid']))
{ {
return; return;
} }
$thissurvey=getSurveyInfo($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']); static $aMatchedQuotas; // EM call 2 times quotas with 3 lines of php code, then use static.
$sTemplatePath=getTemplatePath($thissurvey['templatedir']); if(!$aMatchedQuotas)
$global_matched = false;
$quota_info = getQuotaInformation($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']);
$x=0;
$clang = Yii::app()->lang;
if(count($quota_info) > 0) // Quota's have to exist
{ {
// Check each quota on saved data to see if it is full $aMatchedQuotas=array();
$querycond = array(); $quota_info=$aQuotasInfo = getQuotaInformation($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']);
foreach ($quota_info as $quota) // $aQuotasInfo have an 'active' key, we don't use it ?
if(!$aQuotasInfo || empty($aQuotasInfo))
return $aMatchedQuotas;
// OK, we have some quota, then find if this $_SESSION have some set
$aPostedFields = explode("|",Yii::app()->request->getPost('fieldnames','')); // Needed for quota allowing update
foreach ($aQuotasInfo as $aQuotaInfo)
{ {
if (count($quota['members']) > 0) // Quota can't be empty $iMatchedAnswers=0;
$bPostedField=false;
// Array of field with quota array value
$aQuotaFields=array();
// Array of fieldnames with relevance value : EM fill $_SESSION with default value even is unrelevant (em_manager_helper line 6548)
$aQuotaRelevantFieldnames=array();
foreach ($aQuotaInfo['members'] as $aQuotaMember)
{ {
$fields_list = array(); // Keep a list of fields for easy reference $aQuotaFields[$aQuotaMember['fieldname']][] = $aQuotaMember['value'];
$y=0; $aQuotaRelevantFieldnames[$aQuotaMember['fieldname']]=isset($_SESSION['survey_'.$surveyid]['relevanceStatus'][$aQuotaMember['qid']]) && $_SESSION['survey_'.$surveyid]['relevanceStatus'][$aQuotaMember['qid']];
// We need to make the conditions for the select statement here }
unset($querycond); // For each field : test if actual responses is in quota (and is relevant)
// fill the array of value and query for each fieldnames foreach ($aQuotaFields as $sFieldName=>$aValues)
$fields_value_array = array(); {
$fields_query_array = array(); $bInQuota=isset($_SESSION['survey_'.$surveyid][$sFieldName]) && in_array($_SESSION['survey_'.$surveyid][$sFieldName],$aValues);
foreach($quota['members'] as $member) if($bInQuota && $aQuotaRelevantFieldnames[$sFieldName])
{ {
foreach($member['fieldnames'] as $fieldname) $iMatchedAnswers++;
{
if (!in_array($fieldname,$fields_list))
{
$fields_list[] = $fieldname;
$fields_value_array[$fieldname] = array();
$fields_query_array[$fieldname] = array();
}
$fields_value_array[$fieldname][]=$member['value'];
$fields_query_array[$fieldname][]= dbQuoteID($fieldname)." = '{$member['value']}'";
}
} }
if(in_array($sFieldName,$aPostedFields))// Need only one posted value
// fill the $querycond array with each fields_query grouped by fieldname $bPostedField=true;
foreach($fields_list as $fieldname) }
{ // Count only needed quotas
$select_query = " ( ".implode(' OR ',$fields_query_array[$fieldname]).' )'; if($iMatchedAnswers==count($aQuotaFields) && ( $aQuotaInfo['action']!=2 || $bPostedField ) )
$querycond[] = $select_query; {
} if((int)$aQuotaInfo['qlimit'] < 1){
// Test if the fieldname is in the array of value in the session $aMatchedQuotas[]=$aQuotaInfo;
foreach($quota['members'] as $member) }else{
{ $iCompleted=getQuotaCompletedCount($surveyid, $aQuotaInfo['id']);// Return a string
foreach($member['fieldnames'] as $fieldname) if(ctype_digit($iCompleted) && ((int)$iCompleted >= (int)$aQuotaInfo['qlimit'])) // This remove invalid quota and not completed
{ $aMatchedQuotas[]=$aQuotaInfo;
if (isset($_SESSION['survey_'.$surveyid][$fieldname]))
{
if (in_array($_SESSION['survey_'.$surveyid][$fieldname],$fields_value_array[$fieldname])){
$quota_info[$x]['members'][$y]['insession'] = "true";
}
}
}
$y++;
}
unset($fields_query_array);unset($fields_value_array);
// Lets only continue if any of the quota fields is in the posted page
$matched_fields = false;
if (isset($_POST['fieldnames']))
{
$posted_fields = explode("|",$_POST['fieldnames']);
foreach ($fields_list as $checkfield)
{
if (in_array($checkfield,$posted_fields))
{
$matched_fields = true;
$global_matched = true;
}
}
}
// A field was submitted that is part of the quota
if ($matched_fields == true)
{
// Check the status of the quota, is it full or not
$sQuery = "SELECT count(id) FROM {{survey_".$surveyid."}}
WHERE ".implode(' AND ',$querycond)." "."
AND submitdate IS NOT NULL";
$iRowCount = Yii::app()->db->createCommand($sQuery)->queryScalar();
if ($iRowCount >= $quota['Limit']) // Quota is full!!
{
// Now we have to check if the quota matches in the current session
// This will let us know if this person is going to exceed the quota
$counted_matches = 0;
foreach($quota_info[$x]['members'] as $member)
{
if (isset($member['insession']) && $member['insession'] == "true") $counted_matches++;
}
if($counted_matches == count($quota['members']))
{
// They are going to exceed the quota if data is submitted
$quota_info[$x]['status']="matched";
}
else
{
$quota_info[$x]['status']="notmatched";
}
}
else
{
// Quota is no in danger of being exceeded.
$quota_info[$x]['status']="notmatched";
}
} }
} }
$x++;
} }
} }
else if ($return)
{ return $aMatchedQuotas;
return false; if(empty($aMatchedQuotas))
} return;
// Now we have all the information we need about the quotas and their status. // Now we have all the information we need about the quotas and their status.
// Lets see what we should do now // We need to construct the page and do all needed action
if ($checkaction == 'return') $aSurveyInfo=getSurveyInfo($surveyid, $_SESSION['survey_'.$surveyid]['s_lang']);
$sTemplatePath=getTemplatePath($aSurveyInfo['templatedir']);
$sClientToken=isset($_SESSION['survey_'.$surveyid]['token'])?$_SESSION['survey_'.$surveyid]['token']:"";// {TOKEN} is take by $redata ...
// $redata for templatereplace
$aDataReplacement = array(
'thissurvey'=>$aSurveyInfo,
'clienttoken'=>$sClientToken,
'token'=>$sClientToken,
);
// We take only the first matched quota, no need for each
$aMatchedQuota=$aMatchedQuotas[0];
// If a token is used then mark the token as completed, do it before event : this allow plugin to update token information
$event = new PluginEvent('afterSurveyQuota');
$event->set('surveyId', $surveyid);
$event->set('responseId', $_SESSION['survey_'.$surveyid]['srid']);// We allways have a responseId
$event->set('aMatchedQuotas', $aMatchedQuotas);// Give all the matched quota : the first is the active
App()->getPluginManager()->dispatchEvent($event);
$blocks = array();
foreach ($event->getAllContent() as $blockData)
{ {
return $quota_info; /* @var $blockData PluginEventContent */
$blocks[] = CHtml::tag('div', array('id' => $blockData->getCssId(), 'class' => $blockData->getCssClass()), $blockData->getContent());
} }
elseif ($global_matched == true && $checkaction == 'enforce') // Allow plugin to update message, url, url description and action
$sMessage=$event->get('message',$aMatchedQuota['quotals_message']);
$sUrl=$event->get('url',$aMatchedQuota['quotals_url']);
$sUrlDescription=$event->get('urldescrip',$aMatchedQuota['quotals_urldescrip']);
$sAction=$event->get('action',$aMatchedQuota['action']);
$sAutoloadUrl=$event->get('autoloadurl',$aMatchedQuota['autoload_url']);
// Construct the default message
$sMessage = templatereplace($sMessage,array(),$aDataReplacement, 'QuotaMessage', $aSurveyInfo['anonymized']!='N', NULL, array(), true );
$sUrl = passthruReplace($sUrl, $aSurveyInfo);
$sUrl = templatereplace($sUrl,array(),$aDataReplacement, 'QuotaUrl', $aSurveyInfo['anonymized']!='N', NULL, array(), true );
$sUrlDescription = templatereplace($sUrlDescription,array(),$aDataReplacement, 'QuotaUrldescription', $aSurveyInfo['anonymized']!='N', NULL, array(), true );
// Doing the action and show the page
if ($sAction == "1" && $sClientToken)
submittokens(true);
// Construction of default message inside quotamessage class
$quotaMessage = "<div class='quotamessage limesurveycore'>\n";
$quotaMessage.= "\t".$sMessage."\n";
if($sUrl)
$quotaMessage.= "<br /><br />\t<a href='".$sUrl."'>".$sUrlDescription."</a><br />\n";
// Add the navigator with Previous button if quota allow modification.
if ($sAction == "2")
{ {
// Need to add Quota action enforcement here. $sQuotaStep= isset($_SESSION['survey_'.$surveyid]['step'])?$_SESSION['survey_'.$surveyid]['step']:0; // Surely not needed
reset($quota_info); $sNavigator = CHtml::htmlButton(gT("Previous"),array('type'=>'submit','id'=>"moveprevbtn",'value'=>$sQuotaStep,'name'=>'move','accesskey'=>'p','class'=>"submit button"));
$quotaMessage.= CHtml::form(array("/survey/index"), 'post', array('id'=>'limesurvey','name'=>'limesurvey'));
$quotaMessage.= templatereplace(file_get_contents($sTemplatePath."/navigator.pstpl"),array('NAVIGATOR'=>$sNavigator,'SAVE'=>''),$aDataReplacement);
$quotaMessage.= CHtml::hiddenField('sid',$surveyid);
$quotaMessage.= CHtml::hiddenField('token',$sClientToken);// Did we really need it ?
$quotaMessage.= CHtml::endForm();
}
$quotaMessage.= "</div>\n";
// Add the plugin message before default message
$quotaMessage = implode("\n", $blocks) ."\n". $quotaMessage;
$tempmsg =""; // Send page to user and end.
$found = false; sendCacheHeaders();
$redata = compact(array_keys(get_defined_vars())); if($sAutoloadUrl == 1 && $sUrl != "")
foreach($quota_info as $quota) {
{ if ($sAction == "1")
$quota['Message'] = templatereplace($quota['Message'],array(),$redata);
$quota['Url'] = passthruReplace($quota['Url'], $thissurvey);
$quota['Url'] = templatereplace($quota['Url'],array(),$redata);
$quota['UrlDescrip'] = templatereplace($quota['UrlDescrip'],array(),$redata);
if ((isset($quota['status']) && $quota['status'] == "matched") && (isset($quota['Action']) && $quota['Action'] == "1"))
{
// If a token is used then mark the token as completed
if (isset($clienttoken) && $clienttoken)
{
submittokens(true);
}
sendCacheHeaders();
if($quota['AutoloadUrl'] == 1 && $quota['Url'] != "")
{
header("Location: ".$quota['Url']);
killSurveySession($surveyid);
}
doHeader();
echo templatereplace(file_get_contents($sTemplatePath."/startpage.pstpl"),array(),$redata,'frontend_helper[2617]');
echo "\t<div class='quotamessage'>\n";
echo "\t".$quota['Message']."<br /><br />\n";
echo "\t<a href='".$quota['Url']."'>".$quota['UrlDescrip']."</a><br />\n";
echo "\t</div>\n";
echo templatereplace(file_get_contents($sTemplatePath."/endpage.pstpl"),array(),$redata,'frontend_helper[2622]');
doFooter();
killSurveySession($surveyid); killSurveySession($surveyid);
exit; header("Location: ".$sUrl);
}
if ((isset($quota['status']) && $quota['status'] == "matched") && (isset($quota['Action']) && $quota['Action'] == "2"))
{
sendCacheHeaders();
doHeader();
$redata = compact(array_keys(get_defined_vars()));
echo templatereplace(file_get_contents($sTemplatePath."/startpage.pstpl"),array(),$redata,'frontend_helper[2634]');
echo "\t<div class='quotamessage'>\n";
echo "\t".$quota['Message']."<br /><br />\n";
echo "\t<a href='".$quota['Url']."'>".$quota['UrlDescrip']."</a><br />\n";
echo CHtml::form(array("/survey/index"), 'post', array('id'=>'limesurvey','name'=>'limesurvey'))."
<input type='hidden' name='move' value='movenext' id='movenext' />
<button class='nav-button nav-button-icon-left ui-corner-all' class='submit' accesskey='p' onclick=\"javascript:document.limesurvey.move.value = 'moveprev'; document.limesurvey.submit();\" id='moveprevbtn'>".$clang->gT("Previous")."</button>
<input type='hidden' name='thisstep' value='".($_SESSION['survey_'.$surveyid]['step'])."' id='thisstep' />
<input type='hidden' name='sid' value='".returnGlobal('sid',true)."' id='sid' />
<input type='hidden' name='token' value='".$clienttoken."' id='token' />
</form>\n";
echo "\t</div>\n";
echo templatereplace(file_get_contents($sTemplatePath."/endpage.pstpl"),array(),$redata,'frontend_helper[2644]');
doFooter();
exit;
}
}
}
else
{
// Unknown value
return false;
} }
doHeader();
echo templatereplace(file_get_contents($sTemplatePath."/startpage.pstpl"),array(),$aDataReplacement);
echo $quotaMessage;
echo templatereplace(file_get_contents($sTemplatePath."/endpage.pstpl"),array(),$aDataReplacement);
doFooter();
if ($sAction == "1")
killSurveySession($surveyid);
Yii::app()->end();
} }
/** /**
@ -2163,21 +2096,14 @@ function GetReferringUrl()
// read it from server variable // read it from server variable
if(isset($_SERVER["HTTP_REFERER"])) if(isset($_SERVER["HTTP_REFERER"]))
{ {
if(!preg_match('/'.$_SERVER["SERVER_NAME"].'/', $_SERVER["HTTP_REFERER"])) if (!Yii::app()->getConfig('strip_query_from_referer_url'))
{ {
if (!Yii::app()->getConfig('strip_query_from_referer_url')) return $_SERVER["HTTP_REFERER"];
{
return $_SERVER["HTTP_REFERER"];
}
else
{
$aRefurl = explode("?",$_SERVER["HTTP_REFERER"]);
return $aRefurl[0];
}
} }
else else
{ {
return '-'; $aRefurl = explode("?",$_SERVER["HTTP_REFERER"]);
return $aRefurl[0];
} }
} }
else else
@ -2191,7 +2117,7 @@ function GetReferringUrl()
*/ */
function display_first_page() { function display_first_page() {
global $token, $surveyid, $thissurvey, $navigator; global $token, $surveyid, $thissurvey, $navigator;
$totalquestions = $_SESSION['survey_'.$surveyid]['totalquestions']; $totalquestions = $_SESSION['survey_'.$surveyid]['totalquestions'];
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
@ -2296,7 +2222,6 @@ function SetSurveyLanguage($surveyid, $language)
$clang = new limesurvey_lang($_SESSION['survey_'.$surveyid]['s_lang']); $clang = new limesurvey_lang($_SESSION['survey_'.$surveyid]['s_lang']);
$thissurvey=getSurveyInfo($surveyid, @$_SESSION['survey_'.$surveyid]['s_lang']); $thissurvey=getSurveyInfo($surveyid, @$_SESSION['survey_'.$surveyid]['s_lang']);
Yii::app()->loadHelper('surveytranslator'); Yii::app()->loadHelper('surveytranslator');
$_SESSION['dateformats'] = getDateFormatData($thissurvey['surveyls_dateformat'],$_SESSION['survey_'.$surveyid]['s_lang']);
LimeExpressionManager::SetEMLanguage($_SESSION['survey_'.$surveyid]['s_lang']); LimeExpressionManager::SetEMLanguage($_SESSION['survey_'.$surveyid]['s_lang']);
} }
else else

View file

@ -36,8 +36,7 @@ class pdfHelper
{ {
$pdffont=PDF_FONT_NAME_DATA; $pdffont=PDF_FONT_NAME_DATA;
} }
$pdfcorefont=array("courier","helvetica","symbol","times","zapfdingbats"); $pdfcorefont=array("freesans","dejavusans","courier","helvetica","freemono","symbol","times","zapfdingbats");
$pdffontsize=Yii::app()->getConfig('pdffontsize');
if (in_array($pdffont,$pdfcorefont)) if (in_array($pdffont,$pdfcorefont))
{ {
$alternatepdffontfile=Yii::app()->getConfig('alternatepdffontfile'); $alternatepdffontfile=Yii::app()->getConfig('alternatepdffontfile');
@ -46,6 +45,7 @@ class pdfHelper
$pdffont = $alternatepdffontfile[$language];// Actually use only core font $pdffont = $alternatepdffontfile[$language];// Actually use only core font
} }
} }
$pdffontsize=Yii::app()->getConfig('pdffontsize');
if ($pdffontsize=='auto') if ($pdffontsize=='auto')
{ {
$pdffontsize=PDF_FONT_SIZE_MAIN; $pdffontsize=PDF_FONT_SIZE_MAIN;

View file

@ -89,13 +89,9 @@ function retrieveAnswers($ia)
$qtitle=$ia[3]; $qtitle=$ia[3];
$inputnames=array(); $inputnames=array();
// TMSW - eliminate this - get from LEM
//A bit of housekeeping to stop PHP Notices
$answer = "";
if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])) {$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] = "";}
$aQuestionAttributes = getQuestionAttributeValues($ia[0], $ia[4]); $aQuestionAttributes = getQuestionAttributeValues($ia[0], $ia[4]);
//Create the question/answer html //Create the question/answer html
$answer = "";
// Previously in limesurvey, it was virtually impossible to control how the start of questions were formatted. // Previously in limesurvey, it was virtually impossible to control how the start of questions were formatted.
// this is an attempt to allow users (or rather system admins) some control over how the starting text is formatted. // this is an attempt to allow users (or rather system admins) some control over how the starting text is formatted.
$number = isset($ia[9]) ? $ia[9] : ''; $number = isset($ia[9]) ? $ia[9] : '';
@ -164,10 +160,6 @@ function retrieveAnswers($ia)
break; break;
case 'R': //RANKING STYLE case 'R': //RANKING STYLE
$values=do_ranking($ia); $values=do_ranking($ia);
if (count($values[1]) > 1 && $aQuestionAttributes['hide_tip']==0)
{
$question_text['help'] = $clang->gT("Double-click or drag-and-drop items in the left list to move them to the right - your highest ranking item should be on the top right, moving through to your lowest ranking item.");
}
break; break;
case 'M': //Multiple choice checkbox case 'M': //Multiple choice checkbox
$values=do_multiplechoice($ia); $values=do_multiplechoice($ia);
@ -926,11 +918,10 @@ function do_5pointchoice($ia)
} }
$answer .= " onclick=\"$checkconditionFunction(this.value, this.name, this.type)\" />\n<label for=\"answer$ia[1]$fp\" class=\"answertext\">$fp</label>\n\t</li>\n"; $answer .= " onclick=\"$checkconditionFunction(this.value, this.name, this.type)\" />\n<label for=\"answer$ia[1]$fp\" class=\"answertext\">$fp</label>\n\t</li>\n";
} }
if ($ia[6] != "Y" && SHOW_NO_ANSWER == 1) // Add "No Answer" option if question is not mandatory if ($ia[6] != "Y" && SHOW_NO_ANSWER == 1) // Add "No Answer" option if question is not mandatory
{ {
$answer .= "\t<li class=\"answer-item radio-item noanswer-item\">\n<input class=\"radio\" type=\"radio\" name=\"$ia[1]\" id=\"answer".$ia[1]."NANS\" value=\"\""; $answer .= "\t<li class=\"answer-item radio-item noanswer-item\">\n<input class=\"radio\" type=\"radio\" name=\"$ia[1]\" id=\"answer".$ia[1]."NANS\" value=\"\"";
if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])) if (!$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]])
{ {
$answer .= CHECKED; $answer .= CHECKED;
} }
@ -1143,15 +1134,16 @@ function do_date($ia)
* yearmin = Minimum year value for dropdown list, if not set default is 1900 * yearmin = Minimum year value for dropdown list, if not set default is 1900
* yearmax = Maximum year value for dropdown list, if not set default is 2037 * yearmax = Maximum year value for dropdown list, if not set default is 2037
* if full dates (format: YYYY-MM-DD) are given, only the year is used * if full dates (format: YYYY-MM-DD) are given, only the year is used
* expressions are not supported because contents of dropbox cannot be easily updated dynamically
*/ */
$yearmin = (int)substr(LimeExpressionManager::ProcessString($mindate),0,4); $yearmin = (int)substr($mindate,0,4);
if (!isset($yearmin) || $yearmin==0) if (!isset($yearmin) || $yearmin<1900 || $yearmin>2037)
{ {
$yearmin = 1900; $yearmin = 1900;
} }
$yearmax = (int)substr(LimeExpressionManager::ProcessString($maxdate), 0, 4); $yearmax = (int)substr($maxdate, 0, 4);
if (!isset($yearmax) || $yearmax==0) if (!isset($yearmax) || $yearmax<1900 || $yearmax>2037)
{ {
$yearmax = 2037; $yearmax = 2037;
} }
@ -1288,8 +1280,9 @@ function do_date($ia)
$goodchars = str_replace( array("m","d","y"), "", $dateformatdetails['jsdate']); $goodchars = str_replace( array("m","d","y"), "", $dateformatdetails['jsdate']);
$goodchars = "0123456789".substr($goodchars,0,1); $goodchars = "0123456789".substr($goodchars,0,1);
// Max length of date : Get the date of 1999-12-30 at 32:59:59 to be sure to have space with non leading 0 format
// "+1" makes room for a trailing space in date/time values // "+1" makes room for a trailing space in date/time values
$iLength=strlen($dateformatdetails['dateformat'])+1; $iLength=strlen(date($dateformatdetails['phpdate'],mktime(23,59,59,12,30,1999)))+1;
// HTML for date question using datepicker // HTML for date question using datepicker
@ -1583,7 +1576,7 @@ function do_list_dropdown($ia)
$answer .= ' <option value="-oth-"'.$opt_select.'>'.flattenText($_prefix.$othertext)."</option>\n"; $answer .= ' <option value="-oth-"'.$opt_select.'>'.flattenText($_prefix.$othertext)."</option>\n";
} }
if (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] != '') && $ia[6] != 'Y' && $ia[6] != 'Y' && SHOW_NO_ANSWER == 1) if (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] != '') && $ia[6] != 'Y' && SHOW_NO_ANSWER == 1)
{ {
if ($prefixStyle == 1) { if ($prefixStyle == 1) {
$_prefix = ++$_rowNum . ') '; $_prefix = ++$_rowNum . ') ';
@ -2034,11 +2027,13 @@ function do_listwithcomment($ia)
} }
else //Dropdown list else //Dropdown list
{ {
// --> START NEW FEATURE - SAVE
$answer .= '<p class="select answer-item dropdown-item"> $answer .= '<p class="select answer-item dropdown-item">
<select class="select" name="'.$ia[1].'" id="answer'.$ia[1].'" onchange="'.$checkconditionFunction.'(this.value, this.name, this.type)" > <select class="select" name="'.$ia[1].'" id="answer'.$ia[1].'" onchange="'.$checkconditionFunction.'(this.value, this.name, this.type)" >
'; ';
// --> END NEW FEATURE - SAVE if (is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]))
{
$answer .= '<option value=""'.SELECTED.'>'.$clang->gT('Please choose...').'</option>'."\n";
}
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
{ {
$check_ans = ''; $check_ans = '';
@ -2053,16 +2048,13 @@ function do_listwithcomment($ia)
$maxoptionsize = strlen($ansrow['answer']); $maxoptionsize = strlen($ansrow['answer']);
} }
} }
if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1 && !is_null($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]))
{ {
if ((!$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '') ||($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == ' ')) $check_ans="";
if ( $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '' || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == ' ' )
{ {
$check_ans = SELECTED; $check_ans = SELECTED;
} }
elseif ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] != '')
{
$check_ans = '';
}
$answer .= '<option class="noanswer-item" value=""'.$check_ans.'>'.$clang->gT('No answer')."</option>\n"; $answer .= '<option class="noanswer-item" value=""'.$check_ans.'>'.$clang->gT('No answer')."</option>\n";
} }
$answer .= ' </select> $answer .= ' </select>
@ -2118,9 +2110,12 @@ function do_ranking($ia)
$max_answers=$anscount; $max_answers=$anscount;
} }
// Get the max number of line needed // Get the max number of line needed
if(ctype_digit($max_answers) && intval($max_answers)<$anscount){ if(ctype_digit($max_answers) && intval($max_answers)<$anscount)
{
$iMaxLine=$max_answers; $iMaxLine=$max_answers;
}else{ }
else
{
$iMaxLine=$anscount; $iMaxLine=$anscount;
} }
if (trim($aQuestionAttributes["min_answers"])!='') if (trim($aQuestionAttributes["min_answers"])!='')
@ -2133,13 +2128,13 @@ function do_ranking($ia)
// First start by a ranking without javascript : just a list of select box // First start by a ranking without javascript : just a list of select box
// construction select box // construction select box
$answers= array(); $answers= array();
foreach ($ansresult as $ansrow) foreach ($ansresult as $ansrow)
{ {
$answers[] = $ansrow; $answers[] = $ansrow;
} }
$answer .= '<div class="ranking-answers"> $answer .= '<div class="ranking-answers">
<ul class="answers-list select-list">'; <ul class="answers-list select-list">';
for ($i=1; $i<=$anscount; $i++) for ($i=1; $i<=$iMaxLine; $i++)
{ {
$myfname=$ia[1].$i; $myfname=$ia[1].$i;
$answer .= "\n<li class=\"select-item\">"; $answer .= "\n<li class=\"select-item\">";
@ -2151,7 +2146,7 @@ function do_ranking($ia)
} }
$answer .= "</label>"; $answer .= "</label>";
$answer .= "<select name=\"{$myfname}\" id=\"answer{$myfname}\">\n"; $answer .= "<select name=\"{$myfname}\" id=\"answer{$myfname}\">\n";
if (!$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]) if (!$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])
{ {
$answer .= "\t<option value=\"\"".SELECTED.">".$clang->gT('Please choose...')."</option>\n"; $answer .= "\t<option value=\"\"".SELECTED.">".$clang->gT('Please choose...')."</option>\n";
} }
@ -2177,7 +2172,7 @@ function do_ranking($ia)
. "<div style='display:none' id='ranking-{$ia[0]}-minans'>{".$min_answers."}</div>" . "<div style='display:none' id='ranking-{$ia[0]}-minans'>{".$min_answers."}</div>"
. "<div style='display:none' id='ranking-{$ia[0]}-name'>".$ia[1]."</div>" . "<div style='display:none' id='ranking-{$ia[0]}-name'>".$ia[1]."</div>"
. "</div>"; . "</div>";
// The list with HTML answres // The list with HTML answers
$answer .="<div style=\"display:none\">"; $answer .="<div style=\"display:none\">";
foreach ($answers as $ansrow) foreach ($answers as $ansrow)
{ {
@ -2204,11 +2199,15 @@ function do_ranking($ia)
{ {
$rank_title=$clang->gT("Your Ranking",'js'); $rank_title=$clang->gT("Your Ranking",'js');
} }
// hide_tip is managed by css with EM
$rank_help = $clang->gT("Double-click or drag-and-drop items in the left list to move them to the right - your highest ranking item should be on the top right, moving through to your lowest ranking item.",'js');
$answer .= "<script type='text/javascript'>\n" $answer .= "<script type='text/javascript'>\n"
. " <!--\n" . " <!--\n"
. "var aRankingTranslations = { . "var aRankingTranslations = {
choicetitle: '{$choice_title}', choicetitle: '{$choice_title}',
ranktitle: '{$rank_title}' ranktitle: '{$rank_title}',
rankhelp: '{$rank_help}'
};\n" };\n"
." doDragDropRank({$ia[0]},{$aQuestionAttributes["showpopups"]},{$aQuestionAttributes["samechoiceheight"]},{$aQuestionAttributes["samelistheight"]});\n" ." doDragDropRank({$ia[0]},{$aQuestionAttributes["showpopups"]},{$aQuestionAttributes["samechoiceheight"]},{$aQuestionAttributes["samelistheight"]});\n"
." -->\n" ." -->\n"
@ -3045,9 +3044,7 @@ function do_multipleshorttext($ia)
if ($ansrow['question'] == "") {$ansrow['question'] = "&nbsp;";} if ($ansrow['question'] == "") {$ansrow['question'] = "&nbsp;";}
// color code missing mandatory questions red // color code missing mandatory questions red
if ($ia[6]=='Y' && (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep']) if ($ia[6]=='Y' && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '') {
|| ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep'] > $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step']))
&& $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') {
$ansrow['question'] = "<span class='errormandatory'>{$ansrow['question']}</span>"; $ansrow['question'] = "<span class='errormandatory'>{$ansrow['question']}</span>";
} }
@ -3161,36 +3158,14 @@ function do_multiplenumeric($ia)
$prefixclass="slider"; $prefixclass="slider";
$slider_layout=true; $slider_layout=true;
$extraclass .=" withslider"; $extraclass .=" withslider";
if (trim($aQuestionAttributes['slider_accuracy'])!='') $slider_step=trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_accuracy']}}",$ia[0],array(),false,1,1,false,false,true));
{ $slider_step = (is_numeric($slider_step))?$slider_step:1;
$slider_step = $aQuestionAttributes['slider_accuracy']; $slider_min = trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_min']}}",$ia[0],array(),false,1,1,false,false,true));
} $slider_mintext = $slider_min = (is_numeric($slider_min))?$slider_min:0;
else $slider_max = trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_max']}}",$ia[0],array(),false,1,1,false,false,true));
{ $slider_maxtext = $slider_max = (is_numeric($slider_max))?$slider_max:100;
$slider_step = 1; $slider_default=trim(LimeExpressionManager::ProcessString("{{$aQuestionAttributes['slider_default']}}",$ia[0],array(),false,1,1,false,false,true));
} $slider_default = (is_numeric($slider_default))?$slider_default:"";
if (trim($aQuestionAttributes['slider_min'])!='')
{
$slider_mintext = $aQuestionAttributes['slider_min'];
$slider_min = $aQuestionAttributes['slider_min'];
}
else
{
$slider_mintext = 0;
$slider_min = 0;
}
if (trim($aQuestionAttributes['slider_max'])!='')
{
$slider_maxtext = $aQuestionAttributes['slider_max'];
$slider_max = $aQuestionAttributes['slider_max'];
}
else
{
$slider_maxtext = "100";
$slider_max = 100;
}
$slider_default= (trim($aQuestionAttributes['slider_default'])!='')?$aQuestionAttributes['slider_default']:"";
if ($slider_default == '' && $aQuestionAttributes['slider_middlestart']==1) if ($slider_default == '' && $aQuestionAttributes['slider_middlestart']==1)
{ {
@ -3254,9 +3229,8 @@ function do_multiplenumeric($ia)
} }
// color code missing mandatory questions red // color code missing mandatory questions red
if ($ia[6]=='Y' && (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'] == $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['prevstep']) if ($ia[6]=='Y' && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '')
|| ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['maxstep'] > $_SESSION['survey_'.Yii::app()->getConfig('surveyID')]['step'])) {
&& $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] === '') {
$theanswer = "<span class='errormandatory'>{$theanswer}</span>"; $theanswer = "<span class='errormandatory'>{$theanswer}</span>";
} }
@ -3270,7 +3244,12 @@ function do_multiplenumeric($ia)
$answer_main .= "{$sliderleft}<span class=\"input\">\n\t".$prefix."\n\t<input class=\"text $kpclass\" type=\"text\" size=\"".$tiwidth."\" name=\"".$myfname."\" id=\"answer".$myfname."\" title=\"".$clang->gT('Only numbers may be entered in this field.')."\" value=\""; $answer_main .= "{$sliderleft}<span class=\"input\">\n\t".$prefix."\n\t<input class=\"text $kpclass\" type=\"text\" size=\"".$tiwidth."\" name=\"".$myfname."\" id=\"answer".$myfname."\" title=\"".$clang->gT('Only numbers may be entered in this field.')."\" value=\"";
if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname])) if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]))
{ {
$dispVal = str_replace('.',$sSeparator,$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname]); $dispVal = $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname];
if(strpos($dispVal,"."))
{
$dispVal=rtrim(rtrim($dispVal,"0"),".");
}
$dispVal = str_replace('.',$sSeparator,$dispVal);
$answer_main .= $dispVal; $answer_main .= $dispVal;
} }
@ -3481,6 +3460,10 @@ function do_shortfreetext($ia)
{ {
$checkconditionFunction = "checkconditions"; $checkconditionFunction = "checkconditions";
} }
if (Yii::app()->db->driverName != 'mysql' && Yii::app()->db->driverName != 'mysqli' && (!intval(trim($aQuestionAttributes['maximum_chars'])>0) || intval(trim($aQuestionAttributes['maximum_chars'])>255)))
{
$aQuestionAttributes['maximum_chars']=255;
}
if (intval(trim($aQuestionAttributes['maximum_chars']))>0) if (intval(trim($aQuestionAttributes['maximum_chars']))>0)
{ {
// Only maxlength attribute, use textarea[maxlength] jquery selector for textarea // Only maxlength attribute, use textarea[maxlength] jquery selector for textarea
@ -3852,11 +3835,10 @@ function do_yesno($ia)
// --> START NEW FEATURE - SAVE // --> START NEW FEATURE - SAVE
$answer .= " onclick=\"$checkconditionFunction(this.value, this.name, this.type)\" />\n<label for=\"answer{$ia[1]}N\" class=\"answertext\" >\n\t".$clang->gT('No')."\n</label>\n\t</li>\n"; $answer .= " onclick=\"$checkconditionFunction(this.value, this.name, this.type)\" />\n<label for=\"answer{$ia[1]}N\" class=\"answertext\" >\n\t".$clang->gT('No')."\n</label>\n\t</li>\n";
// --> END NEW FEATURE - SAVE // --> END NEW FEATURE - SAVE
if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1) if ($ia[6] != 'Y' && SHOW_NO_ANSWER == 1)
{ {
$answer .= "\t<li class=\"answer-item radio-item noanswer-item\">\n<input class=\"radio\" type=\"radio\" name=\"{$ia[1]}\" id=\"answer{$ia[1]}\" value=\"\""; $answer .= "\t<li class=\"answer-item radio-item noanswer-item\">\n<input class=\"radio\" type=\"radio\" name=\"{$ia[1]}\" id=\"answer{$ia[1]}\" value=\"\"";
if ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]] == '') if (empty($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$ia[1]]))
{ {
$answer .= CHECKED; $answer .= CHECKED;
} }
@ -3928,7 +3910,9 @@ function do_gender($ia)
// TMSW TODO - Can remove DB query by passing in answer list from EM // TMSW TODO - Can remove DB query by passing in answer list from EM
function do_array_5point($ia) function do_array_5point($ia)
{ {
global $notanswered, $thissurvey; global $thissurvey;
$aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$extraclass =""; $extraclass ="";
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$caption=$clang->gT("An array with sub-question on each line. The answers are value from 1 to 5 and are contained in the table header. "); $caption=$clang->gT("An array with sub-question on each line. The answers are value from 1 to 5 and are contained in the table header. ");
@ -4018,10 +4002,9 @@ function do_array_5point($ia)
$answertext = $ansrow['question']; $answertext = $ansrow['question'];
if (strpos($answertext,'|')) {$answertext=substr($answertext,0,strpos($answertext,'|'));} if (strpos($answertext,'|')) {$answertext=substr($answertext,0,strpos($answertext,'|'));}
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check if this item has not been answered */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && in_array($myfname,$aMandatoryViolationSubQ))
and there must be no answer available for the item in this session. */ {
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ) {
$answertext = "<span class=\"errormandatory\">{$answertext}</span>"; $answertext = "<span class=\"errormandatory\">{$answertext}</span>";
} }
@ -4097,7 +4080,9 @@ function do_array_5point($ia)
// TMSW TODO - Can remove DB query by passing in answer list from EM // TMSW TODO - Can remove DB query by passing in answer list from EM
function do_array_10point($ia) function do_array_10point($ia)
{ {
global $notanswered, $thissurvey; global $thissurvey;
$aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$extraclass =""; $extraclass ="";
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$caption=$clang->gT("An array with sub-question on each line. The answers are value from 1 to 10 and are contained in the table header. "); $caption=$clang->gT("An array with sub-question on each line. The answers are value from 1 to 10 and are contained in the table header. ");
@ -4168,10 +4153,9 @@ function do_array_10point($ia)
{ {
$myfname = $ia[1].$ansrow['title']; $myfname = $ia[1].$ansrow['title'];
$answertext = $ansrow['question']; $answertext = $ansrow['question'];
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check if this item has not been answered */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && in_array($myfname, $aMandatoryViolationSubQ) )
and there must be no answer available for the item in this session. */ {
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == "") ) {
$answertext = "<span class='errormandatory'>{$answertext}</span>"; $answertext = "<span class='errormandatory'>{$answertext}</span>";
} }
$trbc = alternation($trbc , 'row'); $trbc = alternation($trbc , 'row');
@ -4226,7 +4210,9 @@ function do_array_10point($ia)
// TMSW TODO - Can remove DB query by passing in answer list from EM // TMSW TODO - Can remove DB query by passing in answer list from EM
function do_array_yesnouncertain($ia) function do_array_yesnouncertain($ia)
{ {
global $notanswered, $thissurvey; global $thissurvey;
$aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$extraclass =""; $extraclass ="";
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$caption=$clang->gT("An array with sub-question on each line. The answers are yes, no, uncertain and are in the table header. "); $caption=$clang->gT("An array with sub-question on each line. The answers are yes, no, uncertain and are in the table header. ");
@ -4302,10 +4288,9 @@ function do_array_yesnouncertain($ia)
{ {
$myfname = $ia[1].$ansrow['title']; $myfname = $ia[1].$ansrow['title'];
$answertext = $ansrow['question']; $answertext = $ansrow['question'];
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check the sub question mandatory violation */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && in_array($myfname, $aMandatoryViolationSubQ))
and there must be no answer available for the item in this session. */ {
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ) {
$answertext = "<span class='errormandatory'>{$answertext}</span>"; $answertext = "<span class='errormandatory'>{$answertext}</span>";
} }
$trbc = alternation($trbc , 'row'); $trbc = alternation($trbc , 'row');
@ -4383,7 +4368,8 @@ function do_array_yesnouncertain($ia)
function do_array_increasesamedecrease($ia) function do_array_increasesamedecrease($ia)
{ {
global $thissurvey; global $thissurvey;
global $notanswered; $aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$extraclass =""; $extraclass ="";
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$caption=$clang->gT("An array with sub-question on each line. The answers are increase, same, decrease and are contained in the table header. "); $caption=$clang->gT("An array with sub-question on each line. The answers are increase, same, decrease and are contained in the table header. ");
@ -4459,10 +4445,8 @@ function do_array_increasesamedecrease($ia)
{ {
$myfname = $ia[1].$ansrow['title']; $myfname = $ia[1].$ansrow['title'];
$answertext = $ansrow['question']; $answertext = $ansrow['question'];
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check the sub Q mandatory violation */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && in_array($myfname, $aMandatoryViolationSubQ))
and there must be no answer available for the item in this session. */
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == "") )
{ {
$answertext = "<span class=\"errormandatory\">{$answertext}</span>"; $answertext = "<span class=\"errormandatory\">{$answertext}</span>";
} }
@ -4544,7 +4528,8 @@ function do_array_increasesamedecrease($ia)
function do_array($ia) function do_array($ia)
{ {
global $thissurvey; global $thissurvey;
global $notanswered; $aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$repeatheadings = Yii::app()->getConfig("repeatheadings"); $repeatheadings = Yii::app()->getConfig("repeatheadings");
$minrepeatheadings = Yii::app()->getConfig("minrepeatheadings"); $minrepeatheadings = Yii::app()->getConfig("minrepeatheadings");
$extraclass =""; $extraclass ="";
@ -4645,7 +4630,6 @@ function do_array($ia)
$answer = '<tbody>'; $answer = '<tbody>';
$trbc = ''; $trbc = '';
$inputnames=array(); $inputnames=array();
foreach($aQuestions as $ansrow) foreach($aQuestions as $ansrow)
{ {
if (isset($repeatheadings) && $repeatheadings > 0 && ($fn-1) > 0 && ($fn-1) % $repeatheadings == 0) if (isset($repeatheadings) && $repeatheadings > 0 && ($fn-1) > 0 && ($fn-1) % $repeatheadings == 0)
@ -4663,13 +4647,10 @@ function do_array($ia)
{ {
$answertext=substr($answertext,0, strpos($answertext,'|')); $answertext=substr($answertext,0, strpos($answertext,'|'));
} }
/* Check if this item has not been answered: the 'notanswered' variable must be an array,
containing a list of unanswered questions, the current question must be in the array,
and there must be no answer available for the item in this session. */
if (strpos($answertext,'|')) {$answerwidth=$answerwidth/2;} if (strpos($answertext,'|')) {$answerwidth=$answerwidth/2;}
/* Check the mandatory sub Q violation */
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ) { if (in_array($myfname, $aMandatoryViolationSubQ))
{
$answertext = '<span class="errormandatory">'.$answertext.'</span>'; $answertext = '<span class="errormandatory">'.$answertext.'</span>';
} }
// Get array_filter stuff // Get array_filter stuff
@ -4812,13 +4793,10 @@ function do_array($ia)
{ {
$answertext=substr($answertext,0, strpos($answertext,'|')); $answertext=substr($answertext,0, strpos($answertext,'|'));
} }
/* Check if this item has not been answered: the 'notanswered' variable must be an array,
containing a list of unanswered questions, the current question must be in the array,
and there must be no answer available for the item in this session. */
if (strpos($answertext,'|')) {$answerwidth=$answerwidth/2;} if (strpos($answertext,'|')) {$answerwidth=$answerwidth/2;}
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == '') ) { if ($ia[6]=='Y' && in_array($myfname, $aMandatoryViolationSubQ))
{
$answertext = '<span class="errormandatory">'.$answertext.'</span>'; $answertext = '<span class="errormandatory">'.$answertext.'</span>';
} }
// Get array_filter stuff // Get array_filter stuff
@ -4897,7 +4875,8 @@ function do_array($ia)
function do_array_multitext($ia) function do_array_multitext($ia)
{ {
global $thissurvey; global $thissurvey;
global $notanswered; $aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$repeatheadings = Yii::app()->getConfig("repeatheadings"); $repeatheadings = Yii::app()->getConfig("repeatheadings");
$minrepeatheadings = Yii::app()->getConfig("minrepeatheadings"); $minrepeatheadings = Yii::app()->getConfig("minrepeatheadings");
$extraclass =""; $extraclass ="";
@ -4963,7 +4942,7 @@ function do_array_multitext($ia)
} }
$num_class = ' numbers-only'; $num_class = ' numbers-only';
$extraclass.=" numberonly"; $extraclass.=" numberonly";
$caption.=$clang->gT("Each answers are number. "); $caption.=$clang->gT("Each answer is a number. ");
switch ($aQuestionAttributes['show_totals']) switch ($aQuestionAttributes['show_totals'])
{ {
case 'R': case 'R':
@ -4973,11 +4952,11 @@ function do_array_multitext($ia)
<input name="[[ROW_NAME]]_total" title="[[ROW_NAME]] total" size="[[INPUT_WIDTH]]" value="" type="text" disabled="disabled" class="disabled" /> <input name="[[ROW_NAME]]_total" title="[[ROW_NAME]] total" size="[[INPUT_WIDTH]]" value="" type="text" disabled="disabled" class="disabled" />
</label> </label>
</td>'; </td>';
$col_head = ' <th class="total">Total</th>'; $col_head = ' <th class="total">'.$clang->gT('Total').'</th>';
if($show_grand == true) if($show_grand == true)
{ {
$row_head = ' $row_head = '
<th class="answertext total">Grand total</th>'; <th class="answertext total">'.$clang->gT('Grand total').'</th>';
$col_total = ' $col_total = '
<td>&nbsp;</td>'; <td>&nbsp;</td>';
$grand_total = ' $grand_total = '
@ -4985,7 +4964,7 @@ function do_array_multitext($ia)
<input type="text" size="[[INPUT_WIDTH]]" value="" disabled="disabled" class="disabled" /> <input type="text" size="[[INPUT_WIDTH]]" value="" disabled="disabled" class="disabled" />
</td>'; </td>';
}; };
$caption.=$clang->gT("The last row show the total for the column. "); $caption.=$clang->gT("The last row shows the total for the column. ");
break; break;
case 'C': case 'C':
$totals_class = $show_totals = 'col'; $totals_class = $show_totals = 'col';
@ -5005,7 +4984,7 @@ function do_array_multitext($ia)
<input type="text" size="[[INPUT_WIDTH]]" value="" disabled="disabled" class="disabled" /> <input type="text" size="[[INPUT_WIDTH]]" value="" disabled="disabled" class="disabled" />
</td>'; </td>';
}; };
$caption.=$clang->gT("The last column show the total for the row. "); $caption.=$clang->gT("The last column shows the total for the row. ");
break; break;
case 'B': case 'B':
$totals_class = $show_totals = 'both'; $totals_class = $show_totals = 'both';
@ -5018,7 +4997,7 @@ function do_array_multitext($ia)
<td class="total information-item"> <td class="total information-item">
<input type="text" size="[[INPUT_WIDTH]]" value="" disabled="disabled" class="disabled" /> <input type="text" size="[[INPUT_WIDTH]]" value="" disabled="disabled" class="disabled" />
</td>'; </td>';
$col_head = ' <th class="total">Total</th>'; $col_head = ' <th class="total">'.$clang->gT('Total').'</th>';
$row_head = ' $row_head = '
<th class="answertext">Total</th>'; <th class="answertext">Total</th>';
if($show_grand == true) if($show_grand == true)
@ -5033,7 +5012,7 @@ function do_array_multitext($ia)
$grand_total = ' $grand_total = '
<td>&nbsp;</td>'; <td>&nbsp;</td>';
}; };
$caption.=$clang->gT("The last row show the total for the column and the last column show the total for the row. "); $caption.=$clang->gT("The last row shows the total for the column and the last column shows the total for the row. ");
break; break;
}; };
if(!empty($totals_class)) if(!empty($totals_class))
@ -5163,17 +5142,15 @@ function do_array_multitext($ia)
$myfname = $ia[1].$ansrow['title']; $myfname = $ia[1].$ansrow['title'];
$answertext = $ansrow['question']; $answertext = $ansrow['question'];
$answertextsave=$answertext; $answertextsave=$answertext;
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check the sub Q mandatory volation */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && !empty($aMandatoryViolationSubQ))
and there must be no answer available for the item in this session. */
if ($ia[6]=='Y' && is_array($notanswered))
{ {
//Go through each labelcode and check for a missing answer! If any are found, highlight this line //Go through each labelcode and check for a missing answer! If any are found, highlight this line
$emptyresult=0; $emptyresult=0;
foreach($labelcode as $ld) foreach($labelcode as $ld)
{ {
$myfname2=$myfname.'_'.$ld; $myfname2=$myfname.'_'.$ld;
if((array_search($myfname2, $notanswered) !== FALSE) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] == '') if(in_array($myfname2, $aMandatoryViolationSubQ))
{ {
$emptyresult=1; $emptyresult=1;
} }
@ -5283,7 +5260,8 @@ EOD;
function do_array_multiflexi($ia) function do_array_multiflexi($ia)
{ {
global $thissurvey; global $thissurvey;
global $notanswered; $aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$repeatheadings = Yii::app()->getConfig("repeatheadings"); $repeatheadings = Yii::app()->getConfig("repeatheadings");
$minrepeatheadings = Yii::app()->getConfig("minrepeatheadings"); $minrepeatheadings = Yii::app()->getConfig("minrepeatheadings");
$extraclass =""; $extraclass ="";
@ -5497,19 +5475,28 @@ function do_array_multiflexi($ia)
$myfname = $ia[1].$ansrow['title']; $myfname = $ia[1].$ansrow['title'];
$answertext = $ansrow['question']; $answertext = $ansrow['question'];
$answertextsave=$answertext; $answertextsave=$answertext;
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check the sub Q mandatory violation */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && !empty($aMandatoryViolationSubQ))
and there must be no answer available for the item in this session. */
if ($ia[6]=='Y' && is_array($notanswered))
{ {
//Go through each labelcode and check for a missing answer! If any are found, highlight this line //Go through each labelcode and check for a missing answer! Default :If any are found, highlight this line, checkbox : if one is not found : don't highlight
$emptyresult=0; // PS : we really need a better system : event for EM !
$emptyresult=($aQuestionAttributes['multiflexible_checkbox']!=0) ? 1 : 0;
foreach($labelcode as $ld) foreach($labelcode as $ld)
{ {
$myfname2=$myfname.'_'.$ld; $myfname2=$myfname.'_'.$ld;
if((array_search($myfname2, $notanswered) !== FALSE) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] == "") if($aQuestionAttributes['multiflexible_checkbox']!=0)
{ {
$emptyresult=1; if(!in_array($myfname2, $aMandatoryViolationSubQ))
{
$emptyresult=0;
}
}
else
{
if(in_array($myfname2, $aMandatoryViolationSubQ))
{
$emptyresult=1;
}
} }
} }
if ($emptyresult == 1) if ($emptyresult == 1)
@ -5541,6 +5528,7 @@ function do_array_multiflexi($ia)
if ($checkboxlayout == false) if ($checkboxlayout == false)
{ {
$myfname2=$myfname."_$ld"; $myfname2=$myfname."_$ld";
if(isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2])) if(isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]))
{ {
$myfname2_java_value = " value=\"{$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]}\" "; $myfname2_java_value = " value=\"{$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]}\" ";
@ -5562,7 +5550,7 @@ function do_array_multiflexi($ia)
for($ii=$minvalue; ($reverse? $ii>=$maxvalue:$ii<=$maxvalue); $ii+=$stepvalue) { for($ii=$minvalue; ($reverse? $ii>=$maxvalue:$ii<=$maxvalue); $ii+=$stepvalue) {
$answer .= '<option value="'.str_replace('.',$sSeparator,$ii).'"'; $answer .= '<option value="'.str_replace('.',$sSeparator,$ii).'"';
if(isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] == $ii) { if(isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2]) && (string)$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname2] == (string)($ii)) {
$answer .= SELECTED; $answer .= SELECTED;
} }
$answer .= ">".str_replace('.',$sSeparator,$ii)."</option>\n"; $answer .= ">".str_replace('.',$sSeparator,$ii)."</option>\n";
@ -5607,7 +5595,7 @@ function do_array_multiflexi($ia)
. " if(this.checked) {" . " if(this.checked) {"
. " aelt.value=1;jelt.value=1;$checkconditionFunction(1,'{$myfname2}',aelt.type);" . " aelt.value=1;jelt.value=1;$checkconditionFunction(1,'{$myfname2}',aelt.type);"
. " } else {" . " } else {"
. " aelt.value=0;jelt.value=0;$checkconditionFunction(0,'{$myfname2}',aelt.type);" . " aelt.value='';jelt.value='';$checkconditionFunction('','{$myfname2}',aelt.type);"
. " }; return true;\" " . " }; return true;\" "
// . " onchange=\"checkconditions(this.value, this.name, this.type)\" " // . " onchange=\"checkconditions(this.value, this.name, this.type)\" "
. " />\n"; . " />\n";
@ -5648,7 +5636,8 @@ function do_array_multiflexi($ia)
// TMSW TODO - Can remove DB query by passing in answer list from EM // TMSW TODO - Can remove DB query by passing in answer list from EM
function do_arraycolumns($ia) function do_arraycolumns($ia)
{ {
global $notanswered; $aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
$extraclass = ""; $extraclass = "";
$checkconditionFunction = "checkconditions"; $checkconditionFunction = "checkconditions";
@ -5719,10 +5708,8 @@ function do_arraycolumns($ia)
$ld = $answers[$_i]; $ld = $answers[$_i];
$myfname = $ia[1].$anscode[$_i]; $myfname = $ia[1].$anscode[$_i];
$trbc = alternation($trbc , 'row'); $trbc = alternation($trbc , 'row');
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check the Sub Q mandatory violation */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && in_array($myfname, $aMandatoryViolationSubQ))
and there must be no answer available for the item in this session. */
if ($ia[6]=='Y' && (is_array($notanswered)) && (array_search($myfname, $notanswered) !== FALSE) && ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == "") )
{ {
$ld = "<span class=\"errormandatory\">{$ld}</span>"; $ld = "<span class=\"errormandatory\">{$ld}</span>";
} }
@ -5801,7 +5788,8 @@ function do_array_dual($ia)
{ {
$clang = Yii::app()->lang; $clang = Yii::app()->lang;
global $thissurvey; global $thissurvey;
global $notanswered; $aLastMoveResult=LimeExpressionManager::GetLastMoveResult();
$aMandatoryViolationSubQ=($aLastMoveResult['mandViolation'] && $ia[6] == 'Y') ? explode("|",$aLastMoveResult['unansweredSQs']) : array();
$repeatheadings = Yii::app()->getConfig("repeatheadings"); $repeatheadings = Yii::app()->getConfig("repeatheadings");
$minrepeatheadings = Yii::app()->getConfig("minrepeatheadings"); $minrepeatheadings = Yii::app()->getConfig("minrepeatheadings");
$extraclass =""; $extraclass ="";
@ -6044,10 +6032,8 @@ function do_array_dual($ia)
$myfid0 = $ia[1].$ansrow['title'].'_0'; $myfid0 = $ia[1].$ansrow['title'].'_0';
$myfname1 = $ia[1].$ansrow['title'].'#1'; // new multi-scale-answer $myfname1 = $ia[1].$ansrow['title'].'#1'; // new multi-scale-answer
$myfid1 = $ia[1].$ansrow['title'].'_1'; $myfid1 = $ia[1].$ansrow['title'].'_1';
/* Check if this item has not been answered: the 'notanswered' variable must be an array, /* Check the Sub Q mandatory violation */
containing a list of unanswered questions, the current question must be in the array, if ($ia[6]=='Y' && (in_array($myfname0, $aMandatoryViolationSubQ) || in_array($myfname1, $aMandatoryViolationSubQ)))
and there must be no answer available for the item in this session. */
if ($ia[6]=='Y' && (is_array($notanswered)) && ((array_search($myfname0, $notanswered) !== FALSE) || (array_search($myfname1, $notanswered) !== FALSE)) && (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == '') || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] == '')) )
{ {
$answertext = "<span class='errormandatory'>{$answertext}</span>"; $answertext = "<span class='errormandatory'>{$answertext}</span>";
} }
@ -6246,13 +6232,15 @@ function do_array_dual($ia)
$trbc = ''; $trbc = '';
foreach ($aSubQuestions as $ansrow) foreach ($aSubQuestions as $ansrow)
{ {
$myfname = $ia[1].$ansrow['title']; $myfname = $ia[1].$ansrow['title'];
$myfname0 = $ia[1].$ansrow['title']."#0"; $myfname0 = $ia[1].$ansrow['title']."#0";
$myfid0 = $ia[1].$ansrow['title']."_0"; $myfid0 = $ia[1].$ansrow['title']."_0";
$myfname1 = $ia[1].$ansrow['title']."#1"; $myfname1 = $ia[1].$ansrow['title']."#1";
$myfid1 = $ia[1].$ansrow['title']."_1"; $myfid1 = $ia[1].$ansrow['title']."_1";
$sActualAnswer0=isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0])?$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]:"";
if ($ia[6]=='Y' && (is_array($notanswered)) && ((array_search($myfname0, $notanswered) !== FALSE) || (array_search($myfname1, $notanswered) !== FALSE)) && (($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == '') || ($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] == '')) ) $sActualAnswer1=isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1])?$_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1]:"";
if ($ia[6]=='Y' && (in_array($myfname0, $aMandatoryViolationSubQ) || in_array($myfname1, $aMandatoryViolationSubQ)))
{ {
$answertext="<span class='errormandatory'>".$ansrow['question']."</span>"; $answertext="<span class='errormandatory'>".$ansrow['question']."</span>";
} }
@ -6265,12 +6253,8 @@ function do_array_dual($ia)
$answer .= "\t<th class=\"answertext\">\n" $answer .= "\t<th class=\"answertext\">\n"
. "<label for=\"answer$myfid0\">{$answertext}</label>\n"; . "<label for=\"answer$myfid0\">{$answertext}</label>\n";
// Hidden answers used by EM: sure can be added in javascript // Hidden answers used by EM: sure can be added in javascript
$answer .= "<input type=\"hidden\" disabled=\"disabled\" name=\"java$myfid0\" id=\"java$myfid0\" value=\""; $answer .= "<input type=\"hidden\" disabled=\"disabled\" name=\"java$myfid0\" id=\"java$myfid0\" value=\"{$sActualAnswer0}\" />\n";
if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0])) {$answer .= $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0];} $answer .= "<input type=\"hidden\" disabled=\"disabled\" name=\"java$myfid1\" id=\"java$myfid1\" value=\"{$sActualAnswer1}\" />\n";
$answer .= "\" />\n";
$answer .= "<input type=\"hidden\" disabled=\"disabled\" name=\"java$myfid1\" id=\"java$myfid1\" value=\"";
if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1])) {$answer .= $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1];}
$answer .= "\" />\n";
$answer . "\t</th>\n"; $answer . "\t</th>\n";
// Selector 0 // Selector 0
if($ddprefix != '') if($ddprefix != '')
@ -6280,36 +6264,24 @@ function do_array_dual($ia)
$answer .= "\t<td class=\"answer-item dropdown-item\">\n" $answer .= "\t<td class=\"answer-item dropdown-item\">\n"
. "<select name=\"$myfname0\" id=\"answer$myfid0\">\n"; . "<select name=\"$myfname0\" id=\"answer$myfid0\">\n";
// If not mandatory and showanswer, show 'Please choose' // Show the 'Please choose' if there are no answer actually
if (SHOW_NO_ANSWER == 1) if ($sActualAnswer0 == '')
{ {
$answer .= "\t<option value=\"\" "; $answer .= "\t<option value=\"\" ".SELECTED.">".$clang->gT('Please choose...')."</option>\n";
if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == '')
{
$answer .= SELECTED;
}
$answer .='>';
if ($ia[6] != 'Y')
{
$answer .=$clang->gT('No answer');
}
else
{
$answer .=$clang->gT('Please choose...');
}
$answer .="</option>\n";
} }
foreach ($labels0 as $lrow) foreach ($labels0 as $lrow)
{ {
$answer .= "\t<option value=\"".$lrow['code'].'" '; $answer .= "\t<option value=\"".$lrow['code'].'" ';
if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname0] == $lrow['code']) if ($sActualAnswer0 == $lrow['code'])
{ {
$answer .= SELECTED; $answer .= SELECTED;
} }
$answer .= '>'.flattenText($lrow['title'])."</option>\n"; $answer .= '>'.flattenText($lrow['title'])."</option>\n";
} }
if ($sActualAnswer0 != '' && $ia[6] != 'Y' && SHOW_NO_ANSWER)
{
$answer .= "\t<option value=\"\">".$clang->gT('No answer')."</option>\n";
}
$answer .= "</select>\n"; $answer .= "</select>\n";
$answer .= "</td>\n"; $answer .= "</td>\n";
if($ddsuffix != '') if($ddsuffix != '')
@ -6328,35 +6300,24 @@ function do_array_dual($ia)
$answer .= "\t<td class=\"answer-item dropdown-item\">\n" $answer .= "\t<td class=\"answer-item dropdown-item\">\n"
. "<label class=\"hide read\" for=\"answer{$myfid1}\">{$answertext}</label>" . "<label class=\"hide read\" for=\"answer{$myfid1}\">{$answertext}</label>"
. "<select name=\"$myfname1\" id=\"answer$myfid1\">\n"; . "<select name=\"$myfname1\" id=\"answer$myfid1\">\n";
// If not mandatory and showanswer, show 'Please choose' // Show the 'Please choose' if there are no answer actually
if (SHOW_NO_ANSWER == 1) if ($sActualAnswer1 == '')
{ {
$answer .= "\t<option value=\"\" "; $answer .= "\t<option value=\"\" ".SELECTED.">".$clang->gT('Please choose...')."</option>\n";
if (!isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1]) || $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] == '')
{
$answer .= SELECTED;
}
$answer .='>';
if ($ia[6] != 'Y')
{
$answer .=$clang->gT('No answer');
}
else
{
$answer .=$clang->gT('Please choose...');
}
$answer .="</option>\n";
} }
foreach ($labels1 as $lrow1) foreach ($labels1 as $lrow1)
{ {
$answer .= "\t<option value=\"".$lrow1['code'].'" '; $answer .= "\t<option value=\"".$lrow1['code'].'" ';
if (isset($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1]) && $_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname1] == $lrow1['code']) if ($sActualAnswer1 == $lrow1['code'])
{ {
$answer .= SELECTED; $answer .= SELECTED;
} }
$answer .= '>'.flattenText($lrow1['title'])."</option>\n"; $answer .= '>'.flattenText($lrow1['title'])."</option>\n";
} }
if ($sActualAnswer1 != '' && $ia[6] != 'Y' && SHOW_NO_ANSWER)
{
$answer .= "\t<option value=\"\">".$clang->gT('No answer')."</option>\n";
}
$answer .= "</select>\n"; $answer .= "</select>\n";
$answer .= "</td>\n"; $answer .= "</td>\n";
if($ddsuffix != '') if($ddsuffix != '')

View file

@ -221,6 +221,42 @@ function templatereplace($line, $replacements = array(), &$redata = array(), $de
if (isset($question) && is_array($question)) if (isset($question) && is_array($question))
{ {
$question['sgq'] = (isset($question['sgq']) ? $question['sgq'] : '');
if($question['sgq'])
list($question['sid'],$question['gid'],$question['qid'])=explode("X",$question['sgq']);
else
list($question['sid'],$question['gid'],$question['qid'])=array('','','');
$question['aid']= (isset($question['aid']) ? $question['aid'] : '');
/**
* This event fires before each question is rendered.
* Currenty 3 parameters are set:
* @param string text The question text
* @param string class The class for div around the whole question
* @param string help The help text
*/
$event = new PluginEvent('beforeQuestionRender');
$event->set('surveyId', $question['sid']);// or $thissurvey['sid']
$event->set('text', $question['text']);
$event->set('class', $question['class']);
$event->set('help', $question['help']);
$event->set('type', $question['type']);
$event->set('code', $question['code']);
$event->set('qid', $question['qid']);
$event->set('gid', $question['gid']);
$event->set('answers',isset($answer) ? $answer : null);
$event->set('questionhelp',isset($help) ? $help : null);
App()->getPluginManager()->dispatchEvent($event);
$question['text'] = $event->get('text');
$question['class'] = $event->get('class');
$question['help'] = $event->get('help');
$question['mandatory'] = $event->get('mandatory',$question['mandatory']);
$question['answers'] = $event->get('answers');
$question['questionhelp'] = $event->get('questionhelp');
// answer part ?
// $answer is set with answer part
$_question = $question['all']; $_question = $question['all'];
$_question_text = $question['text']; $_question_text = $question['text'];
$_question_help = $question['help']; $_question_help = $question['help'];
@ -228,7 +264,6 @@ function templatereplace($line, $replacements = array(), &$redata = array(), $de
$_question_man_message = $question['man_message']; $_question_man_message = $question['man_message'];
$_question_valid_message = $question['valid_message']; $_question_valid_message = $question['valid_message'];
$_question_file_valid_message = $question['file_valid_message']; $_question_file_valid_message = $question['file_valid_message'];
$question['sgq'] = (isset($question['sgq']) ? $question['sgq'] : '');
$_question_essentials = $question['essentials']; $_question_essentials = $question['essentials'];
$_getQuestionClass = $question['class']; $_getQuestionClass = $question['class'];
$_question_man_class = $question['man_class']; $_question_man_class = $question['man_class'];
@ -236,11 +271,6 @@ function templatereplace($line, $replacements = array(), &$redata = array(), $de
$_question_number = $question['number']; $_question_number = $question['number'];
$_question_code = $question['code']; $_question_code = $question['code'];
$_question_type = $question['type']; $_question_type = $question['type'];
if($question['sgq']) // Not sure it can happen today ? But if set : allways sXgXq
list($question['sid'],$question['gid'],$question['qid'])=explode("X",$question['sgq']);
else
list($question['sid'],$question['gid'],$question['qid'])=array('','','');
$question['aid']= (isset($question['aid']) ? $question['aid'] : '');
} }
else else
{ {
@ -393,8 +423,7 @@ function templatereplace($line, $replacements = array(), &$redata = array(), $de
{ {
$_saveall = ""; $_saveall = "";
} }
$help= isset($question['questionhelp']) ? $question['questionhelp'] : isset($help) ? $help : "";
if(!isset($help)) $help = "";
if (flattenText($help, true,true) != '') if (flattenText($help, true,true) != '')
{ {
if (!isset($helpicon)) if (!isset($helpicon))
@ -703,7 +732,7 @@ EOD;
$coreReplacements = array(); $coreReplacements = array();
$coreReplacements['ACTIVE'] = (isset($thissurvey['active']) && !($thissurvey['active'] != "Y")); $coreReplacements['ACTIVE'] = (isset($thissurvey['active']) && !($thissurvey['active'] != "Y"));
$coreReplacements['AID'] = $question['aid']; $coreReplacements['AID'] = $question['aid'];
$coreReplacements['ANSWER'] = isset($answer) ? $answer : ''; // global $coreReplacements['ANSWER'] = isset($question['answers']) ? $question['answers'] : (isset($answer) ? $answer : '');
$coreReplacements['ANSWERSCLEARED'] = $clang->gT("Answers cleared"); $coreReplacements['ANSWERSCLEARED'] = $clang->gT("Answers cleared");
$coreReplacements['ASSESSMENTS'] = $assessmenthtml; $coreReplacements['ASSESSMENTS'] = $assessmenthtml;
$coreReplacements['ASSESSMENT_CURRENT_TOTAL'] = $_assessment_current_total; $coreReplacements['ASSESSMENT_CURRENT_TOTAL'] = $_assessment_current_total;
@ -760,7 +789,7 @@ EOD;
$coreReplacements['SAVEERROR'] = isset($errormsg) ? $errormsg : ''; // global - same as LOADERROR $coreReplacements['SAVEERROR'] = isset($errormsg) ? $errormsg : ''; // global - same as LOADERROR
$coreReplacements['SAVEFORM'] = $_saveform; $coreReplacements['SAVEFORM'] = $_saveform;
$coreReplacements['SAVEHEADING'] = $clang->gT("Save your unfinished survey"); $coreReplacements['SAVEHEADING'] = $clang->gT("Save your unfinished survey");
$coreReplacements['SAVEMESSAGE'] = $clang->gT("Enter a name and password for this survey and click save below.")."<br />\n".$clang->gT("Your survey will be saved using that name and password, and can be completed later by logging in with the same name and password.")."<br /><br />\n".$clang->gT("If you give an email address, an email containing the details will be sent to you.")."<br /><br />\n".$clang->gT("After having clicked the save button you can either close this browser window or continue filling out the survey."); $coreReplacements['SAVEMESSAGE'] = $clang->gT("Enter a name and password for this survey and click save below.")."<br />\n".$clang->gT("Your survey will be saved using that name and password, and can be completed later by logging in with the same name and password.")."<br /><br /><span class='emailoptional'>\n".$clang->gT("If you give an email address, an email containing the details will be sent to you.")."</span><br /><br />\n".$clang->gT("After having clicked the save button you can either close this browser window or continue filling out the survey.");
$coreReplacements['SGQ'] = $question['sgq']; $coreReplacements['SGQ'] = $question['sgq'];
$coreReplacements['SID'] = Yii::app()->getConfig('surveyID','');// Allways use surveyID from config $coreReplacements['SID'] = Yii::app()->getConfig('surveyID','');// Allways use surveyID from config
$coreReplacements['SITENAME'] = isset($sitename) ? $sitename : ''; // global $coreReplacements['SITENAME'] = isset($sitename) ? $sitename : ''; // global

View file

@ -139,7 +139,7 @@ function sanitize_filename($string, $force_lowercase = true, $alphanumeric = fal
* $alphanumeric - If set to *true*, will remove all non-alphanumeric characters. * $alphanumeric - If set to *true*, will remove all non-alphanumeric characters.
*/ */
function sanitize_dirname($string, $force_lowercase = true, $alphanumeric = false) { function sanitize_dirname($string, $force_lowercase = false, $alphanumeric = false) {
$string = str_replace(".", "", $string); $string = str_replace(".", "", $string);
return sanitize_filename($string, $force_lowercase, $alphanumeric); return sanitize_filename($string, $force_lowercase, $alphanumeric);
} }

View file

@ -364,6 +364,13 @@
$supportedLanguages['ja']['dateformat'] = 6; $supportedLanguages['ja']['dateformat'] = 6;
$supportedLanguages['ja']['radixpoint'] = 0; $supportedLanguages['ja']['radixpoint'] = 0;
// Kazakh
$supportedLanguages['kk']['description'] = $clang->gT('Kazakh');
$supportedLanguages['kk']['nativedescription'] = 'Qazaq&#351;a';
$supportedLanguages['kk']['rtl'] = false;
$supportedLanguages['kk']['dateformat'] = 1;
$supportedLanguages['kk']['radixpoint'] = 1;
// Kinyarwanda // Kinyarwanda
$supportedLanguages['rw']['description'] = $clang->gT('Kinyarwanda'); $supportedLanguages['rw']['description'] = $clang->gT('Kinyarwanda');
$supportedLanguages['rw']['nativedescription'] = 'Kinyarwanda'; $supportedLanguages['rw']['nativedescription'] = 'Kinyarwanda';
@ -385,6 +392,12 @@
$supportedLanguages['ckb']['dateformat'] = 1; $supportedLanguages['ckb']['dateformat'] = 1;
$supportedLanguages['ckb']['radixpoint'] = 1; $supportedLanguages['ckb']['radixpoint'] = 1;
// Kyrgyz
$supportedLanguages['ky']['description'] = $clang->gT('Kyrgyz');
$supportedLanguages['ky']['nativedescription'] = '&#1050;&#1099;&#1088;&#1075;&#1099;&#1079;&#1095;&#1072;';
$supportedLanguages['ky']['rtl'] = false;
$supportedLanguages['ky']['dateformat'] = 1;
$supportedLanguages['ky']['radixpoint'] = 1;
// Lithuanian // Lithuanian
$supportedLanguages['lt']['description'] = $clang->gT('Lithuanian'); $supportedLanguages['lt']['description'] = $clang->gT('Lithuanian');
@ -491,6 +504,13 @@
$supportedLanguages['pl']['dateformat'] = 1; $supportedLanguages['pl']['dateformat'] = 1;
$supportedLanguages['pl']['radixpoint'] = 1; $supportedLanguages['pl']['radixpoint'] = 1;
// Polish
$supportedLanguages['pl']['description'] = $clang->gT('Polish (Informal)');
$supportedLanguages['pl']['nativedescription'] = 'Polski (nieformalny)';
$supportedLanguages['pl']['rtl'] = false;
$supportedLanguages['pl']['dateformat'] = 1;
$supportedLanguages['pl']['radixpoint'] = 1;
// Portuguese // Portuguese
$supportedLanguages['pt']['description'] = $clang->gT('Portuguese'); $supportedLanguages['pt']['description'] = $clang->gT('Portuguese');
$supportedLanguages['pt']['nativedescription'] = 'Portugu&#234;s'; $supportedLanguages['pt']['nativedescription'] = 'Portugu&#234;s';

View file

@ -231,7 +231,7 @@ function db_upgrade_all($iOldDBVersion) {
// copy assessment link to message since from now on we will have HTML assignment messages // copy assessment link to message since from now on we will have HTML assignment messages
$oDB->createCommand("UPDATE {{assessments}} set message=replace(message,'/''','''')||'<br /><a href=\"'||link||'\">'||link||'</a>'")->execute(); $oDB->createCommand("UPDATE {{assessments}} set message=replace(message,'/''','''')||'<br /><a href=\"'||link||'\">'||link||'</a>'")->execute();
break; break;
default: die('Unkown database type'); default: die('Unknown database type');
} }
// activate assessment where assessment rules exist // activate assessment where assessment rules exist
$oDB->createCommand("UPDATE {{surveys}} SET assessments='Y' where sid in (SELECT sid FROM {{assessments}} group by sid)")->execute(); $oDB->createCommand("UPDATE {{surveys}} SET assessments='Y' where sid in (SELECT sid FROM {{assessments}} group by sid)")->execute();
@ -509,7 +509,8 @@ function db_upgrade_all($iOldDBVersion) {
alterColumn('{{questions}}','parent_qid','integer',false ,'0'); alterColumn('{{questions}}','parent_qid','integer',false ,'0');
alterColumn('{{questions}}','title',"{$sVarchar}(20)",false , ''); alterColumn('{{questions}}','title',"{$sVarchar}(20)",false , '');
alterColumn('{{questions}}','question',"text",false); alterColumn('{{questions}}','question',"text",false);
try{ $oDB->createCommand()->dropIndex('questions_idx4','{{questions}}');} catch(Exception $e){}; try { setTransactionBookmark(); $oDB->createCommand()->dropIndex('questions_idx4','{{questions}}'); } catch(Exception $e) { rollBackToTransactionBookmark();}
alterColumn('{{questions}}','type',"{$sVarchar}(1)",false , 'T'); alterColumn('{{questions}}','type',"{$sVarchar}(1)",false , 'T');
try{ $oDB->createCommand()->createIndex('questions_idx4','{{questions}}','type');} catch(Exception $e){}; try{ $oDB->createCommand()->createIndex('questions_idx4','{{questions}}','type');} catch(Exception $e){};
alterColumn('{{questions}}','other',"{$sVarchar}(1)",false , 'N'); alterColumn('{{questions}}','other',"{$sVarchar}(1)",false , 'N');
@ -676,10 +677,8 @@ function db_upgrade_all($iOldDBVersion) {
'date_created' => 'datetime NOT NULL' 'date_created' => 'datetime NOT NULL'
)); ));
addPrimaryKey('survey_links', array('participant_id','token_id','survey_id')); addPrimaryKey('survey_links', array('participant_id','token_id','survey_id'));
// Add language field to question_attributes table // Add language field to question_attributes table
addColumn('{{question_attributes}}','language',"{$sVarchar}(20)"); addColumn('{{question_attributes}}','language',"{$sVarchar}(20)");
upgradeQuestionAttributes148(); upgradeQuestionAttributes148();
fixSubquestions(); fixSubquestions();
$oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>148),"stg_name='DBVersion'"); $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>148),"stg_name='DBVersion'");
@ -1016,6 +1015,7 @@ function db_upgrade_all($iOldDBVersion) {
LimeExpressionManager::UpgradeConditionsToRelevance(); LimeExpressionManager::UpgradeConditionsToRelevance();
$oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>158),"stg_name='DBVersion'"); $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>158),"stg_name='DBVersion'");
} }
if ($iOldDBVersion < 159) if ($iOldDBVersion < 159)
{ {
alterColumn('{{failed_login_attempts}}', 'ip', "{$sVarchar}(40)",false); alterColumn('{{failed_login_attempts}}', 'ip', "{$sVarchar}(40)",false);
@ -1160,7 +1160,7 @@ function db_upgrade_all($iOldDBVersion) {
case 'pgsql': case 'pgsql':
addColumn('{{sessions}}', 'data', 'BYTEA'); addColumn('{{sessions}}', 'data', 'BYTEA');
break; break;
default: die('Unkown database type'); default: die('Unknown database type');
} }
$oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>171),"stg_name='DBVersion'"); $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>171),"stg_name='DBVersion'");
} }
@ -1250,7 +1250,14 @@ function db_upgrade_all($iOldDBVersion) {
upgradeSurveys177(); upgradeSurveys177();
$oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>177),"stg_name='DBVersion'"); $oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>177),"stg_name='DBVersion'");
} }
if ($iOldDBVersion < 178)
{
if ($sDBDriverName=='mysql' || $sDBDriverName=='mysqli')
{
modifyPrimaryKey('questions', array('qid','language'));
}
$oDB->createCommand()->update('{{settings_global}}',array('stg_value'=>178),"stg_name='DBVersion'");
}
$oTransaction->commit(); $oTransaction->commit();
// Activate schema caching // Activate schema caching
@ -1280,23 +1287,26 @@ function db_upgrade_all($iOldDBVersion) {
function upgradeSurveys177() function upgradeSurveys177()
{ {
$sSurveyQuery = "SELECT * FROM {{surveys_languagesettings}}"; $sSurveyQuery = "SELECT surveyls_attributecaptions,surveyls_survey_id,surveyls_language FROM {{surveys_languagesettings}}";
$oSurveyResult = Yii::app()->db->createCommand($sSurveyQuery)->queryAll(); $oSurveyResult = Yii::app()->db->createCommand($sSurveyQuery)->queryAll();
$sSurveyLSUpdateQuery= "update {{surveys_languagesettings}} set surveyls_attributecaptions=:attributecaptions where surveyls_survey_id=:surveyid and surveyls_language=:language";
foreach ( $oSurveyResult as $aSurveyRow ) foreach ( $oSurveyResult as $aSurveyRow )
{ {
$aAttributeDescriptions=@unserialize($aSurveyRow['surveyls_attributecaptions']); $aAttributeDescriptions=@unserialize($aSurveyRow['surveyls_attributecaptions']);
if ($aAttributeDescriptions==NULL) $aAttributeDescriptions=array(); if (!$aAttributeDescriptions) $aAttributeDescriptions=array();
$sSurveyLSUpdateQuery= "update {{surveys_languagesettings}} set surveyls_attributecaptions=:attributecaptions where surveyls_survey_id=".$aSurveyRow['surveyls_survey_id'].' and surveyls_language=:language'; Yii::app()->db->createCommand($sSurveyLSUpdateQuery)->execute(
Yii::app()->db->createCommand($sSurveyLSUpdateQuery)->execute(array(':language'=>$aSurveyRow['surveyls_language'],':attributecaptions'=>json_encode($aAttributeDescriptions))); array(':language'=>$aSurveyRow['surveyls_language'],
':surveyid'=>$aSurveyRow['surveyls_survey_id'],
':attributecaptions'=>json_encode($aAttributeDescriptions)));
} }
$sSurveyQuery = "SELECT * FROM {{surveys}}"; $sSurveyQuery = "SELECT sid,attributedescriptions FROM {{surveys}}";
$oSurveyResult = Yii::app()->db->createCommand($sSurveyQuery)->queryAll(); $oSurveyResult = Yii::app()->db->createCommand($sSurveyQuery)->queryAll();
$sSurveyUpdateQuery= "update {{surveys}} set attributedescriptions=:attributedescriptions where sid=:surveyid";
foreach ( $oSurveyResult as $aSurveyRow ) foreach ( $oSurveyResult as $aSurveyRow )
{ {
$aAttributeDescriptions=@unserialize($aSurveyRow['attributedescriptions']); $aAttributeDescriptions=@unserialize($aSurveyRow['attributedescriptions']);
if ($aAttributeDescriptions==NULL) $aAttributeDescriptions=array(); if (!$aAttributeDescriptions) $aAttributeDescriptions=array();
$sSurveyUpdateQuery= "update {{surveys}} set attributedescriptions=:attributedescriptions where sid=".$aSurveyRow['sid']; Yii::app()->db->createCommand($sSurveyUpdateQuery)->execute(array(':attributedescriptions'=>json_encode($aAttributeDescriptions),':surveyid'=>$aSurveyRow['sid']));
Yii::app()->db->createCommand($sSurveyUpdateQuery)->execute(array(':attributedescriptions'=>json_encode($aAttributeDescriptions)));
} }
} }
@ -1340,6 +1350,7 @@ function upgradeTokens176()
Survey::model()->updateByPk($arSurvey->sid, array('attributedescriptions' => serialize($aAttributes))); Survey::model()->updateByPk($arSurvey->sid, array('attributedescriptions' => serialize($aAttributes)));
} }
} }
unset($arSurveys);
// Now fix all 'old' token tables // Now fix all 'old' token tables
$aTables = dbGetTablesLike("%old_tokens%"); $aTables = dbGetTablesLike("%old_tokens%");
foreach ( $aTables as $sTable ) foreach ( $aTables as $sTable )
@ -1525,9 +1536,9 @@ function upgradeTokens148()
function upgradeQuestionAttributes148() function upgradeQuestionAttributes148()
{ {
global $modifyoutput;
$sSurveyQuery = "SELECT sid FROM {{surveys}}"; $sSurveyQuery = "SELECT sid FROM {{surveys}}";
$oSurveyResult = dbExecuteAssoc($sSurveyQuery); $oSurveyResult = dbExecuteAssoc($sSurveyQuery);
$aAllAttributes=questionAttributes(true);
foreach ( $oSurveyResult->readAll() as $aSurveyRow) foreach ( $oSurveyResult->readAll() as $aSurveyRow)
{ {
$iSurveyID=$aSurveyRow['sid']; $iSurveyID=$aSurveyRow['sid'];
@ -1535,7 +1546,6 @@ function upgradeQuestionAttributes148()
$sAttributeQuery = "select q.qid,attribute,value from {{question_attributes}} qa , {{questions}} q where q.qid=qa.qid and sid={$iSurveyID}"; $sAttributeQuery = "select q.qid,attribute,value from {{question_attributes}} qa , {{questions}} q where q.qid=qa.qid and sid={$iSurveyID}";
$oAttributeResult = dbExecuteAssoc($sAttributeQuery); $oAttributeResult = dbExecuteAssoc($sAttributeQuery);
$aAllAttributes=questionAttributes(true);
foreach ( $oAttributeResult->readAll() as $aAttributeRow) foreach ( $oAttributeResult->readAll() as $aAttributeRow)
{ {
if (isset($aAllAttributes[$aAttributeRow['attribute']]['i18n']) && $aAllAttributes[$aAttributeRow['attribute']]['i18n']) if (isset($aAllAttributes[$aAttributeRow['attribute']]['i18n']) && $aAllAttributes[$aAttributeRow['attribute']]['i18n'])
@ -1544,7 +1554,7 @@ function upgradeQuestionAttributes148()
foreach ($aLanguages as $sLanguage) foreach ($aLanguages as $sLanguage)
{ {
$sAttributeInsertQuery="insert into {{question_attributes}} (qid,attribute,value,language) VALUES({$aAttributeRow['qid']},'{$aAttributeRow['attribute']}','{$aAttributeRow['value']}','{$sLanguage}' )"; $sAttributeInsertQuery="insert into {{question_attributes}} (qid,attribute,value,language) VALUES({$aAttributeRow['qid']},'{$aAttributeRow['attribute']}','{$aAttributeRow['value']}','{$sLanguage}' )";
modifyDatabase("",$sAttributeInsertQuery); echo $modifyoutput; flush();@ob_flush(); modifyDatabase("",$sAttributeInsertQuery);
} }
} }
} }
@ -2025,9 +2035,23 @@ function alterLanguageCode($sOldLanguageCode,$sNewLanguageCode)
function addPrimaryKey($sTablename, $aColumns) function addPrimaryKey($sTablename, $aColumns)
{ {
Yii::app()->db->createCommand("ALTER TABLE {{".$sTablename."}} ADD PRIMARY KEY (".implode(',',$aColumns).")")->execute(); $sDBDriverName=Yii::app()->db->getDriverName();
if ($sDBDriverName=='mysqli' || $sDBDriverName=='mysql')
{
Yii::app()->db->createCommand("ALTER TABLE {{".$sTablename."}} ADD PRIMARY KEY (".implode(',',$aColumns).")")->execute();
}
} }
/**
* Modifies a primary key in one command - this is only tested on MySQL
*
* @param string $sTablename The table name
* @param array $aColumns Column names to be in the new key
*/
function modifyPrimaryKey($sTablename, $aColumns)
{
Yii::app()->db->createCommand("ALTER TABLE {{".$sTablename."}} DROP PRIMARY KEY, ADD PRIMARY KEY (".implode(',',$aColumns).")")->execute();
}
function dropPrimaryKey($sTablename) function dropPrimaryKey($sTablename)
{ {
@ -2054,7 +2078,7 @@ function dropPrimaryKey($sTablename)
Yii::app()->db->createCommand($sQuery)->execute(); Yii::app()->db->createCommand($sQuery)->execute();
} }
break; break;
default: die('Unkown database type'); default: die('Unknown database type');
} }
// find out the constraint name of the old primary key // find out the constraint name of the old primary key
@ -2127,7 +2151,7 @@ function alterColumn($sTable, $sColumn, $sFieldType, $bAllowNull=true, $sDefault
} }
Yii::app()->db->createCommand()->alterColumn($sTable,$sColumn,$sType); Yii::app()->db->createCommand()->alterColumn($sTable,$sColumn,$sType);
break; break;
default: die('Unkown database type'); default: die('Unknown database type');
} }
} }
@ -2136,10 +2160,7 @@ function alterColumn($sTable, $sColumn, $sFieldType, $bAllowNull=true, $sDefault
function dropColumn($sTableName, $sColumnName) function dropColumn($sTableName, $sColumnName)
{ {
$sDBDriverName=Yii::app()->db->getDriverName(); $sDBDriverName=Yii::app()->db->getDriverName();
if ($sDBDriverName=='mysqli') $sDBDriverName='mysql'; if ($sDBDriverName=='mssql' || $sDBDriverName=='sqlsrv' || $sDBDriverName=='dblib')
if ($sDBDriverName=='sqlsrv' || $sDBDriverName=='dblib') $sDBDriverName='mssql';
if ($sDBDriverName=='mssql')
{ {
dropDefaultValueMSSQL($sColumnName,$sTableName); dropDefaultValueMSSQL($sColumnName,$sTableName);
} }

View file

@ -229,7 +229,9 @@
protected static function xmlrpc_echo_stream($data) protected static function xmlrpc_echo_stream($data)
{ {
echo '<string>'; // a Base64 tag would be more sensible here but it would break all current implementations
$data->render(); $data->render();
echo '</string>';
} }
protected static function xmlrpc_echo_string($data) protected static function xmlrpc_echo_string($data)

View file

@ -35,6 +35,21 @@ abstract class AuthPluginBase extends PluginBase {
return $this->_username; return $this->_username;
} }
/**
* Set username and password
*
* @return null
*/
public function afterLoginFormSubmit()
{
// Here we handle post data
$request = $this->api->getRequest();
if ($request->getIsPostRequest()) {
$this->setUsername( $request->getPost('user'));
$this->setPassword($request->getPost('password'));
}
}
/** /**
* Set authentication result to success for the given user object. * Set authentication result to success for the given user object.
* *

View file

@ -266,9 +266,10 @@
{ {
$tables = array(); $tables = array();
$base = App()->getDb()->tablePrefix . 'old_survey_' . $surveyId; $base = App()->getDb()->tablePrefix . 'old_survey_' . $surveyId;
$timingbase = App()->getDb()->tablePrefix . 'old_survey_' . $surveyId . '_timings_';
foreach (App()->getDb()->getSchema()->getTableNames() as $table) foreach (App()->getDb()->getSchema()->getTableNames() as $table)
{ {
if (strpos($table, $base) === 0) if (strpos($table, $base) === 0 && strpos($table, $timingbase)===false)
$tables[] = $table; $tables[] = $table;
} }
return $tables; return $tables;

View file

@ -152,7 +152,7 @@ class Save {
"datestamp" => $today, "datestamp" => $today,
"ipaddr" => getIPAddress(), "ipaddr" => getIPAddress(),
"startlanguage" => $_SESSION['survey_'.$surveyid]['s_lang'], "startlanguage" => $_SESSION['survey_'.$surveyid]['s_lang'],
"refurl" => getenv("HTTP_REFERER") "refurl" => ((isset($_SESSION['survey_'.$surveyid]['refurl'])) ? $_SESSION['survey_'.$surveyid]['refurl'] : getenv('HTTP_REFERER'))
); );
if (SurveyDynamic::model($thissurvey['sid'])->insert($sdata)) // Checked if (SurveyDynamic::model($thissurvey['sid'])->insert($sdata)) // Checked
{ {
@ -176,7 +176,14 @@ class Save {
$saved_control->saved_thisstep = $thisstep; $saved_control->saved_thisstep = $thisstep;
$saved_control->status = 'S'; $saved_control->status = 'S';
$saved_control->saved_date = $today; $saved_control->saved_date = $today;
$saved_control->refurl = getenv('HTTP_REFERER'); if (isset($_SESSION['survey_'.$surveyid]['refurl']))
{
$saved_control->refurl = $_SESSION['survey_'.$surveyid]['refurl'];
}
else
{
$saved_control->refurl = getenv("HTTP_REFERER");
}
if ($saved_control->save()) if ($saved_control->save())
{ {

View file

@ -19,144 +19,144 @@ if(!defined('K_TCPDF_EXTERNAL_CONFIG')) {
# include TCPDF # include TCPDF
require(APPPATH.'config/tcpdf'.EXT); require(APPPATH.'config/tcpdf'.EXT);
require_once($tcpdf['base_directory'].'/tcpdf.php');
/** /**
* page format * page format
*/ */
(!defined ('PDF_PAGE_FORMAT')) ? (define ('PDF_PAGE_FORMAT', 'A4')):''; (!defined ('PDF_PAGE_FORMAT')) ? (define ('PDF_PAGE_FORMAT', isset($tcpdf['page_format']) ? $tcpdf['page_format'] : 'A4')):'';
/** /**
* page orientation (P=portrait, L=landscape) * page orientation (P=portrait, L=landscape)
*/ */
(!defined ('PDF_PAGE_ORIENTATION')) ? (define('PDF_PAGE_ORIENTATION', 'P')):''; (!defined ('PDF_PAGE_ORIENTATION')) ? (define('PDF_PAGE_ORIENTATION', isset($tcpdf['page_orientation']) ? $tcpdf['page_orientation'] :'P')):'';
/** /**
* document creator * document creator
*/ */
(!defined ('PDF_CREATOR'))?(define ('PDF_CREATOR', 'TCPDF')):''; (!defined ('PDF_CREATOR'))?(define ('PDF_CREATOR', isset($tcpdf['creator']) ? $tcpdf['creator'] : 'TCPDF')):'';
/** /**
* document author * document author
*/ */
(!defined ('PDF_AUTHOR'))? (define ('PDF_AUTHOR', 'TCPDF')):''; (!defined ('PDF_AUTHOR'))? (define ('PDF_AUTHOR', isset($tcpdf['author']) ? $tcpdf['author'] : 'TCPDF')):'';
/** /**
* header title * header title
*/ */
(!defined ('PDF_HEADER_TITLE'))? (define ('PDF_HEADER_TITLE', 'TCPDF Example')):''; (!defined ('PDF_HEADER_TITLE'))? (define ('PDF_HEADER_TITLE', isset($tcpdf['header_title']) ? $tcpdf['header_title'] : 'TCPDF Example')):'';
/** /**
* header description string * header description string
*/ */
(!defined ('PDF_HEADER_STRING'))? (define ('PDF_HEADER_STRING', "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org")):''; (!defined ('PDF_HEADER_STRING'))? (define ('PDF_HEADER_STRING', isset($tcpdf['header_string']) ? $tcpdf['header_string'] : "by Nicola Asuni - Tecnick.com\nwww.tcpdf.org")):'';
/** /**
* image logo * image logo
*/ */
(!defined ('PDF_HEADER_LOGO'))? (define ('PDF_HEADER_LOGO', 'tcpdf_logo.jpg')):''; (!defined ('PDF_HEADER_LOGO'))? (define ('PDF_HEADER_LOGO', isset($tcpdf['header_logo']) ? $tcpdf['header_logo'] : 'tcpdf_logo.jpg')):'';
/** /**
* header logo image width [mm] * header logo image width [mm]
*/ */
(!defined ('PDF_HEADER_LOGO_WIDTH'))? (define ('PDF_HEADER_LOGO_WIDTH', 30)):''; (!defined ('PDF_HEADER_LOGO_WIDTH'))? (define ('PDF_HEADER_LOGO_WIDTH', isset($tcpdf['header_logo_width']) ? $tcpdf['header_logo_width'] : 30)):'';
/** /**
* document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch] * document unit of measure [pt=point, mm=millimeter, cm=centimeter, in=inch]
*/ */
(!defined ('PDF_UNIT'))? (define ('PDF_UNIT', 'mm')):''; (!defined ('PDF_UNIT'))? (define ('PDF_UNIT', isset($tcpdf['page_unit']) ? $tcpdf['page_unit'] : 'mm')):'';
/** /**
* header margin * header margin
*/ */
(!defined ('PDF_MARGIN_HEADER'))? (define ('PDF_MARGIN_HEADER', 5)):''; (!defined ('PDF_MARGIN_HEADER'))? (define ('PDF_MARGIN_HEADER', isset($tcpdf['header_margin']) ? $tcpdf['header_margin'] : 5)):'';
/** /**
* footer margin * footer margin
*/ */
(!defined ('PDF_MARGIN_FOOTER'))? (define ('PDF_MARGIN_FOOTER', 10)):''; (!defined ('PDF_MARGIN_FOOTER'))? (define ('PDF_MARGIN_FOOTER', isset($tcpdf['footer_margin']) ? $tcpdf['footer_margin'] : 10)):'';
/** /**
* top margin * top margin
*/ */
(!defined ('PDF_MARGIN_TOP'))? (define ('PDF_MARGIN_TOP', 27)):''; (!defined ('PDF_MARGIN_TOP'))? (define ('PDF_MARGIN_TOP', isset($tcpdf['margin_top']) ? $tcpdf['margin_top'] : 27)):'';
/** /**
* bottom margin * bottom margin
*/ */
(!defined ('PDF_MARGIN_BOTTOM'))? (define ('PDF_MARGIN_BOTTOM', 25)):''; (!defined ('PDF_MARGIN_BOTTOM'))? (define ('PDF_MARGIN_BOTTOM', isset($tcpdf['margin_bottom']) ? $tcpdf['margin_bottom'] : 25)):'';
/** /**
* left margin * left margin
*/ */
(!defined ('PDF_MARGIN_LEFT'))? (define ('PDF_MARGIN_LEFT', 15)):''; (!defined ('PDF_MARGIN_LEFT'))? (define ('PDF_MARGIN_LEFT', isset($tcpdf['margin_left']) ? $tcpdf['margin_left'] : 15)):'';
/** /**
* right margin * right margin
*/ */
(!defined ('PDF_MARGIN_RIGHT'))? (define ('PDF_MARGIN_RIGHT', 15)):''; (!defined ('PDF_MARGIN_RIGHT'))? (define ('PDF_MARGIN_RIGHT', isset($tcpdf['margin_right']) ? $tcpdf['margin_right'] : 15)):'';
/** /**
* default main font name * default main font name
*/ */
(!defined ('PDF_FONT_NAME_MAIN'))? (define ('PDF_FONT_NAME_MAIN', 'helvetica')):''; (!defined ('PDF_FONT_NAME_MAIN'))? (define ('PDF_FONT_NAME_MAIN', isset($tcpdf['page_font']) ? $tcpdf['page_font'] : 'helvetica')):'';
/** /**
* default main font size * default main font size
*/ */
(!defined ('PDF_FONT_SIZE_MAIN'))? (define ('PDF_FONT_SIZE_MAIN', 10)):''; (!defined ('PDF_FONT_SIZE_MAIN'))? (define ('PDF_FONT_SIZE_MAIN', isset($tcpdf['page_font_size']) ? $tcpdf['page_font_size'] : 10)):'';
/** /**
* default data font name * default data font name
*/ */
(!defined ('PDF_FONT_NAME_DATA'))? (define ('PDF_FONT_NAME_DATA', 'helvetica')):''; (!defined ('PDF_FONT_NAME_DATA'))? (define ('PDF_FONT_NAME_DATA', isset($tcpdf['data_font']) ? $tcpdf['data_font'] : 'helvetica')):'';
/** /**
* default data font size * default data font size
*/ */
(!defined ('PDF_FONT_SIZE_DATA'))? (define ('PDF_FONT_SIZE_DATA', 8)):''; (!defined ('PDF_FONT_SIZE_DATA'))? (define ('PDF_FONT_SIZE_DATA', isset($tcpdf['data_font_size']) ? $tcpdf['data_font_size'] : 8)):'';
/** /**
* default monospaced font name * default monospaced font name
*/ */
(!defined ('PDF_FONT_MONOSPACED'))? (define ('PDF_FONT_MONOSPACED', 'courier')):''; (!defined ('PDF_FONT_MONOSPACED'))? (define ('PDF_FONT_MONOSPACED', isset($tcpdf['mono_font']) ? $tcpdf['mono_font'] : 'courier')):'';
/** /**
* ratio used to adjust the conversion of pixels to user units * ratio used to adjust the conversion of pixels to user units
*/ */
(!defined ('PDF_IMAGE_SCALE_RATIO'))? (define ('PDF_IMAGE_SCALE_RATIO', 1.25)):''; (!defined ('PDF_IMAGE_SCALE_RATIO'))? (define ('PDF_IMAGE_SCALE_RATIO', isset($tcpdf['image_scale']) ? $tcpdf['image_scale'] : 1.25)):'';
/** /**
* magnification factor for titles * magnification factor for titles
*/ */
(!defined('HEAD_MAGNIFICATION'))? (define('HEAD_MAGNIFICATION', 1.1)):''; (!defined('HEAD_MAGNIFICATION'))? (define('HEAD_MAGNIFICATION', 1.1)):''; // never used in TCPDF 6.
/** /**
* height of cell repect font height * height of cell repect font height
*/ */
(!defined('K_CELL_HEIGHT_RATIO'))? (define('K_CELL_HEIGHT_RATIO', 1.25)):''; (!defined('K_CELL_HEIGHT_RATIO'))? (define('K_CELL_HEIGHT_RATIO', isset($tcpdf['cell_height_ratio']) ? $tcpdf['cell_height_ratio'] : 1.25)):'';
/** /**
* title magnification respect main font size * title magnification respect main font size
*/ */
(!defined('K_TITLE_MAGNIFICATION'))? (define('K_TITLE_MAGNIFICATION', 1.3)):''; (!defined('K_TITLE_MAGNIFICATION'))? (define('K_TITLE_MAGNIFICATION', 1.3)):''; // never used in TCPDF 6.
/** /**
* reduction factor for small font * reduction factor for small font
*/ */
(!defined('K_SMALL_RATIO'))? (define('K_SMALL_RATIO', 2/3)):''; (!defined('K_SMALL_RATIO'))? (define('K_SMALL_RATIO', isset ($tcpdf['small_font_ratio']) ? $tcpdf['small_font_ratio'] : 2/3)):'';
/** /**
* set to true to enable the special procedure used to avoid the overlappind of symbols on Thai language * set to true to enable the special procedure used to avoid the overlapping of symbols on Thai language
*/ */
(!defined('K_THAI_TOPCHARS'))? (define('K_THAI_TOPCHARS', true)):''; (!defined('K_THAI_TOPCHARS'))? (define('K_THAI_TOPCHARS', isset($tcpdf['thai_top_chars']) ? $tcpdf['thai_top_chars'] : true)):'';
/** /**
* if true allows to call TCPDF methods using HTML syntax * if true allows to call TCPDF methods using HTML syntax
* IMPORTANT: For security reason, disable this feature if you are printing user HTML content. * IMPORTANT: For security reason, disable this feature if you are printing user HTML content.
*/ */
(!defined('K_TCPDF_CALLS_IN_HTML'))? (define('K_TCPDF_CALLS_IN_HTML', true)):''; (!defined('K_TCPDF_CALLS_IN_HTML'))? (define('K_TCPDF_CALLS_IN_HTML', isset($tcpdf['tcpdf_in_html']) ? $tcpdf['tcpdf_in_html'] : true)):'';
require_once($tcpdf['base_directory'].'/tcpdf.php');
/************************************************************ /************************************************************
* TCPDF - CodeIgniter Integration * TCPDF - CodeIgniter Integration
@ -194,6 +194,30 @@ class pdf extends TCPDF {
*/ */
private $_config = array(); private $_config = array();
/**
* Base font size for answer PDF export
*
* @var int
* @access private
*/
private $_ibaseAnswerFontSize = 12;
/**
* Cell height for answer PDF export
*
* @var int
* @access private
*/
private $_iCellHeight = 6;
/**
* Survey Information (preventing from passing to methods every time)
*
* @var array
* @access private
*/
private $_aSurveyInfo = array();
/** /**
* Set _config for pdf * Set _config for pdf
* @access public * @access public
@ -237,13 +261,6 @@ class pdf extends TCPDF {
); );
# language settings
if(is_file($this->_config['language_file'])) {
include($this->_config['language_file']);
$this->setLanguageArray($l);
unset($l);
}
# margin settings # margin settings
$this->SetMargins($this->_config['margin_left'], $this->_config['margin_top'], $this->_config['margin_right']); $this->SetMargins($this->_config['margin_left'], $this->_config['margin_top'], $this->_config['margin_right']);
@ -609,4 +626,162 @@ class pdf extends TCPDF {
$text = str_replace("\t",' ',$text); $text = str_replace("\t",' ',$text);
return strip_tags($text); return strip_tags($text);
} }
/**
*
* Create Answer PDF document, set metadata and set title
* @param $aSurveyInfo - Survey Information (preventing from passing to methods every time)
* @param $aPdfLanguageSettings - Pdf language settings
* @param $sSiteName - LimeSurvey site name (header and metadata)
* @param $sSurveyName - Survey name (header, metadata and title),
* @param $sDefaultHeaderString - TCPDF header string
* @return unknown_type
*/
function initAnswerPDF($aSurveyInfo, $aPdfLanguageSettings, $sSiteName, $sSurveyName, $sDefaultHeaderString = '')
{
if (empty($sDefaultHeaderString))
$sDefaultHeaderString = $sSurveyName;
$this->_aSurveyInfo = $aSurveyInfo;
$this->SetAuthor($sSiteName);
$this->SetTitle($sSurveyName);
$this->SetSubject($sSurveyName);
$this->SetKeywords($sSurveyName);
$this->SetFont($aPdfLanguageSettings['pdffont']);
$this->_ibaseAnswerFontSize = $aPdfLanguageSettings['pdffontsize'];
$this->_iCellHeight = ceil($this->_ibaseAnswerFontSize / 2);
$this->setLanguageArray($aPdfLanguageSettings['lg']);
$this->addHeader($aPdfLanguageSettings, $sSiteName, $sDefaultHeaderString);
$this->AddPage();
$this->SetFillColor(220, 220, 220);
$this->addTitle($sSurveyName);
}
/**
*
* Add title to pdf
* @param $sTitle - Title
* @param $sSubtitle - Subtitle
* @return unknown_type
*/
function addTitle($sTitle, $sSubtitle="")
{
if(!empty($sTitle))
{
$this->ln(1);
$this->SetFontSize($this->_ibaseAnswerFontSize + 6);
$oPurifier = new CHtmlPurifier();
$sTitleHTML = html_entity_decode(stripJavaScript($oPurifier->purify($sTitle)),ENT_COMPAT);
$this->WriteHTMLCell(0, $this->_iCellHeight, $this->getX(), $this->getY(), $sTitleHTML, 0, 1, false, true, 'C');
if (!empty($sSubtitle))
{
$this->ln(1);
$this->SetFontSize($this->_ibaseAnswerFontSize + 2);
$sSubtitleHTML = html_entity_decode(stripJavaScript($oPurifier->purify($sSubtitle)),ENT_COMPAT);
$this->WriteHTMLCell(0, $this->_iCellHeight, $this->getX(), $this->getY(), $sSubtitleHTML, 0, 1, false, true, 'C');
}
$this->ln(6);
$this->SetFontSize($this->_ibaseAnswerFontSize);
}
}
/**
*
* Add header to pdf
* @param $aPdfLanguageSettings - Pdf language settings
* @param $sSiteName - LimeSurvey site name (header and metadata)
* @param $sDefaultHeaderString - TCPDF header string
* @return unknown_type
*/
function addHeader($aPdfLanguageSettings, $sSiteName, $sDefaultHeaderString)
{
$sLogoFileName = Yii::app()->getConfig('pdflogofile');
if (Yii::app()->getConfig('pdfshowheader')=='Y' && file_exists(K_PATH_IMAGES.$sLogoFileName))
{
$sHeaderTitle = Yii::app()->getConfig('pdfheadertitle');
if ($sHeaderTitle == '') $sHeaderTitle = $sSiteName;
$sHeaderString = Yii::app()->getConfig('pdfheaderstring');
if ($sHeaderString == '') $sHeaderString = $sDefaultHeaderString;
$this->SetHeaderData($sLogoFileName, Yii::app()->getConfig('pdflogowidth'), $sHeaderTitle, $sHeaderString);
$this->SetHeaderFont(Array($aPdfLanguageSettings['pdffont'], '', $this->_ibaseAnswerFontSize - 2));
$this->SetFooterFont(Array($aPdfLanguageSettings['pdffont'], '', $this->_ibaseAnswerFontSize - 2));
}
}
/**
*
* Add GID text to PDF
* @param $sFname - Answer field text
* @param $bAllowBreakPage - Allow break cell in two pages
* @return unknown_type
*/
function addGidAnswer($sFname, $bAllowBreakPage=false)
{
$oPurifier = new CHtmlPurifier();
$sAnswerHTML = html_entity_decode(stripJavaScript($oPurifier->purify($sFname)),ENT_COMPAT);
$sData['thissurvey']=$this->_aSurveyInfo;
$sAnswerHTML = templatereplace($sAnswerHTML, array() , $sData, '', $this->_aSurveyInfo['anonymized']=="Y",NULL, array(), true);
$startPage = $this->getPage();
$this->startTransaction();
$this->ln(6);
$this->SetFontSize($this->_ibaseAnswerFontSize + 2);
$this->WriteHTMLCell(0, $this->_iCellHeight, $this->getX(), $this->getY(), $sAnswerHTML, 0, 1, false, true, 'L');
$this->ln(2);
if ($this->getPage() != $startPage && !$bAllowBreakPage)
{
$this->rollbackTransaction(true);
$this->AddPage();
$this->addGidAnswer($sFname,true); // Second param = true avoid an endless loop if a cell is longer than a page
}
else
{
$this->commitTransaction();
}
}
/**
*
* Add answer to PDF
*
* @param $sQuestion - Question field text array
* @param $sResponse - Answer field text array
* @param $bReplaceExpressions - Try to replace LimeSurvey Expressions. This is false when exporting answers PDF from admin GUI
* because we can not interpret expressions so just purify.
* TODO: Find a universal valid method to interpret expressions
* @param $bAllowBreakPage - Allow break cell in two pages
* @return unknown_type
*/
function addAnswer($sQuestion, $sResponse, $bReplaceExpressions=true, $bAllowBreakPage=false)
{
$oPurifier = new CHtmlPurifier();
$sQuestionHTML = str_replace('-oth-','',$sQuestion); // Copied from Writer::stripTagsFull. Really necessary?
$sQuestionHTML = html_entity_decode(stripJavaScript($oPurifier->purify($sQuestionHTML)),ENT_COMPAT);
if ($bReplaceExpressions)
{
$sData['thissurvey']=$this->_aSurveyInfo;
$sQuestionHTML = templatereplace($sQuestionHTML, array() , $sData, '', $this->_aSurveyInfo['anonymized']=="Y",NULL, array(), true);
}
$sResponse = flattenText($sResponse, false, true, 'UTF-8', false);
$startPage = $this->getPage();
$this->startTransaction();
$this->SetFontSize($this->_ibaseAnswerFontSize);
$this->WriteHTMLCell(0, $this->_iCellHeight, $this->getX(), $this->getY(), $sQuestionHTML, 1, 1, true, true, 'L');
$this->MultiCell(0, $this->_iCellHeight, $sResponse, 1, 'L', 0, 1, '', '', true);
$this->ln(2);
if ($this->getPage() != $startPage && !$bAllowBreakPage)
{
$this->rollbackTransaction(true);
$this->AddPage();
$this->addAnswer($sQuestion,$sResponse,$bReplaceExpressions,true); // "Last param = true" prevents an endless loop if a cell is longer than a page
}
else
{
$this->commitTransaction();
}
}
} }

View file

@ -19,7 +19,6 @@
*/ */
require('pdf.php'); require('pdf.php');
require_once($tcpdf['base_directory'].'/tcpdf.php'); require_once($tcpdf['base_directory'].'/tcpdf.php');
require_once($tcpdf['base_directory'].'/config/lang/eng.php');
/** /**
* A TCPDF based class to produce queXF compatible questionnaire PDF files and banding description XML from queXML * A TCPDF based class to produce queXF compatible questionnaire PDF files and banding description XML from queXML

View file

@ -68,7 +68,6 @@ class InstallerConfigForm extends CFormModel
array('dbtype, dblocation, dbname, dbuser', 'required', 'on' => 'database'), array('dbtype, dblocation, dbname, dbuser', 'required', 'on' => 'database'),
array('dbpwd, dbprefix', 'safe', 'on' => 'database'), array('dbpwd, dbprefix', 'safe', 'on' => 'database'),
array('dbtype', 'in', 'range' => array_keys($this->supported_db_types), 'on' => 'database'), array('dbtype', 'in', 'range' => array_keys($this->supported_db_types), 'on' => 'database'),
//Optional //Optional
array('adminLoginName, adminName, siteName, confirmPwd', 'safe', 'on' => 'optional'), array('adminLoginName, adminName, siteName, confirmPwd', 'safe', 'on' => 'optional'),
array('adminEmail', 'email', 'on' => 'optional'), array('adminEmail', 'email', 'on' => 'optional'),

View file

@ -296,6 +296,7 @@ class Participant extends LSActiveRecord
array_push($joinValue,"left join {{users}} luser ON luser.uid=p.owner_uid"); array_push($joinValue,"left join {{users}} luser ON luser.uid=p.owner_uid");
foreach($attid as $iAttributeID=>$aAttributeDetails) foreach($attid as $iAttributeID=>$aAttributeDetails)
{ {
if ($iAttributeID==0) continue;
$sDatabaseType = Yii::app()->db->getDriverName(); $sDatabaseType = Yii::app()->db->getDriverName();
if ($sDatabaseType=='mssql' || $sDatabaseType=="sqlsrv" || $sDatabaseType == 'dblib') if ($sDatabaseType=='mssql' || $sDatabaseType=="sqlsrv" || $sDatabaseType == 'dblib')
{ {
@ -953,7 +954,7 @@ class Participant extends LSActiveRecord
$aTokenAttributes[$key]['cpdbmap']=$iIDAttributeCPDB; $aTokenAttributes[$key]['cpdbmap']=$iIDAttributeCPDB;
Yii::app()->db Yii::app()->db
->createCommand() ->createCommand()
->update('{{surveys}}', array("attributedescriptions" => serialize($aAttributes)), 'sid = '.$surveyid); } ->update('{{surveys}}', array("attributedescriptions" => json_encode($aAttributes)), 'sid = '.$surveyid); }
} }
} }
foreach ($tokenattributefieldnames as $key => $value) foreach ($tokenattributefieldnames as $key => $value)
@ -1000,7 +1001,7 @@ class Participant extends LSActiveRecord
->from('{{surveys}}') ->from('{{surveys}}')
->bindParam(":sid", $surveyid, PDO::PARAM_INT); ->bindParam(":sid", $surveyid, PDO::PARAM_INT);
$aTokenAttributes = $previousatt->queryRow(); $aTokenAttributes = $previousatt->queryRow();
$aTokenAttributes = @unserialize($aTokenAttributes['attributedescriptions'],true); $aTokenAttributes = decodeTokenAttributes($aTokenAttributes['attributedescriptions'],true);
foreach($fieldcontents as $key=>$iIDAttributeCPDB) { foreach($fieldcontents as $key=>$iIDAttributeCPDB) {
$aTokenAttributes[$key]=$iIDAttributeCPDB; $aTokenAttributes[$key]=$iIDAttributeCPDB;
} }
@ -1021,10 +1022,10 @@ class Participant extends LSActiveRecord
} }
//Write each participant to the survey token table //Write each participant to the survey token table
foreach ($participantid as $key => $participant) foreach ($participantid as $key => $sParticipantUID)
{ {
$writearray = array(); $writearray = array();
$participantdata = Yii::app()->db->createCommand()->select('firstname,lastname,email,language,blacklisted')->where('participant_id = :pid')->from('{{participants}}')->bindParam(":pid", $participant, PDO::PARAM_INT); $participantdata = Yii::app()->db->createCommand()->select('firstname,lastname,email,language,blacklisted')->where('participant_id = :pid')->from('{{participants}}')->bindParam(":pid", $sParticipantUID, PDO::PARAM_INT);
$tobeinserted = $participantdata->queryRow(); $tobeinserted = $participantdata->queryRow();
if (Yii::app()->getConfig('blockaddingtosurveys')=='Y' && $tobeinserted=='Y') if (Yii::app()->getConfig('blockaddingtosurveys')=='Y' && $tobeinserted=='Y')
@ -1034,10 +1035,14 @@ class Participant extends LSActiveRecord
} }
/* Search for matching participant name/email in the survey token table */ /* Search for matching participant name/email in the survey token table */
$query = Yii::app()->db->createCommand()->select('*')->from('{{tokens_' . $surveyid . '}}') $sQuery = Yii::app()->db->createCommand()->select('*')->from('{{tokens_' . $surveyid . '}}')
->where('firstname = :firstname AND lastname = :lastname AND email = :email') ->where('firstname = :firstname AND lastname = :lastname AND email = :email AND participant_id = :participant_id')
->bindParam(":firstname", $tobeinserted['firstname'], PDO::PARAM_STR)->bindParam(":lastname", $tobeinserted['lastname'], PDO::PARAM_STR)->bindParam(":email", $tobeinserted['email'], PDO::PARAM_STR)->queryAll(); ->bindParam(":firstname", $tobeinserted['firstname'], PDO::PARAM_STR)
if (count($query) > 0) ->bindParam(":lastname", $tobeinserted['lastname'], PDO::PARAM_STR)
->bindParam(":email", $tobeinserted['email'], PDO::PARAM_STR)
->bindParam(":participant_id", $sParticipantUID, PDO::PARAM_STR)
->queryAll();
if (count($sQuery) > 0)
{ {
//Participant already exists in token table - don't copy //Participant already exists in token table - don't copy
$duplicate++; $duplicate++;
@ -1049,7 +1054,7 @@ class Participant extends LSActiveRecord
$numberofattributes = count($attributesadded); $numberofattributes = count($attributesadded);
for ($a = 0; $a < $numberofattributes; $a++) for ($a = 0; $a < $numberofattributes; $a++)
{ {
Participant::model()->updateTokenAttributeValue($surveyid, $participant,$attributesadded[$a],$attributeidadded[$a]); Participant::model()->updateTokenAttributeValue($surveyid, $sParticipantUID,$attributesadded[$a],$attributeidadded[$a]);
} }
} }
//If there are automapped attributes, add those values to the token entry for this participant //If there are automapped attributes, add those values to the token entry for this participant
@ -1058,7 +1063,7 @@ class Participant extends LSActiveRecord
foreach ($mapped as $key => $value) foreach ($mapped as $key => $value)
{ {
if ($key[10] == 'c') { //We know it's automapped because the 11th letter is 'c' if ($key[10] == 'c') { //We know it's automapped because the 11th letter is 'c'
Participant::model()->updateTokenAttributeValue($surveyid, $participant, $value, $key); Participant::model()->updateTokenAttributeValue($surveyid, $sParticipantUID, $value, $key);
} }
} }
} }
@ -1070,7 +1075,7 @@ class Participant extends LSActiveRecord
foreach ($mapped as $key => $value) foreach ($mapped as $key => $value)
{ {
if ($key[10] != 'c' && $key[9]=='_') { //It's not an auto field because it's 11th character isn't 'c' if ($key[10] != 'c' && $key[9]=='_') { //It's not an auto field because it's 11th character isn't 'c'
Participant::model()->updateTokenAttributeValue($surveyid, $participant, $value, $key); Participant::model()->updateTokenAttributeValue($surveyid, $sParticipantUID, $value, $key);
} }
} }
} }
@ -1081,7 +1086,7 @@ class Participant extends LSActiveRecord
foreach($mapped as $key=>$value) foreach($mapped as $key=>$value)
{ {
if((strlen($key) > 8 && $key[10] != 'c' && $key[9] !='_') || strlen($key) < 9) { if((strlen($key) > 8 && $key[10] != 'c' && $key[9] !='_') || strlen($key) < 9) {
Participant::model()->updateTokenAttributeValue($surveyid, $participant, $value, $key); Participant::model()->updateTokenAttributeValue($surveyid, $sParticipantUID, $value, $key);
} }
} }
} }
@ -1090,7 +1095,7 @@ class Participant extends LSActiveRecord
else else
{ {
//Create a new token entry for this participant //Create a new token entry for this participant
$writearray = array('participant_id' => $participant, $writearray = array('participant_id' => $sParticipantUID,
'firstname' => $tobeinserted['firstname'], 'firstname' => $tobeinserted['firstname'],
'lastname' => $tobeinserted['lastname'], 'lastname' => $tobeinserted['lastname'],
'email' => $tobeinserted['email'], 'email' => $tobeinserted['email'],
@ -1105,7 +1110,7 @@ class Participant extends LSActiveRecord
//Create a survey link for the new token entry //Create a survey link for the new token entry
$data = array( $data = array(
'participant_id' => $participant, 'participant_id' => $sParticipantUID,
'token_id' => $insertedtokenid, 'token_id' => $insertedtokenid,
'survey_id' => $surveyid, 'survey_id' => $surveyid,
'date_created' => date('Y-m-d H:i:s', $time)); 'date_created' => date('Y-m-d H:i:s', $time));
@ -1117,7 +1122,7 @@ class Participant extends LSActiveRecord
$numberofattributes = count($attributesadded); $numberofattributes = count($attributesadded);
for ($a = 0; $a < $numberofattributes; $a++) for ($a = 0; $a < $numberofattributes; $a++)
{ {
Participant::model()->updateTokenAttributeValue($surveyid, $participant,$attributesadded[$a],$attributeidadded[$a]); Participant::model()->updateTokenAttributeValue($surveyid, $sParticipantUID,$attributesadded[$a],$attributeidadded[$a]);
} }
} }
//If there are any automatically mapped attributes, add those values to the token entry for this participant //If there are any automatically mapped attributes, add those values to the token entry for this participant
@ -1125,7 +1130,7 @@ class Participant extends LSActiveRecord
{ {
foreach ($mapped as $key => $value) foreach ($mapped as $key => $value)
{ {
Participant::model()->updateTokenAttributeValue($surveyid, $participant, $value, $key); Participant::model()->updateTokenAttributeValue($surveyid, $sParticipantUID, $value, $key);
} }
} }
$sucessfull++; $sucessfull++;
@ -1377,7 +1382,7 @@ class Participant extends LSActiveRecord
} }
Yii::app()->db Yii::app()->db
->createCommand() ->createCommand()
->update('{{surveys}}', array("attributedescriptions" => serialize($aAttributes)), 'sid = '.$surveyid); ->update('{{surveys}}', array("attributedescriptions" => json_encode($aAttributes)), 'sid = '.$surveyid);
} }
if (!empty($aMapped)) if (!empty($aMapped))
{ {
@ -1388,7 +1393,7 @@ class Participant extends LSActiveRecord
} }
Yii::app()->db Yii::app()->db
->createCommand() ->createCommand()
->update('{{surveys}}', array("attributedescriptions" => serialize($aAttributes)), 'sid = '.$surveyid); ->update('{{surveys}}', array("attributedescriptions" => json_encode($aAttributes)), 'sid = '.$surveyid);
} }
} }
$returndata = array('success' => $sucessfull, 'duplicate' => $duplicate, 'overwriteauto'=>$overwriteauto, 'overwriteman'=>$overwriteman); $returndata = array('success' => $sucessfull, 'duplicate' => $duplicate, 'overwriteauto'=>$overwriteauto, 'overwriteman'=>$overwriteman);

View file

@ -78,9 +78,9 @@ class ParticipantAttributeName extends LSActiveRecord
*/ */
public function rules() public function rules()
{ {
// NOTE: you should only define rules for those attributes that // NOTE: you should only define rules for those attributes that will receive user inputs.
// will receive user inputs.
return array( return array(
array('defaultname','filter','filter' => 'strip_tags'),
array('attribute_type, visible', 'required'), array('attribute_type, visible', 'required'),
array('attribute_type', 'length', 'max'=>4), array('attribute_type', 'length', 'max'=>4),
array('visible', 'length', 'max'=>5), array('visible', 'length', 'max'=>5),
@ -339,21 +339,23 @@ class ParticipantAttributeName extends LSActiveRecord
*/ */
function storeAttribute($data) function storeAttribute($data)
{ {
$insertnames = array('attribute_type' => $data['attribute_type'],
'defaultname'=> $data['defaultname'],
'visible' => $data['visible']);
// Do not allow more than 60 attributes because queries will break because of too many joins // Do not allow more than 60 attributes because queries will break because of too many joins
if (ParticipantAttributeName::model()->count()>59) if (ParticipantAttributeName::model()->count()>59)
{ {
return false; return false;
}; };
Yii::app()->db->createCommand()->insert('{{participant_attribute_names}}',$insertnames); $oParticipantAttributeName=new ParticipantAttributeName;
$attribute_id = getLastInsertID($this->tableName()); $oParticipantAttributeName->attribute_type=$data['attribute_type'];
$insertnameslang = array('attribute_id' => intval($attribute_id), $oParticipantAttributeName->defaultname=$data['defaultname'];
'attribute_name'=> $data['attribute_name'], $oParticipantAttributeName->visible=$data['visible'];
'lang' => Yii::app()->session['adminlang']); $oParticipantAttributeName->save();
Yii::app()->db->createCommand()->insert('{{participant_attribute_names_lang}}',$insertnameslang); $iAttributeID = $oParticipantAttributeName->attribute_id;
return $attribute_id; $oParticipantAttributeNameLang=new ParticipantAttributeNameLang;
$oParticipantAttributeNameLang->attribute_id= intval($iAttributeID);
$oParticipantAttributeNameLang->attribute_name= $data['attribute_name'];
$oParticipantAttributeNameLang->lang= Yii::app()->session['adminlang'];
$oParticipantAttributeNameLang->save();
return $iAttributeID;
} }
function editParticipantAttributeValue($data) function editParticipantAttributeValue($data)
@ -430,16 +432,18 @@ class ParticipantAttributeName extends LSActiveRecord
} }
if (!empty($insertnames)) if (!empty($insertnames))
{ {
self::model()->updateAll($insertnames, 'attribute_id = :id', array(':id' => $data['attribute_id'])); $oParticipantAttributeName=ParticipantAttributeName::model()->findByPk($data['attribute_id']);
foreach ($insertnames as $sFieldname=>$sValue)
{
$oParticipantAttributeName->$sFieldname=$sValue;
}
$oParticipantAttributeName->save();
} }
if (!empty($data['attribute_name'])) if (!empty($data['attribute_name']))
{ {
Yii::app()->db->createCommand() $oParticipantAttributeNameLang=ParticipantAttributeNameLang::model()->findByPk(array('attribute_id'=>$data['attribute_id'],'lang'=>Yii::app()->session['adminlang']));
->update('{{participant_attribute_names_lang}}', array('attribute_name' => $data['attribute_name']), $oParticipantAttributeNameLang->attribute_name=$data['attribute_name'];
'attribute_id = :attribute_id AND lang=:lang', array( $oParticipantAttributeNameLang->save();
':lang' => Yii::app()->session['adminlang'],
':attribute_id' => $data['attribute_id'],
));
} }
} }
@ -448,19 +452,18 @@ class ParticipantAttributeName extends LSActiveRecord
$query = Yii::app()->db->createCommand()->from('{{participant_attribute_names_lang}}')->where('attribute_id = :attribute_id AND lang = :lang')->select('*')->bindParam(":attribute_id", $data['attribute_id'], PDO::PARAM_INT)->bindParam(":lang", $data['lang'], PDO::PARAM_STR)->queryAll(); $query = Yii::app()->db->createCommand()->from('{{participant_attribute_names_lang}}')->where('attribute_id = :attribute_id AND lang = :lang')->select('*')->bindParam(":attribute_id", $data['attribute_id'], PDO::PARAM_INT)->bindParam(":lang", $data['lang'], PDO::PARAM_STR)->queryAll();
if (count($query) == 0) if (count($query) == 0)
{ {
// A record does not exist, insert one. // A record does not exist, insert one.
$record = array('attribute_id'=>$data['attribute_id'],'attribute_name'=>$data['attribute_name'],'lang'=>$data['lang']); $oParticipantAttributeNameLang=new ParticipantAttributeNameLang;
$query = Yii::app()->db->createCommand()->insert('{{participant_attribute_names_lang}}', $data); $oParticipantAttributeNameLang->attribute_id=$data['attribute_id'];
$oParticipantAttributeNameLang->attribute_name=$data['attribute_name'];
$oParticipantAttributeNameLang->lang=$data['lang'];
$oParticipantAttributeNameLang->save();
} }
else else
{ {
// A record does exist, update it. $oParticipantAttributeNameLang=ParticipantAttributeNameLang::model()->findByPk(array('attribute_id'=>$data['attribute_id'],'lang'=>$data['lang']));
$query = Yii::app()->db->createCommand() $oParticipantAttributeNameLang->attribute_name=$data['attribute_name'];
->update('{{participant_attribute_names_lang}}', array('attribute_name' => $data['attribute_name']), $oParticipantAttributeNameLang->save();
'attribute_id = :attribute_id AND lang= :lang', array(
':attribute_id' => $data['attribute_id'],
':lang' => $data['lang'],
));
} }
} }
@ -473,17 +476,20 @@ class ParticipantAttributeName extends LSActiveRecord
function storeAttributeCSV($data) function storeAttributeCSV($data)
{ {
$insertnames = array('attribute_type' => $data['attribute_type'], $oParticipantAttributeName=new ParticipantAttributeName;
'defaultname' => $data['defaultname'], $oParticipantAttributeName->attribute_type=$data['attribute_type'];
'visible' => $data['visible']); $oParticipantAttributeName->defaultname=$data['defaultname'];
Yii::app()->db->createCommand()->insert('{{participant_attribute_names}}', $insertnames); $oParticipantAttributeName->visible=$data['visible'];
$oParticipantAttributeName->save();
$iAttributeID = $oParticipantAttributeName->attribute_id;
$insertid = getLastInsertID($this->tableName()); $oParticipantAttributeNameLang=new ParticipantAttributeNameLang;
$insertnameslang = array('attribute_id' => $insertid, $oParticipantAttributeNameLang->attribute_id=$iAttributeID;
'attribute_name'=>$data['defaultname'], $oParticipantAttributeNameLang->attribute_name=$data['defaultname'];
'lang' => Yii::app()->session['adminlang']); $oParticipantAttributeNameLang->lang=Yii::app()->session['adminlang'];
Yii::app()->db->createCommand()->insert('{{participant_attribute_names_lang}}', $insertnameslang); $oParticipantAttributeNameLang->save();
return $insertid;
return $iAttributeID;
} }
//updates the attribute values in participant_attribute_values //updates the attribute values in participant_attribute_values

View file

@ -59,11 +59,11 @@ class ParticipantAttributeNameLang extends LSActiveRecord
*/ */
public function rules() public function rules()
{ {
// NOTE: you should only define rules for those attributes that // NOTE: you should only define rules for those attributes that will receive user inputs.
// will receive user inputs.
return array( return array(
// The following rule is used by search(). array('attribute_name','filter','filter' => 'strip_tags'),
// Please remove those attributes that should not be searched. // The following rule is used by search().
// Please remove those attributes that should not be searched.
array('attribute_id, attribute_name, lang', 'safe', 'on'=>'search'), array('attribute_id, attribute_name, lang', 'safe', 'on'=>'search'),
); );
} }

View file

@ -58,22 +58,112 @@ class Permission extends LSActiveRecord
*/ */
public static function getSurveyBasePermissions() public static function getSurveyBasePermissions()
{ {
$clang = Yii::app()->lang; $defaults = array(
$aPermissions=array( 'create' => true,
'assessments'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Assessments"),'description'=>$clang->gT("Permission to create/view/update/delete assessments rules for a survey"),'img'=>'assessments'), 'read' => true,
'quotas'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Quotas"),'description'=>$clang->gT("Permission to create/view/update/delete quota rules for a survey"),'img'=>'quota'), 'update' => true,
'responses'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Responses"),'description'=>$clang->gT("Permission to create(data entry)/view/update/delete/import/export responses"),'img'=>'browse'), 'delete' => true,
'statistics'=>array('create'=>false,'read'=>true,'update'=>false,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Statistics"),'description'=>$clang->gT("Permission to view statistics"),'img'=>'statistics'), 'import' => true,
'survey'=>array('create'=>false,'read'=>true,'update'=>false,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey deletion"),'description'=>$clang->gT("Permission to delete a survey"),'img'=>'delete'), 'export' => true
'surveyactivation'=>array('create'=>false,'read'=>false,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey activation"),'description'=>$clang->gT("Permission to activate/deactivate a survey"),'img'=>'activate_deactivate'),
'surveycontent'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Survey content"),'description'=>$clang->gT("Permission to create/view/update/delete/import/export the questions, groups, answers & conditions of a survey"),'img'=>'add'),
'surveylocale'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey locale settings"),'description'=>$clang->gT("Permission to view/update the survey locale settings"),'img'=>'edit'),
'surveysecurity'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey security"),'description'=>$clang->gT("Permission to modify survey security settings"),'img'=>'survey_security'),
'surveysettings'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Survey settings"),'description'=>$clang->gT("Permission to view/update the survey settings including token table creation"),'img'=>'survey_settings'),
'tokens'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Tokens"),'description'=>$clang->gT("Permission to create/update/delete/import/export token entries"),'img'=>'tokens'),
'translations'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Quick translation"),'description'=>$clang->gT("Permission to view & update the translations using the quick-translation feature"),'img'=>'translate')
); );
uasort($aPermissions,"comparePermission"); $aPermissions = array(
'assessments' => array(
'import' => false,
'export' => false,
'title' => gT("Assessments"),
'description' => gT("Permission to create/view/update/delete assessments rules for a survey"),
'img' => 'assessments'
),
'quotas' => array(
'import' => false,
'export' => false,
'title' => gT("Quotas"),
'description' => gT("Permission to create/view/update/delete quota rules for a survey"),
'img' => 'quota'
),
'responses' => array(
'title' => gT("Responses"),
'description' => gT("Permission to create(data entry)/view/update/delete/import/export responses"),
'img' => 'browse'
),
'statistics' => array(
'create' => false,
'update' => false,
'delete' => false,
'import' => false,
'export' => false,
'title' => gT("Statistics"),
'description' => gT("Permission to view statistics"),
'img' => 'statistics'
),
'survey' => array(
'create' => false,
'update' => false,
'import' => false,
'export' => false,
'title' => gT("Survey deletion"),
'description' => gT("Permission to delete a survey"),
'img' => 'delete'
),
'surveyactivation' => array(
'create' => false,
'read' => false,
'delete' => false,
'import' => false,
'export' => false,
'title' => gT("Survey activation"),
'description' => gT("Permission to activate/deactivate a survey"),
'img' => 'activate_deactivate'
),
'surveycontent' => array(
'title' => gT("Survey content"),
'description' => gT("Permission to create/view/update/delete/import/export the questions, groups, answers & conditions of a survey"),
'img' => 'add'
),
'surveylocale' => array(
'create' => false,
'delete' => false,
'import' => false,
'export' => false,
'title' => gT("Survey text elements"),
'description' => gT("Permission to view/update the survey text elements : survey title, survey description, welcome and end message …"),
'img'=>'edit'
),
'surveysecurity' => array(
'import' => false,
'export' => false,
'title' => gT("Survey security"),
'description' => gT("Permission to modify survey security settings"),
'img' => 'survey_security'
),
'surveysettings' => array(
'create' => false,
'delete' => false,
'import' => false,
'export' => false,
'title' => gT("Survey settings"),
'description' => gT("Permission to view/update the survey settings including token table creation"),
'img' => 'survey_settings'
),
'tokens' => array(
'title' => gT("Tokens"),'description'=>gT("Permission to create/update/delete/import/export token entries"),
'img' => 'tokens'
),
'translations' => array(
'create' => false,
'delete' => false,
'import' => false,
'export' => false,
'title' => gT("Quick translation"),
'description' => gT("Permission to view & update the translations using the quick-translation feature"),
'img' => 'translate'
)
);
uasort($aPermissions, array(__CLASS__,"comparePermissionTitle"));
foreach ($aPermissions as &$permission)
{
$permission = array_merge($defaults, $permission);
}
return $aPermissions; return $aPermissions;
} }
@ -87,18 +177,76 @@ class Permission extends LSActiveRecord
*/ */
public static function getGlobalBasePermissions() public static function getGlobalBasePermissions()
{ {
$clang = Yii::app()->lang; $defaults = array(
$aPermissions=array( 'create' => true,
'surveys'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>true,'title'=>$clang->gT("Surveys"),'description'=>$clang->gT("Permission to create surveys (for which all permissions are automatically given) and view, update and delete surveys from other users"),'img'=>'survey'), 'read' => true,
'users'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("Users"),'description'=>$clang->gT("Permission to create, view, update and delete users"),'img'=>'security'), 'update' => true,
'usergroups'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>false,'title'=>$clang->gT("User groups"),'description'=>$clang->gT("Permission to create, view, update and delete user groups"),'img'=>'usergroup'), 'delete' => true,
'templates'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Templates"),'description'=>$clang->gT("Permission to create, view, update, delete, export and import templates"),'img'=>'templates'), 'import' => true,
'labelsets'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>true,'export'=>true,'title'=>$clang->gT("Label sets"),'description'=>$clang->gT("Permission to create, view, update, delete, export and import label sets/labels"),'img'=>'labels'), 'export' => true
'settings'=>array('create'=>false,'read'=>true,'update'=>true,'delete'=>false,'import'=>true,'export'=>false,'title'=>$clang->gT("Settings & Plugins"),'description'=>$clang->gT("Permission to view and update global settings & plugins and to delete and import plugins"),'img'=>'global'),
'participantpanel'=>array('create'=>true,'read'=>true,'update'=>true,'delete'=>true,'import'=>false,'export'=>true,'title'=>$clang->gT("Participant panel"),'description'=>$clang->gT("Permission to create your own participants in the central participants database (for which all permissions are automatically given) and view, update and delete participants from other users"),'img'=>'cpdb'),
); );
uasort($aPermissions,"comparePermission"); $aPermissions=array(
$aPermissions=array('superadmin'=>array('create'=>false,'read'=>true,'update'=>false,'delete'=>false,'import'=>false,'export'=>false,'title'=>$clang->gT("Superadministrator"),'description'=>$clang->gT("Unlimited administration permissions"),'img'=>'superadmin'))+$aPermissions; 'surveys' => array(
'import' => false,
'title' => gT("Surveys"),
'description' => gT("Permission to create surveys (for which all permissions are automatically given) and view, update and delete surveys from other users"),
'img'=>'survey'
),
'users' => array(
'import' => false,
'export' => false,
'title' => gT("Users"),
'description' => gT("Permission to create, view, update and delete users"),
'img' => 'security'
),
'usergroups' => array(
'import' => false,
'export' => false,
'title' => gT("User groups"),
'description' => gT("Permission to create, view, update and delete user groups"),
'img' => 'usergroup'
),
'templates' => array(
'title'=> gT("Templates"),
'description' => gT("Permission to create, view, update, delete, export and import templates"),
'img' => 'templates'
),
'labelsets' => array(
'title' => gT("Label sets"),
'description' => gT("Permission to create, view, update, delete, export and import label sets/labels"),
'img' => 'labels'
),
'settings' => array(
'create' => false,
'delete' => false,
'export' => false,
'title' => gT("Settings & Plugins"),
'description' => gT("Permission to view and update global settings & plugins and to delete and import plugins"),
'img' => 'global'
),
'participantpanel' => array(
'import' => false,
'title' => gT("Participant panel"),
'description' => gT("Permission to create your own participants in the central participants database (for which all permissions are automatically given) and view, update and delete participants from other users"),
'img' => 'cpdb'
),
);
uasort($aPermissions, array(__CLASS__,"comparePermissionTitle"));
$aPermissions['superadmin'] = array(
'create' => false,
'update' => false,
'delete' => false,
'import' => false,
'export' => false,
'title' => gT("Superadministrator"),
'description' => gT("Unlimited administration permissions"),
'img' => 'superadmin'
);
foreach ($aPermissions as &$permission)
{
$permission = array_merge($defaults, $permission);
}
return $aPermissions; return $aPermissions;
} }
@ -259,18 +407,6 @@ class Permission extends LSActiveRecord
$this->setPermissions($iUserID, $iSurveyID, 'survey', $aPermissionsToSet); $this->setPermissions($iUserID, $iSurveyID, 'survey', $aPermissionsToSet);
} }
function deleteSomeRecords($condition)
{
$criteria = new CDbCriteria;
foreach ($condition as $item => $value)
{
$criteria->addCondition($item."='".$value."'");
}
$this->deleteAll($criteria);
}
function insertRecords($data) function insertRecords($data)
{ {
foreach ($item as $data) foreach ($item as $data)
@ -330,19 +466,9 @@ class Permission extends LSActiveRecord
if (!in_array($sCRUD,array('create','read','update','delete','import','export'))) return false; if (!in_array($sCRUD,array('create','read','update','delete','import','export'))) return false;
$sCRUD=$sCRUD.'_p'; $sCRUD=$sCRUD.'_p';
if (is_null($iUserID)) $iUserID=self::getUserId($iUserID);
{ if(!$iUserID)
if (!Yii::app()->user->getIsGuest()) $iUserID = Yii::app()->session['loginID']; return false;
else return false;
}
if ($iEntityID>0 && $sEntityName=='survey')
{
$aSurveyInfo=getSurveyInfo($iEntityID);// OR find but then don't use $static
if (!$aSurveyInfo) return false;
// If you own a survey you have access to the whole survey
if ($iUserID==$aSurveyInfo['owner_id']) return true;
}
// Check if superadmin and cache it // Check if superadmin and cache it
if (!isset($aPermissionCache[0]['global'][$iUserID]['superadmin']['read_p'])) if (!isset($aPermissionCache[0]['global'][$iUserID]['superadmin']['read_p']))
@ -399,9 +525,22 @@ class Permission extends LSActiveRecord
* @param $iUserID integer User ID - if not given the one of the current user is used * @param $iUserID integer User ID - if not given the one of the current user is used
* @return bool True if user has the permission * @return bool True if user has the permission
*/ */
function hasSurveyPermission($iSurveyID, $sPermission, $sCRUD, $iUserID=null) function hasSurveyPermission($iSurveyID,$sPermission, $sCRUD, $iUserID=null)
{ {
return $this->hasPermission($iSurveyID, 'survey', $sPermission, $sCRUD, $iUserID); $oSurvey=Survey::Model()->findByPk($iSurveyID);
if (!$oSurvey)
return false;
$iUserID=self::getUserId($iUserID);
if(!$iUserID)
return false;
// If you own a survey you have access to the whole survey
if ($iUserID==$oSurvey->owner_id)
return true;
// Get global correspondance for surveys rigth
$sGlobalCRUD=($sCRUD=='create' || ($sCRUD=='delete' && $sPermission!='survey') ) ? 'update' : $sCRUD;
return $this->hasGlobalPermission('surveys', $sGlobalCRUD, $iUserID) || $this->hasPermission($iSurveyID, 'survey', $sPermission, $sCRUD, $iUserID);
} }
/** /**
@ -416,5 +555,27 @@ class Permission extends LSActiveRecord
return $this->hasPermission(0, 'template', $sTemplateName, $sCRUD, $iUserID); return $this->hasPermission(0, 'template', $sTemplateName, $sCRUD, $iUserID);
} }
/**
/* function used to order Permission by language string
/* @param aApermission array The first permission information
/* @param aBpermission array The second permission information
/* @return bool
*/
private static function comparePermissionTitle($aApermission,$aBpermission)
{
return strcmp($aApermission['title'], $aBpermission['title']);
}
/**
/* get the default/fixed $iUserID
/* @param iUserID optionnal user id
/* @return integer user id
*/
private static function getUserId($iUserID=null)
{
if (is_null($iUserID) && !Yii::app()->user->getIsGuest())
$iUserID = Yii::app()->session['loginID'];
return $iUserID;
}
} }

View file

@ -147,7 +147,7 @@
*/ */
public static function updateSortOrder($gid, $surveyid) public static function updateSortOrder($gid, $surveyid)
{ {
$questions = self::model()->findAllByAttributes(array('gid' => $gid, 'sid' => $surveyid, 'language' => Survey::model()->findByPk($surveyid)->language)); $questions = self::model()->findAllByAttributes(array('gid' => $gid, 'sid' => $surveyid, 'language' => Survey::model()->findByPk($surveyid)->language), array('order'=>'question_order') );
$p = 0; $p = 0;
foreach ($questions as $question) foreach ($questions as $question)
{ {
@ -168,7 +168,7 @@
function updateQuestionOrder($gid,$language,$position=0) function updateQuestionOrder($gid,$language,$position=0)
{ {
$data=Yii::app()->db->createCommand()->select('qid') $data=Yii::app()->db->createCommand()->select('qid')
->where(array('and','gid=:gid','language=:language')) ->where(array('and','gid=:gid','language=:language', 'parent_qid=0'))
->order('question_order, title ASC') ->order('question_order, title ASC')
->from('{{questions}}') ->from('{{questions}}')
->bindParam(':gid', $gid, PDO::PARAM_INT) ->bindParam(':gid', $gid, PDO::PARAM_INT)
@ -590,7 +590,7 @@
'description' => gT("Yes/No"), 'description' => gT("Yes/No"),
'group' => gT("Mask questions"), 'group' => gT("Mask questions"),
'subquestions' => 0, 'subquestions' => 0,
'hasdefaultvalues' => 0, 'hasdefaultvalues' => 1,
'assessable' => 0, 'assessable' => 0,
'answerscales' => 0), 'answerscales' => 0),
"!" => array( "!" => array(

View file

@ -101,6 +101,8 @@ class QuestionAttribute extends LSActiveRecord
{ {
$iQuestionID=(int)$iQuestionID; $iQuestionID=(int)$iQuestionID;
static $aQuestionAttributesStatic=array();// TODO : replace by Yii::app()->cache static $aQuestionAttributesStatic=array();// TODO : replace by Yii::app()->cache
// Limit the size of the attribute cache due to memory usage
$aQuestionAttributesStatic=array_splice($aQuestionAttributesStatic,-1000,null,true);
if(isset($aQuestionAttributesStatic[$iQuestionID])) if(isset($aQuestionAttributesStatic[$iQuestionID]))
{ {
return $aQuestionAttributesStatic[$iQuestionID]; return $aQuestionAttributesStatic[$iQuestionID];

View file

@ -35,7 +35,7 @@
{ {
$field = "{$question->sid}X{$question->gid}X{$question->qid}"; $field = "{$question->sid}X{$question->gid}X{$question->qid}";
$data = json_decode($this->getAttribute($field), true); $data = json_decode(stripslashes($this->getAttribute($field)), true);
if (is_array($data)) if (is_array($data))
{ {
$files = array_merge($files, $data); $files = array_merge($files, $data);

View file

@ -52,9 +52,9 @@ class Session extends CActiveRecord
public function afterFind() public function afterFind()
{ {
// MSSQL delivers hex data
$sDatabasetype = Yii::app()->db->getDriverName(); $sDatabasetype = Yii::app()->db->getDriverName();
if($sDatabasetype=='sqlsrv' || $sDatabasetype=='mssql' || $sDatabasetype=='dblib') // MSSQL delivers hex data (except for dblib driver)
if($sDatabasetype=='sqlsrv' || $sDatabasetype=='mssql')
{ {
$this->data=$this->hexToStr($this->data); $this->data=$this->hexToStr($this->data);
} }

View file

@ -210,7 +210,7 @@ class Survey extends LSActiveRecord
/** /**
* permission scope for this model * permission scope for this model
* * Actually only test if user have minimal access to survey (read)
* @access public * @access public
* @param int $loginID * @param int $loginID
* @return CActiveRecord * @return CActiveRecord
@ -218,6 +218,8 @@ class Survey extends LSActiveRecord
public function permission($loginID) public function permission($loginID)
{ {
$loginID = (int) $loginID; $loginID = (int) $loginID;
if(Permission::model()->hasGlobalPermission('surveys','read'))// Test global before adding criteria
return $this;
$criteria = $this->getDBCriteria(); $criteria = $this->getDBCriteria();
$criteria->mergeWith(array( $criteria->mergeWith(array(
'condition' => 'sid IN (SELECT entity_id FROM {{permissions}} WHERE entity = :entity AND uid = :uid AND permission = :permission AND read_p = 1) 'condition' => 'sid IN (SELECT entity_id FROM {{permissions}} WHERE entity = :entity AND uid = :uid AND permission = :permission AND read_p = 1)
@ -268,7 +270,7 @@ class Survey extends LSActiveRecord
*/ */
public function getTokenAttributes() public function getTokenAttributes()
{ {
$attdescriptiondata = @unserialize($this->attributedescriptions); $attdescriptiondata = decodeTokenAttributes($this->attributedescriptions);
// checked for invalid data // checked for invalid data
if($attdescriptiondata == null) if($attdescriptiondata == null)
{ {
@ -306,8 +308,8 @@ class Survey extends LSActiveRecord
} }
} }
$ls = SurveyLanguageSetting::model()->findByAttributes(array('surveyls_survey_id' => $this->sid, 'surveyls_language' => $this->language)); $ls = SurveyLanguageSetting::model()->findByAttributes(array('surveyls_survey_id' => $this->sid, 'surveyls_language' => $this->language));
self::model()->updateByPk($this->sid, array('attributedescriptions' => serialize($fields))); self::model()->updateByPk($this->sid, array('attributedescriptions' => json_encode($fields)));
$ls->surveyls_attributecaptions = serialize($languagesettings); $ls->surveyls_attributecaptions = json_encode($languagesettings);
$ls->save(); $ls->save();
$attdescriptiondata = $fields; $attdescriptiondata = $fields;
} }
@ -378,7 +380,11 @@ class Survey extends LSActiveRecord
foreach ($aData as $k => $v) foreach ($aData as $k => $v)
$survey->$k = $v; $survey->$k = $v;
$sResult= $survey->save(); $sResult= $survey->save();
if ($sResult==false) return false; if (!$sResult)
{
tracevar($survey->getErrors());
return false;
}
else return $aData['sid']; else return $aData['sid'];
} }

View file

@ -53,7 +53,7 @@
// Check if we have custom attributes. // Check if we have custom attributes.
if ($this->hasAttribute('attribute_1')) if ($this->hasAttribute('attribute_1'))
{ {
foreach (unserialize($this->survey->attributedescriptions) as $key => $info) foreach (decodeTokenAttributes($this->survey->attributedescriptions) as $key => $info)
{ {
$labels[$key] = $info['description']; $labels[$key] = $info['description'];
} }
@ -86,7 +86,7 @@
$this->token = randomChars($length); $this->token = randomChars($length);
$counter = 0; $counter = 0;
while (!$this->validate('token')) while (!$this->validate(array('token')))
{ {
$this->token = randomChars($length); $this->token = randomChars($length);
$counter++; $counter++;
@ -129,7 +129,7 @@
public function rules() public function rules()
{ {
return array( return array(
array('token', 'unique', 'allowEmpty' => true), array('token', 'unique', 'allowEmpty' => true),// 'caseSensitive'=>false only for mySql
array(implode(',', $this->tableSchema->columnNames), 'safe'), array(implode(',', $this->tableSchema->columnNames), 'safe'),
array('remindercount','numerical', 'integerOnly'=>true,'allowEmpty'=>true), array('remindercount','numerical', 'integerOnly'=>true,'allowEmpty'=>true),
array('email','filter','filter'=>'trim'), array('email','filter','filter'=>'trim'),
@ -137,6 +137,7 @@
array('usesleft','numerical', 'integerOnly'=>true,'allowEmpty'=>true), array('usesleft','numerical', 'integerOnly'=>true,'allowEmpty'=>true),
array('mpid','numerical', 'integerOnly'=>true,'allowEmpty'=>true), array('mpid','numerical', 'integerOnly'=>true,'allowEmpty'=>true),
array('blacklisted', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), array('blacklisted', 'in','range'=>array('Y','N'), 'allowEmpty'=>true),
array('emailstatus', 'default', 'value' => 'OK'),
); );
} }
@ -163,7 +164,8 @@
"COUNT(CASE WHEN (token IS NULL OR token='') THEN 1 ELSE NULL END) as invalid", "COUNT(CASE WHEN (token IS NULL OR token='') THEN 1 ELSE NULL END) as invalid",
"COUNT(CASE WHEN (sent!='N' AND sent<>'') THEN 1 ELSE NULL END) as sent", "COUNT(CASE WHEN (sent!='N' AND sent<>'') THEN 1 ELSE NULL END) as sent",
"COUNT(CASE WHEN (emailstatus LIKE 'OptOut%') THEN 1 ELSE NULL END) as optout", "COUNT(CASE WHEN (emailstatus LIKE 'OptOut%') THEN 1 ELSE NULL END) as optout",
"COUNT(CASE WHEN (completed!='N' and completed<>'') THEN 1 ELSE NULL END) as completed" "COUNT(CASE WHEN (completed!='N' and completed<>'' and completed !='Q') THEN 1 ELSE NULL END) as completed",
"COUNT(CASE WHEN (completed='Q') THEN 1 ELSE NULL END) as screenout",
); );
$command = $this->getCommandBuilder()->createFindCommand($this->getTableSchema(),$criteria); $command = $this->getCommandBuilder()->createFindCommand($this->getTableSchema(),$criteria);
return $command->queryRow(); return $command->queryRow();

View file

@ -85,12 +85,14 @@ class TokenDynamic extends LSActiveRecord
public function rules() public function rules()
{ {
return array( return array(
array('remindercount','numerical', 'integerOnly'=>true,'allowEmpty'=>true), array('token', 'unique', 'allowEmpty'=>true),// 'caseSensitive'=>false only for mySql
array('email','filter','filter'=>'trim'), array('remindercount','numerical', 'integerOnly'=>true,'allowEmpty'=>true),
array('email','LSYii_EmailIDNAValidator', 'allowEmpty'=>true, 'allowMultiple'=>true), array('email','filter','filter'=>'trim'),
array('usesleft','numerical', 'integerOnly'=>true,'allowEmpty'=>true), array('email','LSYii_EmailIDNAValidator', 'allowEmpty'=>true, 'allowMultiple'=>true),
array('mpid','numerical', 'integerOnly'=>true,'allowEmpty'=>true), array('usesleft','numerical', 'integerOnly'=>true,'allowEmpty'=>true),
array('blacklisted', 'in','range'=>array('Y','N'), 'allowEmpty'=>true), array('mpid','numerical', 'integerOnly'=>true,'allowEmpty'=>true),
array('blacklisted', 'in','range'=>array('Y','N'), 'allowEmpty'=>true),
array('emailstatus', 'default', 'value' => 'OK'),
// array('validfrom','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true), // array('validfrom','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true),
// array('validuntil','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true), // array('validuntil','date', 'format'=>array('yyyy-MM-dd', 'yyyy-MM-dd HH:mm', 'yyyy-MM-dd HH:mm:ss',), 'allowEmpty'=>true),
// Date rules currently don't work properly with MSSQL, deactivating for now // Date rules currently don't work properly with MSSQL, deactivating for now

View file

@ -664,6 +664,18 @@ NULL~NUMBEROFQUESTIONS/=5
NULL~NUMBEROFQUESTIONS-=6 NULL~NUMBEROFQUESTIONS-=6
NULL~'Tom'='tired' NULL~'Tom'='tired'
NULL~max() NULL~max()
NULL~convert_value( 10, 1, '0,5,10,15,20', '0,5,10,15')
100~convert_value( 10, 1, '0,5,10,15,20', '0,50,100,150,200')
NULL~convert_value( 10, 0, '0,5,10,15,20', '0,50,100,150,200')
100~convert_value( 8, 0, '0,5,10,15,20', '0,50,100,150,200')
100~convert_value( 12, 0, '0,5,10,15,20', '0,50,100,150,200')
0~convert_value( 0, 0, '0,5,10,15,20', '0,50,100,150,200')
0~convert_value( -10000, 0, '0,5,10,15,20', '0,50,100,150,200')
NULL~convert_value( -10000, 1, '0,5,10,15,20', '0,50,100,150,200')
200~convert_value( 20, 0, '0,5,10,15,20', '0,50,100,150,200')
200~convert_value( 20, 1, '0,5,10,15,20', '0,50,100,150,200')
200~convert_value( 30, 0, '0,5,10,15,20', '0,50,100,150,200')
NULL~convert_value( 30, 1, '0,5,10,15,20', '0,50,100,150,200')
EOD; EOD;
$atests = explode("\n",$tests); $atests = explode("\n",$tests);

View file

@ -312,7 +312,7 @@ of these things:
from a designated place, offer equivalent access to copy the above from a designated place, offer equivalent access to copy the above
specified materials from the same place. specified materials from the same place.
e) Verify that the user has already received a copy of these e) verify that the user has already received a copy of these
materials or that you have already sent this user a copy. materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the For an executable, the required form of the "work that uses the

View file

@ -0,0 +1,49 @@
<?php
/**
* PHPMailer SPL autoloader.
* PHP Version 5
* @package PHPMailer
* @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2014 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
* PHPMailer SPL autoloader.
* @param string $classname The name of the class to load
*/
function PHPMailerAutoload($classname)
{
//Can't use __DIR__ as it's only in PHP 5.3+
$filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';
if (is_readable($filename)) {
require $filename;
}
}
if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
//SPL autoloading was introduced in PHP 5.1.2
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
spl_autoload_register('PHPMailerAutoload', true, true);
} else {
spl_autoload_register('PHPMailerAutoload');
}
} else {
/**
* Fall back to traditional autoload for old PHP versions
* @param string $classname The name of the class to load
*/
function __autoload($classname)
{
PHPMailerAutoload($classname);
}
}

View file

@ -0,0 +1,148 @@
![PHPMailer](https://raw.github.com/PHPMailer/PHPMailer/master/examples/images/phpmailer.png)
# PHPMailer - A full-featured email creation and transfer class for PHP
Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer)
[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/badges/quality-score.png?s=3758e21d279becdf847a557a56a3ed16dfec9d5d)](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/)
[![Code Coverage](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/badges/coverage.png?s=3fe6ca5fe8cd2cdf96285756e42932f7ca256962)](https://scrutinizer-ci.com/g/PHPMailer/PHPMailer/)
## Class Features
- Probably the world's most popular code for sending email from PHP!
- Used by many open-source projects: Drupal, SugarCRM, Yii, Joomla! and many more
- Integrated SMTP support - send without a local mail server
- Send emails with multiple TOs, CCs, BCCs and REPLY-TOs
- Multipart/alternative emails for mail clients that do not read HTML email
- Support for UTF-8 content and 8bit, base64, binary, and quoted-printable encodings
- SMTP authentication with LOGIN, PLAIN, NTLM and CRAM-MD5 mechanisms over SSL and TLS transports
- Native language support
- DKIM and S/MIME signing support
- Compatible with PHP 5.0 and later
- Much more!
## Why you might need it
Many PHP developers utilize email in their code. The only PHP function that supports this is the mail() function. However, it does not provide any assistance for making use of popular features such as HTML-based emails and attachments.
Formatting email correctly is surprisingly difficult. There are myriad overlapping RFCs, requiring tight adherence to horribly complicated formatting and encoding rules - the vast majority of code that you'll find online that uses the mail() function directly is just plain wrong!
*Please* don't be tempted to do it yourself - if you don't use PHPMailer, there are many other excellent libraries that you should look at before rolling your own - try SwiftMailer, Zend_Mail, eZcomponents etc.
The PHP mail() function usually sends via a local mail server, typically fronted by a `sendmail` binary on Linux, BSD and OS X platforms, however, Windows usually doesn't include a local mail server; PHPMailer's integrated SMTP implementation allows email sending on Windows platforms without a local mail server.
## License
This software is licenced under the [LGPL 2.1](http://www.gnu.org/licenses/lgpl-2.1.html). Please read LICENSE for information on the
software availability and distribution.
## Installation & loading
PHPMailer is available via [Composer/Packagist](https://packagist.org/packages/phpmailer/phpmailer). Alternatively, just copy the contents of the PHPMailer folder into somewhere that's in your PHP `include_path` setting. If you don't speak git or just want a tarball, click the 'zip' button at the top of the page in GitHub.
PHPMailer provides an SPL-compatible autoloader, and that is the preferred way of loading the library - just `require '/path/to/PHPMailerAutoload.php';` and everything should work. The autoloader does not throw errors if it can't find classes so it prepends itself to the SPL list, allowing your own (or your framework's) autoloader to catch errors. SPL autoloading was introduced in PHP 5.1.0, so if you are using a version older than that you will need to require/include each class manually.
PHPMailer does *not* declare a namespace because namespaces were only introduced in PHP 5.3.
### Minimal installation
While installing the entire package manually or with composer is simple, convenient and reliable, you may want to include only vital files in your project. At the very least you will need [class.phpmailer.php](class.phpmailer.php). If you're using SMTP, you'll need [class.smtp.php](class.smtp.php), and if you're using POP-before SMTP, you'll need [class.pop3.php](class.pop3.php). For all of these, we recommend you use [the autoloader](PHPMailerAutoload.php) too. You can skip the [language](language/) folder if you're not showing errors to users and can make do with English-only errors. You may need the additional classes in the [extras](extras/) folder if you are using those features, including NTLM authentication, advanced HTML-to-text conversion and ics generation.
## A Simple Example
```php
<?php
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp1.example.com;smtp2.example.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'user@example.com'; // SMTP username
$mail->Password = 'secret'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = 'from@example.com';
$mail->FromName = 'Mailer';
$mail->addAddress('joe@example.net', 'Joe User'); // Add a recipient
$mail->addAddress('ellen@example.com'); // Name is optional
$mail->addReplyTo('info@example.com', 'Information');
$mail->addCC('cc@example.com');
$mail->addBCC('bcc@example.com');
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->addAttachment('/var/tmp/file.tar.gz'); // Add attachments
$mail->addAttachment('/tmp/image.jpg', 'new.jpg'); // Optional name
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
```
You'll find plenty more to play with in the [examples](examples/) folder.
That's it. You should now be ready to use PHPMailer!
## Localization
PHPMailer defaults to English, but in the [language](language/) folder you'll find numerous (39 at the time of writing) translations for PHPMailer error messages that you may encounter. Their filenames contain [ISO 639-1](http://en.wikipedia.org/wiki/ISO_639-1) language code for the translations, for example `fr` for French. To specify a language, you need to tell PHPMailer which one to use, like this:
```php
// To load the French version
$mail->setLanguage('fr', '/optional/path/to/language/directory/');
```
We welcome corrections and new languages - if you're looking for corrections to do, run the [phpmailerLangTest.php](test/phpmailerLangTest.php) script in the tests folder and it will show any missing translations.
## Documentation
Generated documentation is [available online](http://phpmailer.github.io/PHPMailer/).
You'll find some basic user-level docs in the [docs](docs/) folder, and you can generate complete API-level documentation using the [generatedocs.sh](docs/generatedocs.sh) shell script in the docs folder, though you'll need to install [PHPDocumentor](http://www.phpdoc.org) first. You may find [the unit tests](test/phpmailerTest.php) a good source of how to do various operations such as encryption.
## Tests
There is a PHPUnit test script in the [test](test/) folder.
Build status: [![Build Status](https://travis-ci.org/PHPMailer/PHPMailer.svg)](https://travis-ci.org/PHPMailer/PHPMailer)
If this isn't passing, is there something you can do to help?
## Contributing
Please submit bug reports, suggestions and pull requests to the [GitHub issue tracker](https://github.com/PHPMailer/PHPMailer/issues).
We're particularly interested in fixing edge-cases, expanding test coverage and updating translations.
With the move to the PHPMailer GitHub organisation, you'll need to update any remote URLs referencing the old GitHub location with a command like this from within your clone:
`git remote set-url upstream https://github.com/PHPMailer/PHPMailer.git`
Please *don't* use the SourceForge or Google Code projects any more.
## Changelog
See [changelog](changelog.md).
## History
- PHPMailer was originally written in 2001 by Brent R. Matzelle as a [SourceForge project](http://sourceforge.net/projects/phpmailer/).
- Marcus Bointon (coolbru on SF) and Andy Prevost (codeworxtech) took over the project in 2004.
- Became an Apache incubator project on Google Code in 2010, managed by Jim Jagielski.
- Marcus created his fork on [GitHub](https://github.com/Synchro/PHPMailer).
- Jim and Marcus decide to join forces and use GitHub as the canonical and official repo for PHPMailer.
- PHPMailer moves to the [PHPMailer organisation](https://github.com/PHPMailer) on GitHub.
### What's changed since moving from SourceForge?
- Official successor to the SourceForge and Google Code projects.
- Test suite.
- Continuous integration with Travis-CI.
- Composer support.
- Public development.
- Additional languages and language strings.
- CRAM-MD5 authentication support.
- Preserves full repo history of authors, commits and branches from the original SourceForge project.

View file

@ -1,151 +0,0 @@
<?php die(); ?>
/******************************************************************* *
The http://phpmailer.codeworxtech.com/ website now carries a few * *
advertisements through the Google Adsense network. Please visit * * the
advertiser sites and help us offset some of our costs. * * Thanks .... *
********************************************************************/
PHPMailer Full Featured Email Transfer Class for PHP
========================================== Version 5.1.0 (11/11/2009)
With the release of this version, we are initiating a new version
numbering system to differentiate from the PHP4 version of PHPMailer.
Most notable in this release is fully object oriented code. We now have
available the PHPDocumentor (phpdocs) documentation. This is separate
from the regular download to keep file sizes down. Please see the
download area of http://phpmailer.codeworxtech.com. We also have created
a new test script (see /test_script) that you can use right out of the
box. Copy the /test_script folder directly to your server (in the same
structure ... with class.phpmailer.php and class.smtp.php in the folder
above it. Then launch the test script with:
http://www.yourdomain.com/phpmailer/test_script/index.php from this one
script, you can test your server settings for mail(), sendmail (or
qmail), and SMTP. This will email you a sample email (using
contents.html for the email body) and two attachments. One of the
attachments is used as an inline image to demonstrate how PHPMailer will
automatically detect if attachments are the same source as inline
graphics and only include one version. Once you click the Submit button,
the results will be displayed including any SMTP debug information and
send status. We will also display a version of the script that you can
cut and paste to include in your projects. Enjoy! Version 2.3 (November
08, 2008) We have removed the /phpdoc from the downloads. All
documentation is now on the http://phpmailer.codeworxtech.com website.
The phpunit.php has been updated to support PHP5. For all other changes
and notes, please see the changelog. Donations are accepted at PayPal
with our id "paypal@worxteam.com". Version 2.2 (July 15 2008) - see the
changelog. Version 2.1 (June 04 2008) With this release, we are
announcing that the development of PHPMailer for PHP5 will be our focus
from this date on. We have implemented all the enhancements and fixes
from the latest release of PHPMailer for PHP4. Far more important,
though, is that this release of PHPMailer (v2.1) is fully tested with
E_STRICT error checking enabled. ** NOTE: WE HAVE A NEW LANGUAGE
VARIABLE FOR DIGITALLY SIGNED S/MIME EMAILS. IF YOU CAN HELP WITH
LANGUAGES OTHER THAN ENGLISH AND SPANISH, IT WOULD BE APPRECIATED. We
have now added S/MIME functionality (ability to digitally sign emails).
BIG THANKS TO "sergiocambra" for posting this patch back in November
2007. The "Signed Emails" functionality adds the Sign method to pass the
private key filename and the password to read it, and then email will be
sent with content-type multipart/signed and with the digital signature
attached. A quick note on E_STRICT: - In about half the test
environments the development version was subjected to, an error was
thrown for the date() functions (used at line 1565 and 1569). This is
NOT a PHPMailer error, it is the result of an incorrectly configured
PHP5 installation. The fix is to modify your 'php.ini' file and include
the date.timezone = America/New York directive, (for your own server
timezone) - If you do get this error, and are unable to access your
php.ini file, there is a workaround. In your PHP script, add
date_default_timezone_set('America/Toronto'); * do NOT try to use $myVar
= date_default_timezone_get(); as a test, it will throw an error. We
have also included more example files to show the use of "sendmail",
"mail()", "smtp", and "gmail". We are also looking for more programmers
to join the volunteer development team. If you have an interest in this,
please let us know. Enjoy! Version 2.1.0beta1 & beta2 please note, this
is BETA software ** DO NOT USE THIS IN PRODUCTION OR LIVE PROJECTS
INTENDED STRICTLY FOR TESTING ** NOTE: As of November 2007, PHPMailer
has a new project team headed by industry veteran Andy Prevost
(codeworxtech). The first release in more than two years will focus on
fixes, adding ease-of-use enhancements, provide basic compatibility with
PHP4 and PHP5 using PHP5 backwards compatibility features. A new release
is planned before year-end 2007 that will provide full compatiblity with
PHP4 and PHP5, as well as more bug fixes. We are looking for project
developers to assist in restoring PHPMailer to its leadership position.
Our goals are to simplify use of PHPMailer, provide good documentation
and examples, and retain backward compatibility to level 1.7.3
standards. If you are interested in helping out, visit
http://sourceforge.net/projects/phpmailer and indicate your interest. **
http://phpmailer.sourceforge.net/ This software is licenced under the
LGPL. Please read LICENSE for information on the software availability
and distribution. Class Features: - Send emails with multiple TOs, CCs,
BCCs and REPLY-TOs - Redundant SMTP servers - Multipart/alternative
emails for mail clients that do not read HTML email - Support for 8bit,
base64, binary, and quoted-printable encoding - Uses the same methods as
the very popular AspEmail active server (COM) component - SMTP
authentication - Native language support - Word wrap, and more! Why you
might need it: Many PHP developers utilize email in their code. The only
PHP function that supports this is the mail() function. However, it does
not expose any of the popular features that many email clients use
nowadays like HTML-based emails and attachments. There are two
proprietary development tools out there that have all the functionality
built into easy to use classes: AspEmail(tm) and AspMail. Both of these
programs are COM components only available on Windows. They are also a
little pricey for smaller projects. Since I do Linux development I<EFBFBD>ve
missed these tools for my PHP coding. So I built a version myself that
implements the same methods (object calls) that the Windows-based
components do. It is open source and the LGPL license allows you to
place the class in your proprietary PHP projects. Installation: Copy
class.phpmailer.php into your php.ini include_path. If you are using the
SMTP mailer then place class.smtp.php in your path as well. In the
language directory you will find several files like
phpmailer.lang-en.php. If you look right before the .php extension that
there are two letters. These represent the language type of the
translation file. For instance "en" is the English file and "br" is the
Portuguese file. Chose the file that best fits with your language and
place it in the PHP include path. If your language is English then you
have nothing more to do. If it is a different language then you must
point PHPMailer to the correct translation. To do this, call the
PHPMailer SetLanguage method like so: // To load the Portuguese version
$mail->SetLanguage("br", "/optional/path/to/language/directory/");
That's it. You should now be ready to use PHPMailer! A Simple Example:
<?php
require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP(); // set mailer to use SMTP
$mail->Host = "smtp1.example.com;smtp2.example.com"; // specify main and backup server
$mail->SMTPAuth = true; // turn on SMTP authentication
$mail->Username = "jswan"; // SMTP username
$mail->Password = "secret"; // SMTP password
$mail->From = "from@example.com";
$mail->FromName = "Mailer";
$mail->AddAddress("josh@example.net", "Josh Adams");
$mail->AddAddress("ellen@example.com"); // name is optional
$mail->AddReplyTo("info@example.com", "Information");
$mail->WordWrap = 50; // set word wrap to 50 characters
$mail->AddAttachment("/var/tmp/file.tar.gz"); // add attachments
$mail->AddAttachment("/tmp/image.jpg", "new.jpg"); // optional name
$mail->IsHTML(true); // set email format to HTML
$mail->Subject = "Here is the subject";
$mail->Body = "This is the HTML message body <b>in bold!</b>";
$mail->AltBody = "This is the body in plain text for non-HTML mail clients";
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
exit;
}
echo "Message has been sent";
?>
CHANGELOG See ChangeLog.txt Download:
http://sourceforge.net/project/showfiles.php?group_id=26031 Andy Prevost

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,9 @@
<?php <?php
/** /**
* PHPMailer language file: refer to English translation for definitive list * PHPMailer language file: refer to English translation for definitive list
* Arabic Version, UTF-8 * Arabic Version, UTF-8
* by : bahjat al mostafa <bahjat983@hotmail.com> * by : bahjat al mostafa <bahjat983@hotmail.com>
*/ */
$PHPMAILER_LANG['authenticate'] = 'SMTP Error: لم نستطع تأكيد الهوية.'; $PHPMAILER_LANG['authenticate'] = 'SMTP Error: لم نستطع تأكيد الهوية.';
$PHPMAILER_LANG['connect_host'] = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.'; $PHPMAILER_LANG['connect_host'] = 'SMTP Error: لم نستطع الاتصال بمخدم SMTP.';
@ -15,7 +15,7 @@ $PHPMAILER_LANG['file_access'] = 'لم نستطع الوصول للمل
$PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع فتح الملف: '; $PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع فتح الملف: ';
$PHPMAILER_LANG['from_failed'] = 'البريد التالي لم نستطع ارسال البريد له : '; $PHPMAILER_LANG['from_failed'] = 'البريد التالي لم نستطع ارسال البريد له : ';
$PHPMAILER_LANG['instantiate'] = 'لم نستطع توفير خدمة البريد.'; $PHPMAILER_LANG['instantiate'] = 'لم نستطع توفير خدمة البريد.';
//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; //$PHPMAILER_LANG['invalid_address'] = 'Not sending, email address is invalid: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.';
//$PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.'; //$PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.';
$PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: الأخطاء التالية ' . $PHPMAILER_LANG['recipients_failed'] = 'SMTP Error: الأخطاء التالية ' .
@ -24,4 +24,3 @@ $PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: ';
//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; //$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.';
//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; //$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: ';
//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; //$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: ';
?>

View file

@ -0,0 +1,24 @@
<?php
/**
* PHPMailer language file: refer to English translation for definitive list
* Belarusian Version by Aleksander Maksymiuk <info@setpro.pl>
*/
$PHPMAILER_LANG['authenticate'] = 'Памылка SMTP: памылка ідэнтыфікацыі.';
$PHPMAILER_LANG['connect_host'] = 'Памылка SMTP: нельга ўстанавіць сувязь з SMTP-серверам.';
$PHPMAILER_LANG['data_not_accepted'] = 'Памылка SMTP: звесткі непрынятыя.';
$PHPMAILER_LANG['empty_message'] = 'Пустое паведамленне.';
$PHPMAILER_LANG['encoding'] = 'Невядомая кадыроўка тэксту: ';
$PHPMAILER_LANG['execute'] = 'Нельга выканаць каманду: ';
$PHPMAILER_LANG['file_access'] = 'Няма доступу да файла: ';
$PHPMAILER_LANG['file_open'] = 'Нельга адкрыць файл: ';
$PHPMAILER_LANG['from_failed'] = 'Няправільны адрас адпраўніка: ';
$PHPMAILER_LANG['instantiate'] = 'Нельга прымяніць функцыю mail().';
$PHPMAILER_LANG['invalid_address'] = 'Нельга даслаць паведамленне, няправільны email атрымальніка: ';
$PHPMAILER_LANG['provide_address'] = 'Запоўніце, калі ласка, правільны email атрымальніка.';
$PHPMAILER_LANG['mailer_not_supported'] = ' - паштовы сервер не падтрымліваецца.';
$PHPMAILER_LANG['recipients_failed'] = 'Памылка SMTP: няправільныя атрымальнікі: ';
$PHPMAILER_LANG['signing'] = 'Памылка подпісу паведамлення: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'Памылка сувязі з SMTP-серверам.';
$PHPMAILER_LANG['smtp_error'] = 'Памылка SMTP: ';
$PHPMAILER_LANG['variable_set'] = 'Нельга ўстанавіць або перамяніць значэнне пераменнай: ';

View file

@ -1,26 +1,26 @@
<?php <?php
/** /**
* PHPMailer language file: refer to English translation for definitive list * PHPMailer language file: refer to English translation for definitive list
* Portuguese Version * Brazilian Portuguese Version
* By Paulo Henrique Garcia - paulo@controllerweb.com.br * By Paulo Henrique Garcia - paulo@controllerweb.com.br
*/ * Edited by Lucas Guimarães - lucas@lucasguimaraes.com
*/
$PHPMAILER_LANG['authenticate'] = 'Erro de SMTP: Não foi possível autenticar.'; $PHPMAILER_LANG['authenticate'] = 'Erro de SMTP: Não foi possível autenticar.';
$PHPMAILER_LANG['connect_host'] = 'Erro de SMTP: Não foi possível conectar com o servidor SMTP.'; $PHPMAILER_LANG['connect_host'] = 'Erro de SMTP: Não foi possível conectar com o servidor SMTP.';
$PHPMAILER_LANG['data_not_accepted'] = 'Erro de SMTP: Dados não aceitos.'; $PHPMAILER_LANG['data_not_accepted'] = 'Erro de SMTP: Dados rejeitados.';
//$PHPMAILER_LANG['empty_message'] = 'Message body empty'; $PHPMAILER_LANG['empty_message'] = 'Corpo da mensagem vazio';
$PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: '; $PHPMAILER_LANG['encoding'] = 'Codificação desconhecida: ';
$PHPMAILER_LANG['execute'] = 'Não foi possível executar: '; $PHPMAILER_LANG['execute'] = 'Não foi possível executar: ';
$PHPMAILER_LANG['file_access'] = 'Não foi possível acessar o arquivo: '; $PHPMAILER_LANG['file_access'] = 'Não foi possível acessar o arquivo: ';
$PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: Não foi possível abrir o arquivo: '; $PHPMAILER_LANG['file_open'] = 'Erro de Arquivo: Não foi possível abrir o arquivo: ';
$PHPMAILER_LANG['from_failed'] = 'Os endereços de rementente a seguir falharam: '; $PHPMAILER_LANG['from_failed'] = 'Os endereços dos remententes a seguir falharam: ';
$PHPMAILER_LANG['instantiate'] = 'Não foi possível instanciar a função mail.'; $PHPMAILER_LANG['instantiate'] = 'Não foi possível iniciar uma instância da função mail.';
//$PHPMAILER_LANG['invalid_email'] = 'Not sending, email address is invalid: '; $PHPMAILER_LANG['invalid_address'] = 'Não enviando, endereço de e-mail inválido: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não suportado.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';
$PHPMAILER_LANG['provide_address'] = 'Você deve fornecer pelo menos um endereço de destinatário de email.'; $PHPMAILER_LANG['provide_address'] = 'Você deve fornecer pelo menos um endereço de destinatário de e-mail.';
$PHPMAILER_LANG['recipients_failed'] = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: ' $PHPMAILER_LANG['recipients_failed'] = 'Erro de SMTP: Os endereços de destinatário a seguir falharam: ';
//$PHPMAILER_LANG['signing'] = 'Signing Error: '; $PHPMAILER_LANG['signing'] = 'Erro ao assinar: ';
//$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() failed.'; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() falhou.';
//$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; $PHPMAILER_LANG['smtp_error'] = 'Erro de servidor SMTP: ';
//$PHPMAILER_LANG['variable_set'] = 'Cannot set or reset variable: '; $PHPMAILER_LANG['variable_set'] = 'Não foi possível definir ou resetar a variável: ';
?>

Some files were not shown because too many files have changed in this diff Show more