Start working on multiple choice questions.
[platal.git] / modules / survey / question.inc.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2011 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 interface SurveyQuestionContainer
23 {
24 public function addQuestion(SurveyQuestion $question, $pos = null);
25 public function newQuestion($type, $pos = null);
26 public function reassignQuestionIds();
27 }
28
29 class SurveyQuestion extends PlDBTableEntry
30 {
31 protected $survey;
32 protected $parentQuestion;
33
34 public function __construct(Survey $survey)
35 {
36 parent::__construct('survey_questions');
37 $this->registerFieldFormatter('parameters', 'JSonFieldFormatter');
38 $this->survey = $survey;
39 }
40
41 public function typedInstance()
42 {
43 $instance = self::instanceForType($this->survey, $this->type);
44 $instance->copy($this);
45 return $instance;
46 }
47
48 public static function instanceForType(Survey $survey, $type)
49 {
50 $file = dirname(__FILE__) . '/' . $type . '.inc.php';
51 if (!file_exists($file)) {
52 throw new Exception("Unknown question type \"$type\"");
53 }
54 require_once $file;
55 $class = 'SurveyQuestion' . $type;
56 return new $class($survey);
57 }
58
59 public function voteTemplate()
60 {
61 return 'survey/question.' . $this->type . '.tpl';
62 }
63
64 public function editTemplate()
65 {
66 return 'survey/edit.' . $this->type . '.tpl';
67 }
68
69 protected function buildAnswer(SurveyAnswer $answer, PlDict $answers)
70 {
71 Platal::assert(false, "This should not happen");
72 }
73
74 public function vote(SurveyVote $vote, PlDict $answers)
75 {
76 if ($this->flags->hasFlag('noanswer')) {
77 if ($answers->has($this->qid)) {
78 throw new Exception("Des réponses ont été données à une question n'en attendant pas");
79 }
80 return null;
81 }
82 $answer = $vote->getAnswer($this);
83 if (is_null($answer)) {
84 return null;
85 }
86 if (!$this->buildAnswer($answer, $answers)) {
87 return $answer;
88 }
89 if ($this->flags->hasFlag('mandatory') && is_null($answer->answer)) {
90 $answer->inError = 'Tu dois répondre à cette question';
91 }
92 return $answer;
93 }
94 }
95
96 class SurveyQuestionGroup extends SurveyQuestion implements SurveyQuestionContainer
97 {
98 public $children = array();
99
100 public function __construct(Survey $survey)
101 {
102 parent::__construct($survey);
103 }
104
105 public function addQuestion(SurveyQuestion $question, $pos = null)
106 {
107 $question->parentQuestion = $this;
108 if (is_null($pos)) {
109 $this->children[] = $question;
110 } else {
111 array_splice($this->children, $pos, 0, $question);
112 }
113 }
114
115 public function newQuestion($type, $pos = null)
116 {
117 $question = SurveyQuestion::instanceForType($this->survey, $type);
118 $this->addQuestion($question, $pos);
119 return $question;
120 }
121
122 public function reassignQuestionIds()
123 {
124 $id = $this->qid + 1;
125 foreach ($this->children as $question) {
126 $question->qid = $id;
127 if ($question instanceof SurveyQuestionContainer) {
128 $id = $question->reassignQuestionIds();
129 } else {
130 $id++;
131 }
132 }
133 return $id;
134 }
135
136 protected function postSave()
137 {
138 foreach ($this->children as $question) {
139 $question->sid = $this->sid;
140 $question->parent = $this->qid;
141 $question->insert();
142 }
143 }
144
145 public function export()
146 {
147 $export = parent::export();
148 $export['children'] = array();
149 foreach ($this->children as $child) {
150 $export['children'][] = $child->export();
151 }
152 return $export;
153 }
154
155 public function vote(SurveyVote $vote, PlDict $answers)
156 {
157 $a = parent::vote($vote, $answers);
158 foreach ($this->children as $child) {
159 $child->vote($vote, $answers);
160 }
161 return $a;
162 }
163
164 public function child($qid)
165 {
166 $prev = null;
167 foreach ($this->children as $question) {
168 if ($qid == $question->qid) {
169 return $question;
170 } else if ($qid < $question->qid) {
171 Platal::assert($prev instanceof SurveyQuestionGroup);
172 return $prev->child($qid);
173 }
174 $prev = $question;
175 }
176 Platal::assert($prev instanceof SurveyQuestionGroup);
177 return $prev->child($qid);
178 }
179 }
180
181 // vim:set et sw=4 sts=4 ts=4 foldmethod=marker enc=utf-8:
182 ?>