surveys : adds 'table' questions
authorx2004laborde <x2004laborde@839d8a87-29fc-0310-9880-83ba4fa771e5>
Tue, 8 May 2007 09:27:57 +0000 (09:27 +0000)
committerx2004laborde <x2004laborde@839d8a87-29fc-0310-9880-83ba4fa771e5>
Tue, 8 May 2007 09:27:57 +0000 (09:27 +0000)
git-svn-id: svn+ssh://murphy/home/svn/platal/trunk@1804 839d8a87-29fc-0310-9880-83ba4fa771e5

modules/survey/survey.inc.php
templates/survey/edit_checkboxtable.tpl [new file with mode: 0644]
templates/survey/edit_question.tpl
templates/survey/edit_radio.tpl
templates/survey/edit_radiotable.tpl [new file with mode: 0644]
templates/survey/show_checkbox.tpl
templates/survey/show_checkboxtable.tpl [new file with mode: 0644]
templates/survey/show_radio.tpl
templates/survey/show_radiotable.tpl [new file with mode: 0644]
templates/survey/show_text.tpl
templates/survey/show_textarea.tpl

index 39047af..a28580a 100644 (file)
@@ -37,11 +37,13 @@ class Survey
         return ($long)? self::$longModes : self::$shortModes;
     }
 
-    private static $types = array('text'     => 'Texte court',
-                                  'textarea' => 'Texte long',
-                                  'num'      => 'Num&#233;rique',
-                                  'radio'    => 'Choix multiples (une rĂ©ponse)',
-                                  'checkbox' => 'Choix multiples (plusieurs rĂ©ponses)');
+    private static $types = array('text'          => 'Texte court',
+                                  'textarea'      => 'Texte long',
+                                  'num'           => 'Num&#233;rique',
+                                  'radio'         => 'Choix multiples (une r&#233;ponse)',
+                                  'checkbox'      => 'Choix multiples (plusieurs r&#233;ponses)',
+                                  'radiotable'    => 'Questions multiples &#224; choix multiples (une r&#233;ponse)',
+                                  'checkboxtable' => 'Questions multiples &#224; choix mutliples (plusieurs r&#233;ponses)');
 
     public static function getTypes()
     {
@@ -158,10 +160,7 @@ class Survey
                     $q = $this->questions[$k]->toArray();
                     $q['id'] = $k;
                     if ($this->isEnded()) { // if the survey is ended, then adds here the results of this question
-                        $sql = $this->questions[$k]->buildResultRequest();
-                        if ($sql != '') {
-                            $q['result'] = XDB::iterator($sql, $this->id, $k);
-                        }
+                        $q['result'] = $this->questions[$k]->getResultArray($this->id, $k);
                     }
                     $qArr[$k] = $q;
                 }
@@ -250,8 +249,10 @@ class Survey
             return new SurveyRadio($args);
         case 'checkbox':
             return new SurveyCheckbox($args);
-        case 'personal':
-            return new SurveyPersonal($args);
+        case 'radiotable':
+            return new SurveyRadioTable($args);
+        case 'checkboxtable':
+            return new SurveyCheckboxTable($args);
         default:
             return null;
         }
@@ -500,6 +501,11 @@ abstract class SurveyQuestion
     }
 
     abstract protected function getQuestionType();
+
+    protected function getQuestion()
+    {
+        return $this->question;
+    }
     // }}}
 
     // {{{ function toArray() : converts to array
@@ -516,7 +522,7 @@ abstract class SurveyQuestion
     }
     // }}}
 
-    // {{{ function checkAnswer : returns a correctly formatted answer (or nothing empty string if error)
+    // {{{ function checkAnswer : returns a correct answer (or a null value if error)
     public function checkAnswer($ans)
     {
         return null;
@@ -524,10 +530,7 @@ abstract class SurveyQuestion
     // }}}
 
     // {{{ functions regarding the results of a survey
-    public function buildResultRequest()
-    {
-        return '';
-    }
+    abstract public function getResultArray($sid, $qid);
 
     public function getCSVColumn()
     {
@@ -546,7 +549,7 @@ abstract class SurveySimple extends SurveyQuestion
         return array($ans);
     }
 
-    public function buildResultRequest()
+    public function getResultArray($sid, $qid)
     {
         $sql = 'SELECT answer
                   FROM survey_answers
@@ -554,7 +557,8 @@ abstract class SurveySimple extends SurveyQuestion
                    AND question_id={?}
               ORDER BY RAND()
                  LIMIT 5;';
-        return $sql;
+        $res = XDB::query($sql, $sid, $qid);
+        return $res->fetchAllAssoc();
     }
 }
 // }}}
