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/Error.class.php';
27 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
29 class Survey extends Error {
32 * Associative array of data from db.
34 * @var array $data_array.
39 * Questions array in this survey
41 * @var array $question_array.
43 var $all_question_array;
55 * @param object The Group object to which this servey is associated.
56 * @param int The servey_id.
57 * @param array The associative array of data.
58 * @return boolean success.
60 function __construct(&$Group, $survey_id = false, $arr = false) {
62 if (!$Group || !is_object($Group)) {
63 $this->setError(sprintf(_('%1$s:: No Valid Group Object'), "Survey"));
66 if ($Group->isError()) {
67 $this->setError('Survey:: '.$Group->getErrorMessage());
70 $this->Group =& $Group;
73 if (!$arr || !is_array($arr)) {
74 if (!$this->fetchData($survey_id)) {
78 $this->data_array =& $arr;
79 if ($this->data_array['group_id'] != $this->Group->getID()) {
80 $this->setError(_('Group_id in db result does not match Group Object'));
81 $this->data_array = null;
89 * create - use this function to create a survey
91 * @param string The survey title
92 * @param int array The question numbers to be added
93 * @param is_active 1: Active, 0: Inactive
95 * @param is_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:Every body
96 * @param is_result_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:voted user 4:Every body
97 * @param double_vote Allow double vote if it is 1
98 * @return boolean success.
100 function create($survey_title, $add_questions, $is_active = 0, $is_public = 1, $is_result_public = 0, $double_vote = 0) {
101 if (!$survey_title) {
102 $this->setError(_('Update Failed: Survey Title Required'));
104 /* We need at least one survey question at this point */
105 } else if (!$add_questions || !is_array($add_questions) || count($add_questions)<1) {
106 $this->setError(_('Update Failed: Survey Questions Required'));
110 $group_id = $this->Group->GetID();
112 /* Make old style survey string from array: 1, 2, 3, ..., n */
113 $survey_questions = $this->_makeQuestionString($add_questions);
115 $result = db_query_params('INSERT INTO surveys (survey_title,group_id,survey_questions,is_active) VALUES ($1,$2,$3,$4)',
116 array(htmlspecialchars($survey_title),
122 $this->setError(_('Insert Error').db_error());
126 /* Load question to data array */
127 $survey_id=db_insertid($result,'surveys','survey_id');
128 return $this->fetchData($survey_id);
134 * update - use this function to update a survey
136 * @param string The survey title
137 * @param int array The question numbers to be added
138 * @param int array The question numbers to be deleted
139 * @param is_active 1: Active, 0: Inactive
140 * @param is_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:Every body
141 * @param is_result_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:voted user 4:Every body
142 * @param double_vote Allow double vote if it is 1
143 * @return boolean success.
145 function update($survey_title, &$add_questions, &$del_questions, $is_active = 0, $is_public = 1, $is_result_public = 0, $double_vote = 0) {
146 if (!$survey_title) {
147 $this->setError(_('Update Failed: Survey Title Required'));
149 /* We need at least one survey question at this point */
152 $group_id = $this->Group->GetID();
153 $survey_id = $this->getID();
155 /* Ths Survey is not ready to update */
157 $this->setError(_('The Survey data is not filled'));
161 $survey_questions = $this->_updateQuestionString($add_questions, $del_questions);
162 $result = db_query_params('UPDATE surveys SET survey_title=$1, survey_questions=$2, is_active=$3 WHERE survey_id=$4 AND group_id=$5',
163 array (htmlspecialchars($survey_title),
169 if (db_affected_rows($result) < 1) {
170 $this->setError(_('UPDATE FAILED').db_error());
173 /* Update internal data */
174 return $this->fetchData($survey_id);
178 * updateOrder - use this function to update question order
180 * @param int Question number
181 * @param boolean decide up or down. it is up if it is true
182 * @return boolean success.
184 function updateOrder($question_number, $is_up = true) {
185 $group_id = $this->Group->GetID();
186 $survey_id = $this->getID();
188 /* Ths Survey is not ready to update */
190 $this->setError(_('The Survey data is not filled'));
201 $survey_questions = $this->_updateQuestionStringOrder($question_number, $delta);
202 $result = db_query_params('UPDATE surveys SET survey_questions=$1 WHERE survey_id=$2 AND group_id=$3',
203 array ($survey_questions,
207 if (db_affected_rows($result) < 1) {
208 $this->setError(_('UPDATE FAILED').db_error());
212 /* Update internal data */
213 return $this->fetchData($survey_id);
217 * delete - use this function to delete this survey
218 * (We don't support delete yet)
220 * @return boolean success.
223 $group_id = $this->Group->GetID();
224 $survey_id = $this->getID();
226 $res = db_query_params('DELETE FROM surveys where survey_id=$1 AND group_id=$2',
227 array($survey_id, $group_id)
229 if (!$res || db_affected_rows($res) < 1) {
230 $this->setError(_('Delete failed').db_error());
234 /* Delete internal data */
235 $this->data_array = null;
240 * fetchData - re-fetch the data for this survey from the database.
242 * @param int The survey_id.
243 * @return boolean success.
245 function fetchData($survey_id) {
246 $group_id = $this->Group->GetID();
248 $res = db_query_params('SELECT * FROM surveys where survey_id=$1 AND group_id=$2',
249 array($survey_id, $group_id)) ;
251 if (!$res || db_numrows($res) < 1) {
252 $this->setError(_('No Survey is found').db_error());
255 $this->data_array = db_fetch_array($res);
256 db_free_result($res);
261 * getGroup - get the Group object this Survey is associated with.
263 * @return object The Group object.
265 function &getGroup() {
270 * getID - Get the id of this Survey
272 * @return int The question_id
275 return $this->data_array['survey_id'];
279 * isActriv - return if it is active
281 * @return int is active
283 function isActive() {
284 return $this->data_array['is_active'];
288 * getTitle - Get the Survey title
290 * @return string the survey title
292 function getTitle() {
293 return $this->data_array['survey_title'];
297 * getQuestionString - Get the question string
299 * @return string the question
301 function getQuestionString() {
302 return $this->data_array['survey_questions'];
306 * getNumberOfQuestion - Get the number of questions
308 * @return int the number questions
310 function getNumberOfQuestions() {
311 return count($this->getQuestionArray());
315 * getNumberOfVotes - Get the number of votes
317 * @return int the number votes
319 function getNumberOfVotes() {
320 $group_id = $this->Group->GetID();
321 $survey_id = $this->getID();
323 $res = db_query_params ('SELECT 1 FROM survey_responses WHERE survey_id=$1 AND group_id=$2 GROUP BY user_id',
326 $ret = db_numrows($res);
327 db_free_result($res);
333 * isUserVote - Figure out the user voted or not
336 * @return true of false
338 function isUserVote($user_id) {
339 $group_id = $this->Group->GetID();
340 $survey_id = $this->getID();
342 $res = db_query_params ('SELECT 1 FROM survey_responses where survey_id=$1 AND group_id=$2 AND user_id=$3',
346 $ret = db_numrows($res);
347 db_free_result($res);
353 * getQuestionArray - Get the question string numbers in array
355 * @return string the question
357 function &getQuestionArray() {
359 $questions = $this->getQuestionString();
364 $arr_from_str = explode(',', $questions);
366 /* Remove non existed questions */
367 for ($i=0; $i<count($arr_from_str); $i++) {
368 if ($this->_isValidQuestionID($arr_from_str[$i])) {
369 $ret_arr[] = $arr_from_str[$i];
377 * getQuestionInstances - Get the SurveyQuestion array belongs to this Survey by order
379 * @return string the question
381 function &getQuestionInstances() {
384 if (!$this->all_question_array || !is_array($this->all_question_array)) {
385 $this->_fillSurveyQuestions();
388 $arr = & $this->getQuestionArray();
390 for ($i=0; $i<count($arr); $i++) {
391 for ($j=0; $j<count($this->all_question_array); $j++) {
392 /* If it is, copy into new array in order */
393 if ($this->all_question_array[$j]->getID()==$arr[$i]) {
394 $ret[] = $this->all_question_array[$j];
404 * getAddableQuestionInstances - Get the addable SurveyQuestion from all questions
406 * @return string the question
408 function &getAddableQuestionInstances() {
411 if (!$this->all_question_array || !is_array($this->all_question_array)) {
412 $this->_fillSurveyQuestions();
415 $arr = & $this->getQuestionArray();
417 /* Copy questions only if it is not in question string */
418 for ($i=0; $i<count($this->all_question_array); $i++) {
419 if (array_search($this->all_question_array[$i]->getID(), $arr) == false &&
420 $this->all_question_array[$i]->getID()!=$arr[0]) {
421 $ret[] = $this->all_question_array[$i];
425 $ret = $this->all_question_array;
431 /***************************************************************
432 * private question string deal methods
433 * TODO: Add a joint table for surveys and survey_questions.
434 * Deal with DBMS not comma separated string
435 ***************************************************************/
438 * _fillSurveyQuestions - Get all Survey Questions using SurveyQuestionFactory
440 * @return boolean success
442 function _fillSurveyQuestions() {
443 $sqf = new SurveyQuestionFactory($this->getGroup());
444 $this->all_question_array = & $sqf->getSurveyQuestions();
449 * _isValidQuestionID - Check it is correct question id
451 * @param int questioin id
452 * @return boolean true if it is valid question id
454 function _isValidQuestionID($question_id) {
455 if (!$this->all_question_array || !is_array($this->all_question_array)) {
456 $this->_fillSurveyQuestions();
459 for ($i=0; $i<count($this->all_question_array); $i++) {
460 if ($question_id == $this->all_question_array[$i]->getID()) {
469 * _makeQuestionString - Make comma separated question number string
471 * @param int array Array of question number
472 * @return string question_strong (example: 1, 2, 3, 7);
474 function _makeQuestionString($arr) {
476 /* No questions to add */
477 if (!$arr || !is_array($arr) || count($arr)<1) {
480 return join(',', $arr);
484 * _updateQuestionString - Update comma saparated question number string
486 * @param int array Array of questions to add
487 * @param int array Array of questions to delete
488 * @return string question_strong (example: 1, 2, 3, 7);
490 function _updateQuestionString(&$arr_to_add, &$arr_to_del) {
491 /* Get array of current question string */
492 $arr = & $this->getQuestionArray();
494 /* questions to add */
498 if ($arr_to_add && is_array($arr_to_add) && count($arr_to_add)>0) {
499 for ($i = 0; $i < count($arr_to_add); $i++) {
500 /* Avoid double question */
501 if ($arr_to_add[$i] && array_search($arr_to_add[$i], $arr) == false && $arr_to_add[$i]!=$arr[0]) {
502 $arr[] = $arr_to_add[$i];
508 /* questions to delete */
509 if ($arr_to_del && is_array($arr_to_del) && count($arr_to_del)>0) {
511 for ($i = 0; $i < count($arr); $i++) {
512 /* If the value is no in the delete array, copy it into new array */
513 if ($arr[$i] && array_search($arr[$i], $arr_to_del)==false && $arr_to_del[0]!=$arr[$i]) {
514 $new_arr[] = $arr[$i];
517 /* copy new_arr to arr */
521 /* converty array to String */
522 return $this->_makeQuestionString($arr);
526 * _updateArrayOrder - Update array order
528 * @param int question number
529 * @param int increment or decrement (must be 1 or -1)
530 * @return string question_strong (example: 1, 2, 3, 7);
532 function _updateQuestionStringOrder($question_number, $delta) {
533 /* Get array of current question string */
534 $arr = & $this->getQuestionArray();
536 /* We are expectiong array */
537 if (!$arr || !is_array($arr)) {
538 return $this->getQuestionString();
541 $index = array_search($question_number, $arr);
543 /* The question number is not in the array
544 * We have nothing to change
546 if ($index==false && $question_number!=$arr[0]) {
547 return $this->getQuestionString();
550 $new_index = $index + $delta;
552 /* Out of boundary */
553 if ($new_index < 0 || $new_index >= count($arr)) {
554 return $this->getQuestionString();
559 $arr[$index] = $arr[$new_index];
560 $arr[$new_index] = $tmp;
562 /* converty array to String */
563 return $this->_makeQuestionString($arr);
569 // c-file-style: "bsd"