Add link to account types from account creation page.
[platal.git] / modules / survey / survey.inc.php
CommitLineData
8fe81c50 1<?php
2/***************************************************************************
9f5bd98e 3 * Copyright (C) 2003-2010 Polytechnique.org *
8fe81c50 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
2f4b93be 22class Survey extends PlDBTableEntry implements SurveyQuestionContainer
8fe81c50 23{
2f4b93be
FB
24 private $fetchQuestions = true;
25 public $questions = array();
8fe81c50 26
2f4b93be 27 public function __construct()
8fe81c50 28 {
2f4b93be
FB
29 parent::__construct('surveys');
30 $this->registerFieldValidator('shortname', 'ShortNameFieldValidator');
31 $this->registerFieldFormatter('voters', 'JSonFieldFormatter');
32 $this->registerFieldFormatter('viewers', 'JSonFieldFormatter');
8fe81c50 33 }
34
2f4b93be 35 protected function postFetch()
8fe81c50 36 {
2f4b93be 37 if (!$this->fetchQuestions) {
4b8c8634 38 return true;
39 }
2f4b93be
FB
40 $selector = new SurveyQuestion($this);
41 $selector->sid = $this->id;
42
43 $stack = array();
44 foreach ($selector as $question) {
45 $question = $question->typedInstance();
46 if (is_null($question->parent)) {
47 $this->addQuestion($question);
8fe81c50 48 } else {
2f4b93be
FB
49 $pos = count($stack) - 1;
50 while ($stack[$pos]->qid != $question->parent) {
51 --$pos;
52 array_pop($stack);
8fe81c50 53 }
2f4b93be
FB
54 Platal::assert(count($stack) > 0, "Invalid question structure");
55 Platal::assert($stack[$pos] instanceof SurveyQuestionContainer, "Invalid question type");
56 $stack[$pos]->addQuestion($question);
8fe81c50 57 }
2f4b93be 58 array_push($stack, $question);
8fe81c50 59 }
2f4b93be 60 return true;
8fe81c50 61 }
62
2f4b93be 63 protected function postSave()
4b8c8634 64 {
2f4b93be
FB
65 $questions = array();
66 $selector = new SurveyQuestion($this);
67 $selector->sid = $this->id;
68 $selector->delete();
4b8c8634 69
2f4b93be
FB
70 $this->reassignQuestionIds();
71 foreach ($this->questions as $question) {
72 $question->sid = $this->id;
73 $question->insert();
8fe81c50 74 }
5c6e38d7 75 }
5c6e38d7 76
2f4b93be 77 public function addQuestion(SurveyQuestion $question, $pos = null)
5c6e38d7 78 {
2f4b93be
FB
79 $question->parent = null;
80 if (is_null($pos)) {
81 $this->questions[] = $question;
5c6e38d7 82 } else {
2f4b93be 83 array_splice($this->questions, $pos, 0, $question);
8fe81c50 84 }
8fe81c50 85 }
86
2f4b93be 87 public function newQuestion($type, $pos = null)
8fe81c50 88 {
2f4b93be
FB
89 $question = SurveyQuestion::instanceForType($this, $type);
90 $this->addQuestion($question, $pos);
91 return $question;
8fe81c50 92 }
8fe81c50 93
2f4b93be 94 public function reassignQuestionIds()
8fe81c50 95 {
2f4b93be
FB
96 $id = 0;
97 foreach ($this->questions as $question) {
98 $question->qid = $id;
99 if ($question instanceof SurveyQuestionContainer) {
100 $id = $question->reassignQuestionIds();
5c6e38d7 101 } else {
2f4b93be 102 $id++;
8fe81c50 103 }
8fe81c50 104 }
2f4b93be 105 return $id;
8fe81c50 106 }
107
2f4b93be 108 public function export()
8fe81c50 109 {
2f4b93be
FB
110 $export = parent::export();
111 $export['questions'] = array();
112 foreach ($this->questions as $question) {
113 $export['questions'][] = $question->export();
5c6e38d7 114 }
2f4b93be 115 return $export;
8fe81c50 116 }
8fe81c50 117
2f4b93be 118 public function canSee(User $user)
8fe81c50 119 {
2f4b93be
FB
120 if ($this->uid == $user->id() || $user->hasFlag('admin')) {
121 return true;
8fe81c50 122 }
2f4b93be 123 return false;
8fe81c50 124 }
8fe81c50 125
2f4b93be 126 public static function get($name, $fetchQuestions = true)
797d27db 127 {
2f4b93be
FB
128 if (is_array($name)) {
129 $name = $name[0];
797d27db 130 }
2f4b93be
FB
131 $survey = new Survey();
132 $survey->fetchQuestions = $fetchQuestions;
133 if (can_convert_to_integer($name)) {
134 $survey->id = $name;
797d27db 135 } else {
2f4b93be 136 $survey->shortname = $name;
8fe81c50 137 }
2f4b93be
FB
138 if (!$survey->fetch()) {
139 return null;
5c6e38d7 140 }
2f4b93be 141 return $survey;
8fe81c50 142 }
143
2f4b93be 144 public static function iterActive()
8fe81c50 145 {
2f4b93be
FB
146 $survey = new Survey();
147 $survey->fetchQuestions = false;
148 return $survey->iterateOnCondition('begin <= CURDATE() AND end >= CURDATE()
149 AND FIND_IN_SET(\'validated\', flags)');
8fe81c50 150 }
5c6e38d7 151}
8fe81c50 152
2f4b93be 153class ShortNameFieldValidator implements PlDBTableFieldValidator
5c6e38d7 154{
2f4b93be 155 public function __construct(PlDBTableField $field, $value)
8fe81c50 156 {
2f4b93be
FB
157 if (can_convert_to_integer($value) || !preg_match('/^[a-z0-9]+[-_\.a-z0-9]*[a-z0-9]+$/i', $value)) {
158 throw new PlDBBadValueException($value, $field,
159 'The shortname can only contain alphanumerical caracters, dashes, underscores and dots');
160 }
4b8c8634 161 }
8fe81c50 162}
8fe81c50 163
2f4b93be 164interface SurveyQuestionContainer
8fe81c50 165{
2f4b93be
FB
166 public function addQuestion(SurveyQuestion $question, $pos = null);
167 public function newQuestion($type, $pos = null);
168 public function reassignQuestionIds();
8fe81c50 169}
170
2f4b93be 171class SurveyQuestion extends PlDBTableEntry
8fe81c50 172{
2f4b93be
FB
173 protected $survey;
174 protected $parentQuestion;
8fe81c50 175
2f4b93be 176 public function __construct(Survey $survey)
8fe81c50 177 {
2f4b93be
FB
178 parent::__construct('survey_questions');
179 $this->registerFieldFormatter('parameters', 'JSonFieldFormatter');
180 $this->survey = $survey;
8fe81c50 181 }
8fe81c50 182
2f4b93be 183 public function typedInstance()
8fe81c50 184 {
2f4b93be
FB
185 $instance = self::instanceForType($this->survey, $this->type);
186 $instance->copy($this);
187 return $instance;
8fe81c50 188 }
189
2f4b93be 190 public static function instanceForType(Survey $survey, $type)
8fe81c50 191 {
2f4b93be
FB
192 require_once dirname(__FILE__) . '/' . $type . '.inc.php';
193 $class = 'SurveyQuestion' . $type;
194 return new $class($survey);
8fe81c50 195 }
196}
8fe81c50 197
2f4b93be 198class SurveyQuestionGroup extends SurveyQuestion implements SurveyQuestionContainer
8fe81c50 199{
2f4b93be 200 public $children = array();
8fe81c50 201
2f4b93be 202 public function __construct(Survey $survey)
9f01f40b 203 {
2f4b93be 204 parent::__construct($survey);
9f01f40b 205 }
4b8c8634 206
2f4b93be 207 public function addQuestion(SurveyQuestion $question, $pos = null)
4b8c8634 208 {
2f4b93be
FB
209 $question->parentQuestion = $this;
210 if (is_null($pos)) {
211 $this->children[] = $question;
8e9f416e 212 } else {
2f4b93be 213 array_splice($this->children, $pos, 0, $question);
8fe81c50 214 }
8fe81c50 215 }
216
2f4b93be 217 public function newQuestion($type, $pos = null)
8fe81c50 218 {
2f4b93be
FB
219 $question = SurveyQuestion::instanceForType($this->survey, $type);
220 $this->addQuestion($question, $pos);
221 return $question;
8fe81c50 222 }
8fe81c50 223
2f4b93be 224 public function reassignQuestionIds()
02d94468 225 {
2f4b93be
FB
226 $id = $this->qid + 1;
227 foreach ($this->children as $question) {
228 $question->qid = $id;
229 if ($question instanceof SurveyQuestionContainer) {
230 $id = $question->reassignQuestionIds();
231 } else {
232 $id++;
02d94468 233 }
234 }
2f4b93be 235 return $id;
02d94468 236 }
237
2f4b93be 238 protected function postSave()
02d94468 239 {
2f4b93be
FB
240 foreach ($this->children as $question) {
241 $question->sid = $this->sid;
242 $question->parent = $this->qid;
243 $question->insert();
02d94468 244 }
02d94468 245 }
246
2f4b93be 247 public function export()
02d94468 248 {
2f4b93be
FB
249 $export = parent::export();
250 $export['children'] = array();
251 foreach ($this->children as $child) {
252 $export['children'][] = $child->export();
02d94468 253 }
2f4b93be 254 return $export;
02d94468 255 }
02d94468 256}
02d94468 257
8602c852 258// vim:set et sw=4 sts=4 ts=4 foldmethod=marker enc=utf-8:
8fe81c50 259?>