5 * Copyright 2004, Sung Kim/GForge, LLC
6 * Copyright 2009, Roland Mas
7 * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
8 * http://fusionforge.org
10 * This file is part of FusionForge. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 require_once $gfcommon.'include/FFError.class.php';
27 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
29 $SURVEY_OBJ = array();
32 * survey_get_object() - Get the survey object.
34 * survey_get_object() is useful so you can pool survey objects/save database queries
35 * You should always use this instead of instantiating the object directly.
37 * You can now optionally pass in a db result handle. If you do, it re-uses that query
38 * to instantiate the objects.
40 * IMPORTANT! That db result must contain all fields
41 * from surveys table or you will have problems
43 * @param int $survey_id Required
44 * @param int|bool $res Result set handle ("SELECT * FROM surveys WHERE survey_id = xx")
45 * @return Survey|bool A survey object or false on failure
47 function &survey_get_object($survey_id, $res = false) {
49 if (!isset($SURVEY_OBJ["_".$survey_id."_"])) {
51 //the db result handle was passed in
53 $res = db_query_params('SELECT * FROM surveys WHERE survey_id=$1', array($survey_id));
55 if (!$res || db_numrows($res) < 1) {
56 $SURVEY_OBJ["_".$survey_id."_"] = false;
58 $arr = db_fetch_array($res);
59 $groupObject = group_get_object($arr['group_id']);
60 $SURVEY_OBJ["_".$survey_id."_"] = new Survey($groupObject, $survey_id, $arr);
63 return $SURVEY_OBJ["_".$survey_id."_"];
66 class Survey extends FFError {
69 * Associative array of data from db.
71 * @var array $data_array.
76 * Questions array in this survey
78 * @var array $question_array.
80 var $all_question_array;
91 * @param bool $survey_id
94 function __construct(&$Group, $survey_id = false, $arr = false) {
95 parent::__construct();
96 if (!$Group || !is_object($Group)) {
97 $this->setError(_('Invalid Project'));
100 if ($Group->isError()) {
101 $this->setError('Survey: '.$Group->getErrorMessage());
104 $this->Group =& $Group;
107 if (!$arr || !is_array($arr)) {
108 if (!$this->fetchData($survey_id)) {
112 $this->data_array =& $arr;
113 if ($this->data_array['group_id'] != $this->Group->getID()) {
114 $this->setError(_('group_id in db result does not match Group Object'));
115 $this->data_array = null;
123 * create - use this function to create a survey
125 * @param string $survey_title The survey title
126 * @param array $add_questions The question numbers to be added
127 * @param int $is_active 1: Active, 0: Inactive
128 * @param int $is_public
129 * @param int $is_result_public
130 * @param int $double_vote
131 * @return bool success.
133 function create($survey_title, $add_questions, $is_active = 0, $is_public = 1, $is_result_public = 0, $double_vote = 0) {
134 if (!$survey_title) {
135 $this->setError(_('Update Failed: Survey Title Required'));
137 /* We need at least one survey question at this point */
138 } elseif (!$add_questions || !is_array($add_questions) || count($add_questions)<1) {
139 $this->setError(_('Update Failed: Survey Questions Required'));
143 $group_id = $this->Group->GetID();
145 /* Make old style survey string from array: 1, 2, 3, ..., n */
146 $survey_questions = $this->_makeQuestionString($add_questions);
148 $result = db_query_params('INSERT INTO surveys (survey_title,group_id,survey_questions,is_active) VALUES ($1,$2,$3,$4)',
149 array(htmlspecialchars($survey_title),
155 $this->setError(_('Insert Error').db_error());
159 /* Load question to data array */
160 $survey_id=db_insertid($result,'surveys','survey_id');
161 return $this->fetchData($survey_id);
165 * update - use this function to update a survey
167 * @param string $survey_title The survey title
168 * @param array $add_questions The question numbers to be added
169 * @param array $del_questions The question numbers to be deleted
170 * @param int $is_active 1: Active, 0: Inactive
171 * @param int $is_public
172 * @param int $is_result_public
173 * @param int $double_vote
174 * @return bool success.
176 function update($survey_title, &$add_questions, &$del_questions, $is_active = 0, $is_public = 1, $is_result_public = 0, $double_vote = 0) {
177 if (!$survey_title) {
178 $this->setError(_('Update Failed: Survey Title Required'));
180 /* We need at least one survey question at this point */
183 $group_id = $this->Group->GetID();
184 $survey_id = $this->getID();
186 /* Ths Survey is not ready to update */
188 $this->setError(_('The Survey data is not filled'));
192 $survey_questions = $this->_updateQuestionString($add_questions, $del_questions);
193 $result = db_query_params('UPDATE surveys SET survey_title=$1, survey_questions=$2, is_active=$3 WHERE survey_id=$4 AND group_id=$5',
194 array (htmlspecialchars($survey_title),
200 if (db_affected_rows($result) < 1) {
201 $this->setError(_('Update failed').db_error());
204 /* Update internal data */
205 return $this->fetchData($survey_id);
209 * updateOrder - use this function to update question order
211 * @param int $question_number Question number
212 * @param bool $is_up decide up or down. it is up if it is true
213 * @return bool success.
215 function updateOrder($question_number, $is_up = true) {
216 $group_id = $this->Group->GetID();
217 $survey_id = $this->getID();
219 /* Ths Survey is not ready to update */
221 $this->setError(_('The Survey data is not filled'));
232 $survey_questions = $this->_updateQuestionStringOrder($question_number, $delta);
233 $result = db_query_params('UPDATE surveys SET survey_questions=$1 WHERE survey_id=$2 AND group_id=$3',
234 array ($survey_questions,
238 if (db_affected_rows($result) < 1) {
239 $this->setError(_('Update failed').db_error());
243 /* Update internal data */
244 return $this->fetchData($survey_id);
248 * delete - use this function to delete this survey
249 * (We don't support delete yet)
251 * @return bool success.
254 $group_id = $this->Group->GetID();
255 $survey_id = $this->getID();
257 $res = db_query_params('DELETE FROM surveys where survey_id=$1 AND group_id=$2',
258 array($survey_id, $group_id)
260 if (!$res || db_affected_rows($res) < 1) {
261 $this->setError(_('Delete failed').db_error());
265 /* Delete internal data */
266 $this->data_array = null;
271 * fetchData - re-fetch the data for this survey from the database.
273 * @param int $survey_id The survey_id.
274 * @return bool success.
276 function fetchData($survey_id) {
277 $group_id = $this->Group->GetID();
279 $res = db_query_params('SELECT * FROM surveys where survey_id=$1 AND group_id=$2',
280 array($survey_id, $group_id)) ;
282 if (!$res || db_numrows($res) < 1) {
283 $this->setError(_('No Survey is found').db_error());
286 $this->data_array = db_fetch_array($res);
287 db_free_result($res);
292 * getGroup - get the Group object this Survey is associated with.
294 * @return object The Group object.
296 function &getGroup() {
301 * getID - Get the id of this Survey
303 * @return int The question_id
306 return $this->data_array['survey_id'];
310 * isActive - return if it is active
312 * @return int is active
314 function isActive() {
315 return $this->data_array['is_active'];
319 * getTitle - Get the Survey title
321 * @return string the survey title
323 function getTitle() {
324 return $this->data_array['survey_title'];
328 * getQuestionString - Get the question string
330 * @return string the question
332 function getQuestionString() {
333 return $this->data_array['survey_questions'];
337 * getNumberOfQuestion - Get the number of questions
339 * @return int the number questions
341 function getNumberOfQuestions() {
342 return count($this->getQuestionArray());
346 * getNumberOfVotes - Get the number of votes
348 * @return int the number votes
350 function getNumberOfVotes() {
351 $group_id = $this->Group->GetID();
352 $survey_id = $this->getID();
354 $res = db_query_params ('SELECT 1 FROM survey_responses WHERE survey_id=$1 AND group_id=$2 GROUP BY user_id',
357 $ret = db_numrows($res);
358 db_free_result($res);
364 * isUserVote - Figure out the user voted or not
366 * @param int $user_id
367 * @return true or false
369 function isUserVote($user_id) {
370 $group_id = $this->Group->GetID();
371 $survey_id = $this->getID();
373 $res = db_query_params ('SELECT 1 FROM survey_responses where survey_id=$1 AND group_id=$2 AND user_id=$3',
377 $ret = db_numrows($res);
378 db_free_result($res);
384 * getQuestionArray - Get the question string numbers in array
386 * @return string the question
388 function &getQuestionArray() {
390 $questions = $this->getQuestionString();
395 $arr_from_str = explode(',', $questions);
397 /* Remove non existed questions */
398 for ($i=0; $i<count($arr_from_str); $i++) {
399 if ($this->_isValidQuestionID($arr_from_str[$i])) {
400 $ret_arr[] = $arr_from_str[$i];
408 * getQuestionInstances - Get the SurveyQuestion array belongs to this Survey by order
410 * @return string the question
412 function &getQuestionInstances() {
415 if (!$this->all_question_array || !is_array($this->all_question_array)) {
416 $this->_fillSurveyQuestions();
419 $arr = & $this->getQuestionArray();
421 for ($i=0; $i<count($arr); $i++) {
422 for ($j=0; $j<count($this->all_question_array); $j++) {
423 /* If it is, copy into new array in order */
424 if ($this->all_question_array[$j]->getID()==$arr[$i]) {
425 $ret[] = $this->all_question_array[$j];
435 * getAddableQuestionInstances - Get the addable SurveyQuestion from all questions
437 * @return string the question
439 function &getAddableQuestionInstances() {
442 if (!$this->all_question_array || !is_array($this->all_question_array)) {
443 $this->_fillSurveyQuestions();
446 $arr = & $this->getQuestionArray();
448 /* Copy questions only if it is not in question string */
449 for ($i=0; $i<count($this->all_question_array); $i++) {
450 if (array_search($this->all_question_array[$i]->getID(), $arr) == false &&
451 $this->all_question_array[$i]->getID()!=$arr[0]) {
452 $ret[] = $this->all_question_array[$i];
456 $ret = $this->all_question_array;
462 /***************************************************************
463 * private question string deal methods
464 * TODO: Add a joint table for surveys and survey_questions.
465 * Deal with DBMS not comma separated string
466 ***************************************************************/
469 * _fillSurveyQuestions - Get all Survey Questions using SurveyQuestionFactory
471 * @return bool success
473 function _fillSurveyQuestions() {
474 $sqf = new SurveyQuestionFactory($this->getGroup());
475 $this->all_question_array = & $sqf->getSurveyQuestions();
479 * _isValidQuestionID - Check it is correct question id
481 * @param int $question_id question id
482 * @return bool true if it is valid question id
484 function _isValidQuestionID($question_id) {
485 if (!$this->all_question_array || !is_array($this->all_question_array)) {
486 $this->_fillSurveyQuestions();
489 for ($i=0; $i<count($this->all_question_array); $i++) {
490 if ($question_id == $this->all_question_array[$i]->getID()) {
498 * _makeQuestionString - Make comma separated question number string
500 * @param int $arr array Array of question number
501 * @return string question_strong (example: 1, 2, 3, 7);
503 function _makeQuestionString($arr) {
505 /* No questions to add */
506 if (!$arr || !is_array($arr) || count($arr)<1) {
509 return join(',', $arr);
513 * _updateQuestionString - Update comma separated question number string
515 * @param int array Array of questions to add
516 * @param int array Array of questions to delete
517 * @return string question_strong (example: 1, 2, 3, 7);
519 function _updateQuestionString(&$arr_to_add, &$arr_to_del) {
520 /* Get array of current question string */
521 $arr = & $this->getQuestionArray();
523 /* questions to add */
527 if ($arr_to_add && is_array($arr_to_add) && !empty($arr_to_add)) {
528 for ($i = 0; $i < count($arr_to_add); $i++) {
529 /* Avoid double question */
530 if ($arr_to_add[$i] && array_search($arr_to_add[$i], $arr) == false && $arr_to_add[$i]!=$arr[0]) {
531 $arr[] = $arr_to_add[$i];
537 /* questions to delete */
538 if ($arr_to_del && is_array($arr_to_del) && !empty($arr_to_del)) {
540 for ($i = 0; $i < count($arr); $i++) {
541 /* If the value is no in the delete array, copy it into new array */
542 if ($arr[$i] && array_search($arr[$i], $arr_to_del)==false && $arr_to_del[0]!=$arr[$i]) {
543 $new_arr[] = $arr[$i];
546 /* copy new_arr to arr */
550 /* convert array to String */
551 return $this->_makeQuestionString($arr);
555 * _updateArrayOrder - Update array order
557 * @param int $question_number
558 * @param int $delta increment or decrement (must be 1 or -1)
559 * @return string question_strong (example: 1, 2, 3, 7);
561 function _updateQuestionStringOrder($question_number, $delta) {
562 /* Get array of current question string */
563 $arr = & $this->getQuestionArray();
565 /* We are expecting array */
566 if (!$arr || !is_array($arr)) {
567 return $this->getQuestionString();
570 $index = array_search($question_number, $arr);
572 /* The question number is not in the array
573 * We have nothing to change
575 if ($index==false && $question_number!=$arr[0]) {
576 return $this->getQuestionString();
579 $new_index = $index + $delta;
581 /* Out of boundary */
582 if ($new_index < 0 || $new_index >= count($arr)) {
583 return $this->getQuestionString();
588 $arr[$index] = $arr[$new_index];
589 $arr[$new_index] = $tmp;
591 /* convert array to String */
592 return $this->_makeQuestionString($arr);
598 // c-file-style: "bsd"