mirror of
https://github.com/YunoHost-Apps/limesurvey_ynh.git
synced 2024-09-03 19:36:32 +02:00
330 lines
11 KiB
PHP
330 lines
11 KiB
PHP
<?php
|
|
|
|
|
|
abstract class QuestionBase implements iQuestion {
|
|
/**
|
|
* @var LimesurveyApi
|
|
*/
|
|
protected $api;
|
|
|
|
/**
|
|
* Array containing meta data for supported question attributes.
|
|
* @var array
|
|
*/
|
|
|
|
protected $attributes;
|
|
|
|
/**
|
|
* Array containing an array for each column.
|
|
* The supported keys for column meta data are:
|
|
* - type
|
|
* - name
|
|
* - description
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $columns;
|
|
|
|
/**
|
|
* Array containing attributes that all question types share.
|
|
* @var array
|
|
*/
|
|
private $defaultAttributes;
|
|
|
|
/**
|
|
* Array containing default attributes that are merged into the attribute
|
|
* arrays.
|
|
* @var array
|
|
*/
|
|
protected $defaultAttributeProperties = array(
|
|
'localized' => false,
|
|
'advanced' => false
|
|
);
|
|
public static $info = array();
|
|
|
|
/**
|
|
*
|
|
* @var iPlugin
|
|
*/
|
|
protected $plugin;
|
|
|
|
/**
|
|
*
|
|
* @var int The question id for this question object instance.
|
|
*/
|
|
protected $questionId = null;
|
|
|
|
/**
|
|
* @var int The response id for this question object instance.
|
|
*/
|
|
protected $responseId = null;
|
|
/**
|
|
* Contains the subquestion objects for this question.
|
|
* @var iQuestion[]
|
|
*/
|
|
protected $subQuestions;
|
|
|
|
/**
|
|
* The signature array is used for deriving a unique identifier for
|
|
* a question type.
|
|
* After initial release the contents of this array may NEVER be changed.
|
|
* Changing the contents of the array will identify the question object
|
|
* as a new question type and will break many if not all existing surveys.
|
|
*
|
|
*
|
|
* - Add more keys & values to make it more unique.
|
|
* @var array
|
|
*/
|
|
protected static $signature = array();
|
|
|
|
/**
|
|
* @param iPlugin $plugin The plugin to which this question belongs.
|
|
* @param int $questionId
|
|
* @param int $responseId Pass a response id to load results.
|
|
*/
|
|
|
|
public function __construct(iPlugin $plugin, LimesurveyApi $api, $questionId = null, $responseId = null) {
|
|
$this->plugin = $plugin;
|
|
$this->api = $api;
|
|
$this->responseId = $responseId;
|
|
$this->questionId = $questionId;
|
|
if (isset($questionId))
|
|
{
|
|
$this->loadSubQuestions($questionId);
|
|
}
|
|
$this->defaultAttributes = array(
|
|
'questiontype' => array(
|
|
'type' => 'select',
|
|
'localized' => false,
|
|
'advanced' => false,
|
|
'label' => gt('Question type:'),
|
|
'options' => CHtml::listData(App()->getPluginManager()->loadQuestionObjects(), 'guid', 'name')
|
|
),
|
|
'code' => array(
|
|
'type' => 'string',
|
|
'localized' => false,
|
|
'advanced' => false,
|
|
'label' => gT('Question code:')
|
|
),
|
|
'gid' => array(
|
|
'type' => 'select',
|
|
'localized' => false,
|
|
'advanced' => false,
|
|
'label' => gT('Question group:'),
|
|
'options' => function($this) { return $this->api->getGroupList($this->get('sid')); }
|
|
),
|
|
'relevance' => array(
|
|
'type' => 'relevance',
|
|
'localized' => false,
|
|
'advanced' => false,
|
|
'label' => gT('Relevance equation:')
|
|
),
|
|
'randomization' => array(
|
|
'type' => 'string',
|
|
'localized' => false,
|
|
'advanced' => false,
|
|
'label' => gT("Randomization group:")
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* This function retrieves question data. Do not cache this data; the plugin storage
|
|
* engine will handling caching. After the first call to this function, subsequent
|
|
* calls will only consist of a few function calls and array lookups.
|
|
*
|
|
* @param string $key String identifier for data.
|
|
* @param mixed $default Default value.
|
|
* @param string $language Language to retrieve.
|
|
* @param int $questionId By default uses the question id for the current instance. Override this to read from another question.
|
|
* @return boolean
|
|
*/
|
|
protected function get($key = null, $default = null, $language = null, $questionId = null)
|
|
{
|
|
if (!isset($questionId) && isset($this->questionId))
|
|
{
|
|
$questionId = $this->questionId;
|
|
return $this->plugin->getStore()->get($this->plugin, $key, 'Question', $questionId, $default, $language);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the meta data for question attributes.
|
|
* Optionally pass one or more languages to also get current values.
|
|
* Pass * to get all stored languages.
|
|
* @param type $language
|
|
* @return type
|
|
*/
|
|
public function getAttributes($languages = null)
|
|
{
|
|
$allAttributes = array_merge($this->defaultAttributes, $this->attributes);
|
|
if (count($allAttributes) != count($this->defaultAttributes) + count($this->attributes))
|
|
{
|
|
throw new Exception(get_class($this) . " must not redefine default attributes");
|
|
}
|
|
|
|
foreach ($allAttributes as $name => &$metaData)
|
|
{
|
|
$metaData = array_merge($this->defaultAttributeProperties, $metaData);
|
|
if (isset($this->questionId))
|
|
{
|
|
if (is_array($languages))
|
|
{
|
|
foreach ($languages as $language)
|
|
{
|
|
$metaData['current'][$language] = $this->get($name, null, $language);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$metaData['current'] = $this->get($name, null, $languages);
|
|
}
|
|
|
|
// Populate select fields with a list.
|
|
if ($metaData['type'] == 'select' && is_callable($metaData['options']))
|
|
{
|
|
$metaData['options'] = call_user_func($metaData['options'], $this);
|
|
}
|
|
}
|
|
}
|
|
return $allAttributes;
|
|
}
|
|
|
|
public function getColumns()
|
|
{
|
|
return $this->columns;
|
|
}
|
|
|
|
|
|
public function getCount()
|
|
{
|
|
return 1;
|
|
}
|
|
/**
|
|
* This function derives a unique identifier for identifying a question type.
|
|
*/
|
|
public static function getGUID()
|
|
{
|
|
// We use json_encode because it is faster than serialize.
|
|
return md5(json_encode(static::$signature));
|
|
}
|
|
|
|
/**
|
|
* Gets the response for the current response id.
|
|
* @return type
|
|
*/
|
|
public function getResponse()
|
|
{
|
|
if (isset($this->responseId))
|
|
{
|
|
$surveyId = Question::model()->findFieldByPk($this->questionId, 'sid');
|
|
$response = SurveyDynamic::model($surveyId)->findByPk($this->responseId);
|
|
$columns = $this->getColumns();
|
|
foreach ($columns as &$column)
|
|
{
|
|
if (isset($response->$column))
|
|
{
|
|
$column['response'] = $response->$column;
|
|
}
|
|
}
|
|
return $columns;
|
|
}
|
|
}
|
|
|
|
public function getVariables()
|
|
{
|
|
if (isset($this->questionId))
|
|
{
|
|
return array(
|
|
$this->get('code') => array(
|
|
'id' => $this->questionId,
|
|
'relevance' => $this->get('relevance')
|
|
)
|
|
);
|
|
}
|
|
return array();
|
|
}
|
|
/**
|
|
* Load the question data from the questions model.
|
|
* @param type $questionId
|
|
*/
|
|
public function loadSubQuestions($questionId)
|
|
{
|
|
$subQuestions = Question::model()->findAllByAttributes(array(
|
|
'parent_id' => $questionId
|
|
));
|
|
foreach ($subQuestions as $subQuestion)
|
|
{
|
|
/**
|
|
* @todo Alter this so that subquestion can be of another type.
|
|
*/
|
|
$this->subQuestions[] = new self($subQuestion->qid, $this->responseId);
|
|
}
|
|
}
|
|
|
|
public function saveAttributes(array $attributeValues, $qid = null)
|
|
{
|
|
$attributes = $this->getAttributes();
|
|
$result = true;
|
|
foreach ($attributeValues as $key => $value)
|
|
{
|
|
// Check if the attribute is valid for the question.
|
|
if (isset($attributes[$key]))
|
|
{
|
|
// If the attribute is localized, save each language.
|
|
if ($attributes[$key]['localized'])
|
|
{
|
|
foreach ($value as $language => $localizedValue)
|
|
{
|
|
if (!$this->set($key, $localizedValue, $language, $qid))
|
|
{
|
|
$result = false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!$this->set($key, $value, $qid))
|
|
{
|
|
$result = false;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* This function saves question data.
|
|
* @param int $qid Question id.
|
|
* @param string $key
|
|
* @param string $language
|
|
* @param mixed $value
|
|
* @return boolean
|
|
*/
|
|
protected function set($key, $value, $language = null, $questionId = null)
|
|
{
|
|
if (!isset($questionId) && isset($this->questionId))
|
|
{
|
|
$questionId = $this->questionId;
|
|
return $this->plugin->getStore()->set($this->plugin, $key, $value, 'Question', $questionId, $language);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
?>
|