2 /***************************************************************************
3 * Copyright (C) 2003-2010 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
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. *
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. *
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 *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
22 require_once dirname(__FILE__
) . '/question.inc.php';
23 require_once dirname(__FILE__
) . '/answer.inc.php';
25 class Survey
extends PlDBTableEntry
implements SurveyQuestionContainer
27 private $fetchQuestions = true
;
28 public $questions = array();
29 public $viewerFilter = null
;
30 public $voterFilter = null
;
32 public function __construct()
34 parent
::__construct('surveys');
35 $this->registerFieldValidator('shortname', 'ShortNameFieldValidator');
36 $this->registerFieldFormatter('voters', 'JSonFieldFormatter');
37 $this->registerFieldFormatter('viewers', 'JSonFieldFormatter');
40 protected function postFetch()
42 if (!is_null($this->voters
)) {
43 $this->voterFilter
= UserFilter
::fromExportedConditions($this->voters
);
45 $this->voterFilter
= null
;
47 if (!is_null($this->viewers
)) {
48 $this->viewerFilter
= UserFilter
::fromExportedConditions($this->viewers
);
50 $this->viewerFilter
= null
;
52 if (!$this->fetchQuestions
) {
55 $selector = new SurveyQuestion($this);
56 $selector->sid
= $this->id
;
59 foreach ($selector as $question) {
60 $question = $question->typedInstance();
61 if (is_null($question->parent
)) {
62 $this->addQuestion($question);
64 $pos = count($stack) - 1;
65 while ($stack[$pos]->qid
!= $question->parent
) {
69 Platal
::assert(count($stack) > 0, "Invalid question structure");
70 Platal
::assert($stack[$pos] instanceof SurveyQuestionContainer
, "Invalid question type");
71 $stack[$pos]->addQuestion($question);
73 array_push($stack, $question);
78 protected function preSave()
80 if (!is_null($this->voterFilter
)) {
81 $this->voters
= $this->voterFilter
->exportConditions();
85 if (!is_null($this->viewerFilter
)) {
86 $this->viewers
= $this->viewerFilter
->exportConditions();
88 $this->viewers
= null
;
93 protected function postSave()
96 $selector = new SurveyQuestion($this);
97 $selector->sid
= $this->id
;
100 $this->reassignQuestionIds();
101 foreach ($this->questions
as $question) {
102 $question->sid
= $this->id
;
107 public function addQuestion(SurveyQuestion
$question, $pos = null
)
109 $question->parent
= null
;
111 $this->questions
[] = $question;
113 array_splice($this->questions
, $pos, 0, $question);
117 public function newQuestion($type, $pos = null
)
119 $question = SurveyQuestion
::instanceForType($this, $type);
120 $this->addQuestion($question, $pos);
124 public function questionForId($qid)
127 foreach ($this->questions
as $question) {
128 if ($qid == $question->qid
) {
130 } else if ($qid < $question->qid
) {
131 Platal
::assert($prev instanceof SurveyQuestionGroup
,
132 "Id gap must be caused by question groups");
133 return $prev->child($qid);
137 Platal
::assert($prev instanceof SurveyQuestionGroup
,
138 "Id gap must be caused by question groups");
139 return $prev->child($qid);
142 public function reassignQuestionIds()
145 foreach ($this->questions
as $question) {
146 $question->qid
= $id;
147 if ($question instanceof SurveyQuestionContainer
) {
148 $id = $question->reassignQuestionIds();
156 public function export()
158 $export = parent
::export();
159 $export['questions'] = array();
160 foreach ($this->questions
as $question) {
161 $export['questions'][] = $question->export();
166 /* Return an indicator of the progression of the survey:
167 * negative values means 'the survey is not started'
168 * 0 means 'the survey is in progress'
169 * positive values means 'the survey expired'
171 public function progression()
173 if (!$this->flags
->hasFlag('validated')) {
177 if ($this->begin
->format('U') > $now) {
180 if ($this->end
->format('U') <= $now) {
186 public function canSee(User
$user)
188 if ($this->canSeeResults($user) ||
$this->canVote($user)) {
194 public function canSeeResults(User
$user)
196 if ($user->id() == $this->uid ||
$user->hasFlag('admin')) {
199 if (is_null($this->viewerFilter
)) {
200 return $this->viewerFilter
->checkUser($user);
205 public function canVote(User
$user)
207 $status = $this->progression();
209 return "Ce sondage n'est pas encore commencé";
210 } else if ($status > 0) {
211 return "Ce sondage est terminé";
213 if (!is_null($this->voterFilter
) && !$this->voterFilter
->checkUser($user)) {
214 return "Ce sondage ne s'adresse pas à toi";
216 $vote = SurveyVote
::getVote($this, $user, false
);
217 if (is_null($vote)) {
218 return "Tu as déjà voté à ce sondage.";
223 public function vote(User
$user, array $answers)
225 if (!$this->canVote($user)) {
226 return array('survey' => "Tu n'es pas autorisé à voter à ce sondage.");
228 $vote = SurveyVote
::getVote($this, $user);
229 if (is_null($vote)) {
232 $answers = new PlDict($answers);
233 foreach ($this->questions
as $question) {
234 $question->vote($vote, $answers);
239 public static function get($name, $fetchQuestions = true
)
241 if (is_array($name)) {
244 $survey = new Survey();
245 $survey->fetchQuestions
= $fetchQuestions;
246 if (can_convert_to_integer($name)) {
249 $survey->shortname
= $name;
251 if (!$survey->fetch()) {
257 public static function iterActive()
259 $survey = new Survey();
260 $survey->fetchQuestions
= false
;
261 return $survey->iterateOnCondition('begin <= CURDATE() AND end >= CURDATE()
262 AND FIND_IN_SET(\'validated\', flags)');
266 class ShortNameFieldValidator
implements PlDBTableFieldValidator
268 public function __construct(PlDBTableField
$field, $value)
270 if (can_convert_to_integer($value) ||
!preg_match('/^[a-z0-9]+[-_\.a-z0-9]*[a-z0-9]+$/i', $value)) {
271 throw new PlDBBadValueException($value, $field,
272 'The shortname can only contain alphanumerical caracters, dashes, underscores and dots');
277 // vim:set et sw=4 sts=4 ts=4 foldmethod=marker enc=utf-8: