5 * Copyright 2004, Sung Kim/GForge, LLC
6 * Copyright 2009, Roland Mas
8 * This file is part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published
12 * by the Free Software Foundation; either version 2 of the License,
13 * or (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
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 Survey(&$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;
90 * create - use this function to create a survey
92 * @param string The survey title
93 * @param int array The question numbers to be added
94 * @param is_active 1: Active, 0: Inactive
96 * @param is_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:Every body
97 * @param is_result_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:voted user 4:Every body
98 * @param double_vote Allow double vote if it is 1
99 * @return boolean success.
101 function create($survey_title, $add_questions, $is_active=0, $is_public=1, $is_result_public=0, $double_vote=0) {
102 if (!$survey_title) {
103 $this->setError(_('Update Failed: Survey Title Required'));
105 /* We need at least one survey question at this point */
106 } else if (!$add_questions || !is_array($add_questions) || count($add_questions)<1) {
107 $this->setError(_('Update Failed: Survey Questions Required'));
111 $group_id = $this->Group->GetID();
113 /* Make old style survey string from array: 1, 2, 3, ..., n */
114 $survey_questions = $this->_makeQuestionString(array_reverse($add_questions));
116 $result = db_query_params ('INSERT INTO surveys (survey_title,group_id,survey_questions,is_active) VALUES ($1,$2,$3,$4)',
117 array (htmlspecialchars($survey_title),
122 $this->setError(_('Insert Error').db_error());
126 /* Load question to data array */
127 $survey_id=db_insertid($res,'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 if (is_array($add_questions))
162 $add_questions = array_reverse($add_questions);
164 $survey_questions = $this->_updateQuestionString($add_questions, $del_questions);
165 $result = db_query_params ('UPDATE surveys SET survey_title=$1, survey_questions=$2, is_active=$3 WHERE survey_id=$4 AND group_id=$5',
166 array (htmlspecialchars($survey_title),
171 if (db_affected_rows($result) < 1) {
172 $this->setError(_('UPDATE FAILED').db_error());
175 /* Update internal data */
176 return $this->fetchData($survey_id);
180 * updateOrder - use this function to update question order
182 * @param int Question number
183 * @param boolean decide up or down. it is up if it is true
184 * @return boolean success.
186 function updateOrder($question_number, $is_up=true) {
187 $group_id = $this->Group->GetID();
188 $survey_id = $this->getID();
190 /* Ths Survey is not ready to update */
192 $this->setError(_('The Survey data is not filled'));
203 $survey_questions = $this->_updateQuestionStringOrder($question_number, $delta);
204 $result = db_query_params ('UPDATE surveys SET survey_questions=$1 WHERE survey_id=$2 AND group_id=$3',
205 array ($survey_questions,
208 if (db_affected_rows($result) < 1) {
209 $this->setError(_('UPDATE FAILED').db_error());
213 /* Update internal data */
214 return $this->fetchData($survey_id);
218 * delete - use this function to delete this survey
219 * (We don't support delete yet)
221 * @return boolean success.
224 $group_id = $this->Group->GetID();
225 $survey_id = $this->getID();
227 $res = db_query_params ('DELETE FROM surveys where survey_id=$1 AND group_id=$2',
230 if (!$res || db_affected_rows($res) < 1) {
231 $this->setError(_('Delete failed').db_error());
235 /* Delete internal data */
236 $this->data_array = null;
241 * fetchData - re-fetch the data for this survey from the database.
243 * @param int The survey_id.
244 * @return boolean success.
246 function fetchData($survey_id) {
247 $group_id = $this->Group->GetID();
249 $res = db_query_params ('SELECT * FROM surveys where survey_id=$1 AND group_id=$2',
253 if (!$res || db_numrows($res) < 1) {
254 $this->setError(_('No Survey is found').db_error());
257 $this->data_array =& db_fetch_array($res);
258 db_free_result($res);
263 * getGroup - get the Group object this Survey is associated with.
265 * @return object The Group object.
267 function &getGroup() {
272 * getID - Get the id of this Survey
274 * @return int The question_id
277 return $this->data_array['survey_id'];
281 * isActriv - return if it is active
283 * @return int is active
285 function isActive() {
286 return $this->data_array['is_active'];
290 * getTitle - Get the Survey title
292 * @return string the survey title
294 function getTitle() {
295 return $this->data_array['survey_title'];
299 * getQuestionString - Get the question string
301 * @return string the question
303 function getQuestionString() {
304 return $this->data_array['survey_questions'];
308 * getNumberOfQuestion - Get the number of questions
310 * @return int the number questions
312 function getNumberOfQuestions() {
313 return count($this->getQuestionArray());
317 * getNumberOfVotes - Get the number of votes
319 * @return int the number votes
321 function getNumberOfVotes() {
322 $group_id = $this->Group->GetID();
323 $survey_id = $this->getID();
325 $res = db_query_params ('SELECT 1 FROM survey_responses WHERE survey_id=$1 AND group_id=$2 GROUP BY user_id',
328 $ret = db_numrows($res);
329 db_free_result($res);
335 * isUserVote - Figure out the user voted or not
338 * @return true of false
340 function isUserVote($user_id) {
341 $group_id = $this->Group->GetID();
342 $survey_id = $this->getID();
344 $res = db_query_params ('SELECT 1 FROM survey_responses where survey_id=$1 AND group_id=$2 AND user_id=$3',
348 $ret = db_numrows($res);
349 db_free_result($res);
355 * getQuestionArray - Get the question string numbers in array
357 * @return string the question
359 function &getQuestionArray() {
361 $questions = $this->getQuestionString();
366 $arr_from_str = explode(',', $questions);
368 /* Remove non existed questions */
369 for ($i=0; $i<count($arr_from_str); $i++) {
370 if ($this->_isValidQuestionID($arr_from_str[$i])) {
371 $ret_arr[] = $arr_from_str[$i];
379 * getQuestionInstances - Get the SurveyQuestion array belongs to this Survey by order
381 * @return string the question
383 function &getQuestionInstances() {
386 if (!$this->all_question_array || !is_array($this->all_question_array)) {
387 $this->_fillSurveyQuestions();
390 $arr = & $this->getQuestionArray();
392 for ($i=0; $i<count($arr); $i++) {
393 for ($j=0; $j<count($this->all_question_array); $j++) {
394 /* If it is, copy into new array in order */
395 if ($this->all_question_array[$j]->getID()==$arr[$i]) {
396 $ret[] = $this->all_question_array[$j];
406 * getAddableQuestionInstances - Get the addable SurveyQuestion from all questions
408 * @return string the question
410 function &getAddableQuestionInstances() {
413 if (!$this->all_question_array || !is_array($this->all_question_array)) {
414 $this->_fillSurveyQuestions();
417 $arr = & $this->getQuestionArray();
419 /* Copy questions only if it is not in question string */
420 for ($i=0; $i<count($this->all_question_array); $i++) {
421 if (array_search($this->all_question_array[$i]->getID(), $arr)==false &&
422 $this->all_question_array[$i]->getID()!=$arr[0]) {
423 $ret[] = $this->all_question_array[$i];
427 $ret = $this->all_question_array;
433 /***************************************************************
434 * private question string deal methods
435 * TODO: Add a joint table for surveys and survey_questions.
436 * Deal with DBMS not comma separated string
437 ***************************************************************/
440 * _fillSurveyQuestions - Get all Survey Questions using SurveyQuestionFactory
442 * @return booelan suesssness
444 function _fillSurveyQuestions() {
445 $sqf = new SurveyQuestionFactory($this->getGroup());
446 $this->all_question_array = & $sqf->getSurveyQuestions();
451 * _isValidQuestionID - Check it is correct question id
453 * @param int questioin id
454 * @return boolean true if it is valid question id
456 function _isValidQuestionID($question_id) {
457 if (!$this->all_question_array || !is_array($this->all_question_array)) {
458 $this->_fillSurveyQuestions();
461 for ($i=0; $i<count($this->all_question_array); $i++) {
462 if ($question_id == $this->all_question_array[$i]->getID()) {
471 * _makeQuestionString - Make comma separated question number string
473 * @param int array Array of question number
474 * @return string question_strong (example: 1, 2, 3, 7);
476 function _makeQuestionString($arr) {
478 /* No questions to add */
479 if (!$arr || !is_array($arr) || count($arr)<1) {
482 return join(',', $arr);
486 * _updateQuestionString - Update comma saparated question number string
488 * @param int array Array of questions to add
489 * @param int array Array of questions to delete
490 * @return string question_strong (example: 1, 2, 3, 7);
492 function _updateQuestionString(&$arr_to_add, &$arr_to_del) {
493 /* Get array of current question string */
494 $arr = & $this->getQuestionArray();
496 /* questions to add */
500 if ($arr_to_add && is_array($arr_to_add) && count($arr_to_add)>0) {
501 for ($i = 0; $i < count($arr_to_add); $i++) {
502 /* Avoid double question */
503 if ($arr_to_add[$i] && array_search($arr_to_add[$i], $arr)==false && $arr_to_add[$i]!=$arr[0]) {
504 $arr[] = $arr_to_add[$i];
510 /* questions to delete */
511 if ($arr_to_del && is_array($arr_to_del) && count($arr_to_del)>0) {
513 for ($i = 0; $i < count($arr); $i++) {
514 /* If the value is no in the delete array, copy it into new array */
515 if ($arr[$i] && array_search($arr[$i], $arr_to_del)==false && $arr_to_del[0]!=$arr[$i]) {
516 $new_arr[] = $arr[$i];
519 /* copy new_arr to arr */
523 /* converty array to String */
524 return $this->_makeQuestionString($arr);
528 * _updateArrayOrder - Update array order
530 * @param int question number
531 * @param int increment or decrement (must be 1 or -1)
532 * @return string question_strong (example: 1, 2, 3, 7);
534 function _updateQuestionStringOrder($question_number, $delta) {
535 /* Get array of current question string */
536 $arr = & $this->getQuestionArray();
538 /* We are expectiong array */
539 if (!$arr || !is_array($arr)) {
540 return $this->getQuestionString();
543 $index = array_search($question_number, $arr);
545 /* The question number is not in the array
546 * We have nothing to change
548 if ($index==false && $question_number!=$arr[0]) {
549 return $this->getQuestionString();
552 $new_index = $index + $delta;
554 /* Out of boundary */
555 if ($new_index < 0 || $new_index >= count($arr)) {
556 return $this->getQuestionString();
561 $arr[$index] = $arr[$new_index];
562 $arr[$new_index] = $tmp;
564 /* converty array to String */
565 return $this->_makeQuestionString($arr);
571 // c-file-style: "bsd"