@@ -605,7 +609,7 @@ abstract class SurveyList extends SurveyQuestion
     {
         parent::update($args);
         $this->choices = array();
-        foreach ($args['options'] as $val) {
+        foreach ($args['choices'] as $val) {
             if (trim($val) || trim($val) == '0') {
                 $this->choices[] = $val;
             }
@@ -619,14 +623,15 @@ abstract class SurveyList extends SurveyQuestion
         return $rArr;
     }
 
-    public function buildResultRequest()
+    public function getResultArray($sid, $qid)
     {
         $sql = 'SELECT answer, COUNT(id) AS count
                   FROM survey_answers
                  WHERE vote_id IN (SELECT id FROM survey_votes WHERE survey_id={?})
                    AND question_id={?}
               GROUP BY answer ASC';
-        return $sql;
+        $res = XDB::query($sql, $sid, $qid);
+        return $res->fetchAllAssoc();
     }
 
     public function getCSVColumn()
@@ -650,7 +655,8 @@ class SurveyRadio extends SurveyList
 {
     public function checkAnswer($ans)
     {
-        return (array_key_exists($ans, $this->choices))? array($ans) : null;
+        $a = intval($ans);
+        return (array_key_exists($a, $this->choices))? array($a) : null;
     }
 
     protected function getQuestionType()
@@ -683,5 +689,125 @@ class SurveyCheckbox extends SurveyList
 // }}}
 // }}}
 
+// {{{ abstract class SurveyTable and its derived classes : table question, each column represents a choice, each line represents a question
+// {{{ abstract class SurveyTable extends SurveyList
+abstract class SurveyTable extends SurveyList
+{
+    protected $subquestions;
+
+    public function update($args)
+    {
+        parent::update($args);
+        $this->subquestions = array();
+        foreach ($args['subquestions'] as $val) {
+            if (trim($val) || trim($val) == '0') {
+                $this->subquestions[] = $val;
+            }
+        }
+    }
+
+    public function toArray()
+    {
+        $rArr = parent::toArray();
+        $rArr['subquestions'] = $this->subquestions;
+        return $rArr;
+    }
+
+    public function getResultArray($sid, $qid)
+    {
+        $sql = 'SELECT answer, COUNT(id) AS count
+                  FROM survey_answers
+                 WHERE vote_id IN (SELECT id FROM survey_votes WHERE survey_id={?})
+                   AND question_id={?}
+              GROUP BY answer ASC';
+        $res = XDB::iterator($sql, $sid, $qid);
+        $result = array();
+        for ($i = 0; $i < count($this->subquestions); $i++) {
+            $result[$i] = array_fill(0, count($this->choices), 0);
+        }
+        while ($r = $res->next()) {
+            list($i, $j) = explode(':', $r['answer']);
+            $result[$i][$j] = $r['count'];
+        }
+        return $result;
+    }
+
+    public function getCSVColumn()
+    {
+        $r = $this->getQuestion() . ' (format "sous-question:choix") ';
+        if (!empty($this->subquestions)) {
+            $r .= ' [sous-questions : 0 =>'.$this->subquestions[0];
+            for ($k = 1; $k < count($this->subquestions); $k++) {
+                $r .= ', '.$k.' => '.$this->subquestions[$k];
+            }
+            $r .= ']';
+        }
+        if (!empty($this->choices)) {
+            $r .= ' [choix : 0 => '.$this->choices[0];
+            for ($k = 1; $k < count($this->choices); $k++) {
+                $r .= ', '.$k.' => '.$this->choices[$k];
+            }
+            $r .= ']';
+        }
+        return $r;
+    }
+}
+// }}}
+
+// {{{ class SurveyRadioTable extends SurveyTable : SurveyTable with radio type choices
+class SurveyRadioTable extends SurveyTable
+{
+    public function checkAnswer($ans)
+    {
+        $rep = array();
+        foreach ($ans as $k => $a) {
+            if (!array_key_exists($k, $this->subquestions)) {
+                continue;
+            }
+            $a = intval($a);
+            if (array_key_exists($a, $this->choices)) {
+                $rep[] = $k . ':' . $a;
+            }
+        }
+        return (count($rep) == 0)? null : $rep;
+    }
+
+    protected function getQuestionType()
+    {
+        return "radiotable";
+    }
+
+}
+// }}}
+
+// {{{ class SurveyCheckboxTable extends SurveyTable : SurveyTable with checkbox type choices
+class SurveyCheckboxTable extends SurveyTable
+{
+    public function checkAnswer($ans)
+    {
+        $rep = array();
+        foreach ($ans as $k => $aa) {
+            if (!array_key_exists($k, $this->subquestions)) {
+                continue;
+            }
+            foreach ($aa as $a) {
+                $a = intval($a);
+                if (array_key_exists($a, $this->choices)) {
+                    $rep[] = $k . ':' . $a;
+                }
+            }
+        }
+        return (count($rep) == 0)? null : $rep;
+    }
+
+    protected function getQuestionType()
+    {
+        return "checkboxtable";
+    }
+
+}
+// }}}
+// }}}
+
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>
diff --git a/templates/survey/edit_checkboxtable.tpl b/templates/survey/edit_checkboxtable.tpl
new file mode 100644 (file)
index 0000000..a5dfb56
--- /dev/null
@@ -0,0 +1,25 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2007 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+{include file='survey/edit_radiotable.tpl'}
+
+{* vim:set et sw=2 sts=2 ts=8 enc=utf-8: *}
index dfe81e1..41527ed 100644 (file)
     </tr>
     {javascript name=jquery} 
     <script type="text/javascript">//<![CDATA[ 
-      var id = {$survey_current.choices|@count};
+      var id = new Array();
+      id['choices'] = {$survey_current.choices|@count};
+      id['subquestions'] = {$survey_current.subquestions|@count};
       {literal}
-      function newChoice(tid)
+      function newField(name, tid)
       {
-        fid = "t" + id;
-        $("#choice_" + tid).before('<div id="choice_' + fid + '">' 
-            + '<input type="text" name="survey_question[options][' + fid + ']" size="50" maxlength="200" value="" />&nbsp;'
-            + '<a href="javascript:removeChoice(&quot;' + fid + '&quot;)"><img src="images/icons/delete.gif" alt="" title="Supprimer" /></a>'
+        fid = "t" + id[name];
+        $("#" + name + "_" + tid).before('<div id="' + name + '_' + fid + '">' 
+            + '<input id="' + name + '_' + fid + '_field" type="text" name="survey_question[' + name + '][' + fid + ']" size="50" maxlength="200" value="" />&nbsp;'
+            + '<a href="javascript:removeField(&quot;' + name + '&quot;, &quot;' + fid + '&quot;)"><img src="images/icons/delete.gif" alt="" title="Supprimer" /></a>'
             + '</div>'); 
-        id++; 
+        id[name]++; 
+        $("#" + name + "_" + fid + "_field").focus();
       }
-      function removeChoice(tid)
+      function removeField(name, tid)
       {
-        $("#choice_" + tid).remove();
+        $("#" + name + "_" + tid).remove();
       }
       {/literal} 
     //]]></script> 
index d748420..2e5b206 100644 (file)
       <td class="titre">Choix</td>
       <td>
         {foreach from=$survey_current.choices key=value item=choice}
-        <div id="choice_t{$value}">
-          <input type="text" name="survey_question[options][t{$value}]" size="50" maxlength="200" value="{$choice}" />
-          <a href="javascript:removeChoice('t{$value}')">{icon name=delete title="Supprimer"}</a>
+        <div id="choices_t{$value}">
+          <input type="text" name="survey_question[choices][t{$value}]" size="50" maxlength="200" value="{$choice}" />
+          <a href="javascript:removeField('choices', 't{$value}')">{icon name=delete title="Supprimer"}</a>
         </div>
         {/foreach}
-        <div id="choice_last">
-          <a href="javascript:newChoice('last')">{icon name=add}</a>
+        <div id="choices_last">
+          <a href="javascript:newField('choices', 'last')">{icon name=add}</a>
         </div>
       </td>
     </tr>
diff --git a/templates/survey/edit_radiotable.tpl b/templates/survey/edit_radiotable.tpl
new file mode 100644 (file)
index 0000000..048f89e
--- /dev/null
@@ -0,0 +1,39 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2007 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+{include file='survey/edit_radio.tpl'}
+    <tr>
+      <td class="titre">Sous-questions</td>
+      <td>
+        {foreach from=$survey_current.subquestions key=value item=subquestion}
+        <div id="subquestions_t{$value}">
+          <input type="text" name="survey_question[subquestions][t{$value}]" size="50" maxlength="200" value="{$subquestion}" />
+          <a href="javascript:removeField('subquestions', 't{$value}')">{icon name=delete title="Supprimer"}</a>
+        </div>
+        {/foreach}
+        <div id="subquestions_last">
+          <a href="javascript:newField('subquestions', 'last')">{icon name=add}</a>
+        </div>
+      </td>
+    </tr>
+
+{* vim:set et sw=2 sts=2 ts=8 enc=utf-8: *}
index 32181c2..d4b06a5 100644 (file)
@@ -22,9 +22,9 @@
 
 {if $survey_resultmode}
   <ul>
-  {iterate item=sresult from=$squestion.result}
+  {foreach item=sresult from=$squestion.result}
     <li>{$squestion.choices[$sresult.answer]} : {$sresult.count*100/$survey.votes|string_format:"%.1f"}% ({$sresult.count} votes)</li>
-  {/iterate}
+  {/foreach}
   </ul>
 {else}
   {assign var=sid value=$survey.id}
diff --git a/templates/survey/show_checkboxtable.tpl b/templates/survey/show_checkboxtable.tpl
new file mode 100644 (file)
index 0000000..9c24e4d
--- /dev/null
@@ -0,0 +1,51 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2007 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<table class="bicol">
+  <tr class="pair">
+    <td></td>
+  {foreach from=$squestion.choices item=schoice}
+    <td>{$schoice}</td>
+  {/foreach}
+  </tr>
+{foreach from=$squestion.subquestions item=ssubq key=ssqid}
+  <tr class="{cycle values="impair,pair"}">
+    <td>{$ssubq}</td>
+  {assign var=sid value=$survey.id}
+  {assign var=sqid value=$squestion.id}
+  {if $survey_resultmode}
+    {foreach from=$squestion.choices item=schoice key=value}
+    <td>
+      {$squestion.result.$ssqid.$value*100/$survey.votes|string_format:"%.1f"}% ({$squestion.result.$ssqid.$value} votes)
+    </td>
+    {/foreach}
+  {else}
+    {foreach from=$squestion.choices item=schoice key=value}
+    <td>
+      <label><input type="checkbox" name="survey{$sid}[{$sqid}][{$ssqid}][]" value="{$value}" {if !$survey_votemode}disabled="disabled" {/if}/></label>
+    </td>
+    {/foreach}
+  {/if}
+{/foreach}
+</table>
+
+{* vim:set et sw=2 sts=2 ts=8 enc=utf-8: *}
index 5ac0a87..02dd20c 100644 (file)
@@ -22,9 +22,9 @@
 
 {if $survey_resultmode}
   <ul>
-  {iterate item=sresult from=$squestion.result}
+  {foreach item=sresult from=$squestion.result}
     <li>{$squestion.choices[$sresult.answer]} : {$sresult.count*100/$survey.votes|string_format:"%.1f"}% ({$sresult.count} votes)</li>
-  {/iterate}
+  {/foreach}
   </ul>
 {else}
   {assign var=sid value=$survey.id}
diff --git a/templates/survey/show_radiotable.tpl b/templates/survey/show_radiotable.tpl
new file mode 100644 (file)
index 0000000..39448cf
--- /dev/null
@@ -0,0 +1,51 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2007 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<table class="bicol">
+  <tr class="pair">
+    <td></td>
+  {foreach from=$squestion.choices item=schoice}
+    <td>{$schoice}</td>
+  {/foreach}
+  </tr>
+{foreach from=$squestion.subquestions item=ssubq key=ssqid}
+  <tr class="{cycle values="impair,pair"}">
+    <td>{$ssubq}</td>
+  {assign var=sid value=$survey.id}
+  {assign var=sqid value=$squestion.id}
+  {if $survey_resultmode}
+    {foreach from=$squestion.choices item=schoice key=value}
+    <td>
+      {$squestion.result.$ssqid.$value*100/$survey.votes|string_format:"%.1f"}% ({$squestion.result.$ssqid.$value} votes)
+    </td>
+    {/foreach}
+  {else}
+    {foreach from=$squestion.choices item=schoice key=value}
+    <td>
+      <label><input type="radio" name="survey{$sid}[{$sqid}][{$ssqid}]" value="{$value}" {if !$survey_votemode}disabled="disabled" {/if}/></label>
+    </td>
+    {/foreach}
+  {/if}
+{/foreach}
+</table>
+
+{* vim:set et sw=2 sts=2 ts=8 enc=utf-8: *}
index fb5710d..b44d1fa 100644 (file)
@@ -23,9 +23,9 @@
 {if $survey_resultmode}
   Quelques r&#233;ponses donn&#233;es par les personnes sond&#233;es :
   <ul>
-  {iterate item=sresult from=$squestion.result}
+  {foreach item=sresult from=$squestion.result}
     <li>{$sresult.answer}</li>
-  {/iterate}
+  {/foreach}
   </ul>
 {else}
   <input type="text" name="survey{$survey.id}[{$squestion.id}]" value="" size="50" maxlength="200" {if !$survey_votemode}disabled="disabled"{/if}/>
index 88a42b4..aca9599 100644 (file)
@@ -23,9 +23,9 @@
 {if $survey_resultmode}
   Quelques r&#233;ponses donn&#233;es par les personnes sond&#233;es :
   <ul>
-  {iterate item=sresult from=$squestion.result}
+  {foreach item=sresult from=$squestion.result}
     <li>{$sresult.answer}</li>
-  {/iterate}
+  {/foreach}
   </ul>
 {else}
   <textarea name="survey{$survey.id}[{$squestion.id}]" rows="5" cols="60" {if !$survey_votemode}disabled="disabled"{/if}></textarea>