2 /***************************************************************************
3 * Copyright (C) 2003-2007 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 // {{{ class Survey : static database managing functions
25 // {{{ static function retrieveList() : gets the list of available survey (current, old and not validated surveys)
26 public static function retrieveList($type, $tpl = true
)
35 $where = 'valid=1 AND end > NOW()';
39 $where = 'valid=1 AND end <= NOW()';
44 $sql = 'SELECT survey_id, title, end
48 return XDB
::iterator($sql);
50 return XDB
::iterRow($sql);
55 // {{{ static function proposeSurvey() : stores a proposition of survey in database (before validation)
56 public static function proposeSurvey($survey)
58 $sql = 'INSERT INTO survey_questions
66 $data = $survey->storeArray();
67 return XDB
::execute($sql, serialize($survey), $data['question'], $data['comment'], S
::v('uid'), $data['end'], $data['promos']);
71 // {{{ static function updateSurvey() : updates a survey in database (before validation)
72 public static function updateSurvey($survey, $sid)
74 $sql = 'UPDATE survey_questions
80 WHERE survey_id={?};';
81 $data = $survey->storeArray();
82 return XDB
::execute($sql, serialize($survey), $data['question'], $data['comment'], $data['end'], $data['promos'], $sid);
86 // {{{ static function retrieveSurvey() : gets a survey in database (and unserialize the survey object structure)
87 public static function retrieveSurvey($sid)
89 $sql = 'SELECT questions, title, description, end, promos, valid
92 $res = XDB
::query($sql, $sid);
93 $data = $res->fetchOneAssoc();
94 $survey = unserialize($data['questions']);
95 if (isset($data['end'])) {
96 $data['end'] = preg_replace('#^(\d{4})-(\d{2})-(\d{2})$#', '\3/\2/\1', $data['end']);
98 $survey->update(array('question' => $data['title'], 'comment' => $data['description'], 'end' => $data['end'], 'promos' => $data['promos']));
99 $survey->setValid($data['valid']);
104 // {{{ static function retrieveSurveyInfo() : gets information about a survey (title, description, end date, restrictions) but does not unserialize the survey object structure
105 public static function retrieveSurveyInfo($sid)
107 $sql = 'SELECT title, description, end, promos, valid
108 FROM survey_questions
109 WHERE survey_id={?}';
110 $res = XDB
::query($sql, $sid);
111 return $res->fetchOneAssoc();
115 // {{{ static function validateSurvey() : validates a survey
116 public static function validateSurvey($sid)
118 $sql = 'UPDATE survey_questions
120 WHERE survey_id={?};';
121 return XDB
::execute($sql, $sid);
125 // {{{ static function deleteSurvey() : deletes a survey (and all its votes)
126 public static function deleteSurvey($sid)
128 $sql1 = 'DELETE FROM survey_questions
129 WHERE survey_id={?};';
130 $sql2 = 'DELETE FROM survey_answers
131 WHERE survey_id={?};';
132 $sql3 = 'DELETE FROM survey_votes
133 WHERE survey_id={?};';
134 return (XDB
::execute($sql1, $sid) && XDB
::execute($sql2, $sid) && XDB
::execute($sql3, $sid));
140 // {{{ abstract class SurveyQuestion
141 abstract class SurveyQuestion
143 // {{{ static properties and methods regarding question types
144 private static $types = array('text' => 'texte court',
145 'textarea' => 'texte long',
146 'num' => 'numérique',
148 'checkbox' => 'checkbox',
149 'personal' => 'informations personnelles');
151 public static function getTypes()
156 public static function isType($t)
158 return array_key_exists($t, self
::$types);
162 // {{{ common properties, constructor, and basic methods
168 protected function __construct($i, $args)
171 $this->update($args);
174 protected function update($a)
176 $this->question
= $a['question'];
177 $this->comment
= $a['comment'];
180 protected function getId()
185 abstract protected function getQuestionType();
188 // {{{ tree manipulation methods : not implemented here (but definition needed)
189 protected function addChildNested($i, $c)
194 protected function addChildAfter($i, $c)
199 protected function delChild($i)
205 // {{{ function edit($i, $a) : searches and edits question $i
206 protected function edit($i, $a)
208 if ($this->id
== $i) {
217 // {{{ functions toArray() and searchToArray($i) : (searches and) converts to array
218 protected function toArray()
220 return $this->storeArray();
223 protected function searchToArray($i)
225 if ($this->id
== $i) {
226 return $this->storeArray();
232 protected function storeArray()
234 return array('type' => $this->getQuestionType(), 'id' => $this->id
, 'question' => $this->question
, 'comment' => $this->comment
);
238 // {{{ function checkSyntax() : checks question elements (before storing into database)
239 protected function checkSyntax()
245 // {{{ function vote() : handles vote
246 protected function checkAnswer($ans)
251 function vote($sid, $vid, $a)
253 $ans = $this->checkAnswer($a[$this->getId
]);
256 'INSERT INTO survey_answers
260 answer = "{?}"', $sid, $vid, $id, $ans);
267 // {{{ abstract class SurveyTreeable extends SurveyQuestion : questions that allow nested ones
268 abstract class SurveyTreeable
extends SurveyQuestion
270 // {{{ common properties, constructor
273 protected function __construct($i, $args)
275 parent
::__construct($i, $args);
276 $this->children
= array();
280 // {{{ tree manipulation functions : actual implementation
281 protected function hasChild()
283 return !is_null($this->children
) && is_array($this->children
);
286 protected function addChildNested($i, $c)
288 if ($this->getId() == $i) {
289 if ($this->hasChild()) {
290 array_unshift($this->children
, $c);
292 $this->children
= array($c);
296 foreach ($this->children
as $child) {
297 if ($child->addChildNested($i, $c)) {
305 protected function addChildAfter($i, $c)
308 for ($k = 0; $k < count($this->children
); $k++
) {
309 if ($this->children
[$k]->getId() == $i) {
313 if ($this->children
[$k]->addChildAfter($i, $c)) {
319 array_splice($this->children
, $k+
1, 0, array($c));
325 protected function delChild($i)
328 for ($k = 0; $k < count($this->children
); $k++
) {
329 if ($this->children
[$k]->getId() == $i) {
333 if ($this->children
[$k]->delChild($i)) {
339 array_splice($this->children
, $k, 1);
346 // {{{ function edit() with tree support
347 protected function edit($i, $a)
349 if ($this->getId() == $i) {
353 foreach ($this->children
as $child) {
354 if ($child->edit($i, $a)) {
363 // {{{ functions toArray() and searchToArray() with tree support
364 protected function toArray()
366 if ($this->hasChild()) {
368 foreach ($this->children
as $child) {
369 $cArr[] = $child->toArray();
371 $a = $this->storeArray();
372 $a['children'] = $cArr;
375 return $this->storeArray();
379 protected function searchToArray($i)
381 if ($this->getId() == $i) {
382 return $this->storeArray();
384 foreach ($this->children
as $child) {
385 $a = $child->searchToArray($i);
386 if (!is_null($a) && is_array($a)) {
395 // {{{ function checkSyntax()
396 protected function checkSyntax()
399 foreach ($this->children
as $child) {
400 $a = $child->checkSyntax();
405 return (empty($rArr))? null
: $rArr;
409 // {{{ function vote()
410 function vote($sid, $vid, $a)
412 parent
::vote($sid, $vid, $a);
413 if ($this->hasChild()) {
414 foreach ($this->children
as $c) {
415 $c->vote($sid, $vid, $a);
423 // {{{ class SurveyRoot extends SurveyTreeable : root of any survey, actually the only entry point (no public methods outside this class)
424 class SurveyRoot
extends SurveyTreeable
426 // {{{ properties, constructor and basic methods
433 public function __construct($args)
435 parent
::__construct(0, $args);
439 public function update($args)
441 parent
::update($args);
442 //$this->beginning = $args['beginning_year'] . "-" . $args['beginning_month'] . "-" . $args['beginning_day'];
443 //$this->end = $args['end_year'] . "-" . $args['end_year'] . "-" . $args['end_day'];
444 if (preg_match('#^\d{2}/\d{2}/\d{4}$#', $args['end'])) {
445 $this->end
= preg_replace('#^(\d{2})/(\d{2})/(\d{4})$#', '\3-\2-\1', $args['end']);
447 $this->end
= (preg_match('#^\d{4}-\d{2}-\d{2}$#', $args['end']))?
$args['end'] : '#';
449 $this->promos
= ($args['promos'] == '' ||
preg_match('#^(\d{4}-?|(\d{4})?-\d{4})(,(\d{4}-?|(\d{4})?-\d{4}))*$#', $args['promos']))?
$args['promos'] : '#';
452 private function getNextId()
455 return $this->last_id
;
458 public function setValid($v)
460 $this->valid
= (intval($v) != 0);
463 public function isValid()
468 protected function getQuestionType()
474 // {{{ function factory($type, $args) : builds a question according to the given type
475 public function factory($t, $args)
477 $i = $this->getNextId();
480 return new SurveyText($i, $args);
482 return new SurveyTextarea($i, $args);
484 return new SurveyNum($i, $args);
486 return new SurveyRadio($i, $args);
488 return new SurveyCheckbox($i, $args);
490 return new SurveyPersonal($i, $args);
497 // {{{ methods needing public access
498 public function addChildNested($i, $c)
500 return parent
::addChildNested($i, $c);
503 public function addChildAfter($i, $c)
505 return parent
::addChildAfter($i, $c);
508 public function delChild($i)
510 return parent
::delChild($i);
513 public function edit($i, $a)
515 return parent
::edit($i, $a);
518 public function toArray()
520 return parent
::toArray();
523 public function searchToArray($i)
525 return parent
::searchToArray($i);
529 // {{{ function storeArray()
530 public function storeArray()
532 $rArr = parent
::storeArray();
533 $rArr['beginning'] = $this->beginning
;
534 $rArr['end'] = $this->end
;
535 $rArr['promos'] = $this->promos
;
540 // {{{ function checkSyntax()
541 private static $errorMessages = array(
542 "dateformat" => "la date de fin de sondage est mal formattée : elle doit respecter la syntaxe dd/mm/aaaa",
543 "datepassed" => "la date de fin de sondage est déjà dépassée : vous devez préciser une date future",
544 "promoformat" => "les restrictions à certaines promotions sont mal formattées"
547 public function checkSyntax()
549 $rArr = parent
::checkSyntax();
550 if (!preg_match('#^\d{4}-\d{2}-\d{2}$#', $this->end
)) {
551 $rArr[] = array('question' => $this->getId(), 'error' => self
::$errorMessages["dateformat"]);
553 if (strtotime($this->end
) - time() <= 0) {
554 $rArr[] = array('question' => $this->getId(), 'error' => self
::$errorMessages["datepassed"]);
557 if ($this->promos
!= '' && !preg_match('#^(\d{4}-?|(\d{4})?-\d{4})(,(\d{4}-?|(\d{4})?-\d{4}))*$#', $this->promos
)) {
558 $rArr[] = array('question' => $this->getId(), 'error' => self
::$errorMessages["promoformat"]);
560 return (empty($rArr))? null
: $rArr;
566 // {{{ abstract class SurveySimple extends SurveyQuestion : "opened" questions
567 abstract class SurveySimple
extends SurveyQuestion
569 protected function checkAnswer($ans)
575 // {{{ class SurveyText extends SurveySimple : simple text field, allowing a few words
576 class SurveyText
extends SurveySimple
578 protected function getQuestionType()
585 // {{{ class SurveyTextarea extends SurveySimple : textarea field, allowing longer comments
586 class SurveyTextarea
extends SurveySimple
588 protected function getQuestionType()
595 // {{{ class SurveyNum extends SurveySimple : allows numerical answers
596 class SurveyNum
extends SurveySimple
598 protected function checkAnswer($ans)
603 protected function getQuestionType()
611 // {{{ abstract class SurveyList extends SurveyTreeable : restricted questions that allows only a list of possible answers
612 abstract class SurveyList
extends SurveyTreeable
616 protected function update($args)
618 parent
::update($args);
619 $this->choices
= explode('|', $args['options']);
622 protected function storeArray()
624 $rArr = parent
::storeArray();
625 $rArr['choices'] = $this->choices
;
626 $rArr['options'] = implode('|', $this->choices
);
632 // {{{ class SurveyRadio extends SurveyList : radio question, allows one answer among the list offered
633 class SurveyRadio
extends SurveyList
635 protected function checkAnswer($ans)
637 return (in_array($ans, $this->choices
)) ?
$ans : "";
640 protected function getQuestionType()
647 // {{{ class SurveyCheckbox extends SurveyList : checkbox question, allows any number of answers among the list offered
648 class SurveyCheckbox
extends SurveyList
650 protected function checkAnswer($ans)
653 foreach ($this->choices
as $key => $value) {
654 if (array_key_exists($key,$v[$id]) && $v[$id][$key]) {
658 $rep = (strlen($rep) >= 4) ?
substr($rep, 4) : "";
662 protected function getQuestionType()
670 // {{{ class SurveyPersonal extends SurveyQuestion : allows easy and verified access to user's personal data (promotion, name...)
671 class SurveyPersonal
extends SurveyQuestion
675 protected function update($args)
677 $args['question'] = "Informations personnelles";
678 parent
::update($args);
679 $this->perm
['promo'] = isset($args['promo'])?
1 : 0;
680 $this->perm
['name'] = isset($args['name'])?
1 : 0;
683 protected function checkAnswer($ans)
685 if (intval($ans) == 1) {
693 protected function getQuestionType()
698 protected function storeArray()
700 $a = parent
::storeArray();
701 $a['promo'] = $this->perm
['promo'];
702 $a['name'] = $this->perm
['name'];
708 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: