5 * Copyright 2004, Sung Kim/GForge, LLC
6 * Copyright 2009, Roland Mas
7 * http://fusionforge.org
9 * This file is part of FusionForge.
11 * FusionForge is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published
13 * by the Free Software Foundation; either version 2 of the License,
14 * or (at your option) any later version.
16 * FusionForge is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with FusionForge; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 require_once $gfcommon.'include/Error.class.php';
28 require_once $gfcommon.'survey/SurveyQuestionFactory.class.php';
30 class Survey extends Error {
33 * Associative array of data from db.
35 * @var array $data_array.
40 * Questions array in this survey
42 * @var array $question_array.
44 var $all_question_array;
56 * @param object The Group object to which this servey is associated.
57 * @param int The servey_id.
58 * @param array The associative array of data.
59 * @return boolean success.
61 function Survey(&$Group, $survey_id = false, $arr = false) {
63 if (!$Group || !is_object($Group)) {
64 $this->setError(sprintf(_('%1$s:: No Valid Group Object'), "Survey"));
67 if ($Group->isError()) {
68 $this->setError('Survey:: '.$Group->getErrorMessage());
71 $this->Group =& $Group;
74 if (!$arr || !is_array($arr)) {
75 if (!$this->fetchData($survey_id)) {
79 $this->data_array =& $arr;
80 if ($this->data_array['group_id'] != $this->Group->getID()) {
81 $this->setError(_('Group_id in db result does not match Group Object'));
82 $this->data_array = null;
91 * create - use this function to create a survey
93 * @param string The survey title
94 * @param int array The question numbers to be added
95 * @param is_active 1: Active, 0: Inactive
97 * @param is_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:Every body
98 * @param is_result_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:voted user 4:Every body
99 * @param double_vote Allow double vote if it is 1
100 * @return boolean success.
102 function create($survey_title, $add_questions, $is_active = 0, $is_public = 1, $is_result_public = 0, $double_vote = 0) {
103 if (!$survey_title) {
104 $this->setError(_('Update Failed: Survey Title Required'));
106 /* We need at least one survey question at this point */
107 } else if (!$add_questions || !is_array($add_questions) || count($add_questions)<1) {
108 $this->setError(_('Update Failed: Survey Questions Required'));
112 $group_id = $this->Group->GetID();
114 /* Make old style survey string from array: 1, 2, 3, ..., n */
115 $survey_questions = $this->_makeQuestionString(array_reverse($add_questions));
117 $result = db_query_params('INSERT INTO surveys (survey_title,group_id,survey_questions,is_active) VALUES ($1,$2,$3,$4)',
118 array(htmlspecialchars($survey_title),
124 $this->setError(_('Insert Error').db_error());
128 /* Load question to data array */
129 $survey_id=db_insertid($result,'surveys','survey_id');
130 return $this->fetchData($survey_id);
136 * update - use this function to update a survey
138 * @param string The survey title
139 * @param int array The question numbers to be added
140 * @param int array The question numbers to be deleted
141 * @param is_active 1: Active, 0: Inactive
142 * @param is_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:Every body
143 * @param is_result_public 0: Admins Only, 1: Group Members, 2: Gforge user, 3:voted user 4:Every body
144 * @param double_vote Allow double vote if it is 1
145 * @return boolean success.
147 function update($survey_title, &$add_questions, &$del_questions, $is_active = 0, $is_public = 1, $is_result_public = 0, $double_vote = 0) {
148 if (!$survey_title) {
149 $this->setError(_('Update Failed: Survey Title Required'));
151 /* We need at least one survey question at this point */
154 $group_id = $this->Group->GetID();
155 $survey_id = $this->getID();
157 /* Ths Survey is not ready to update */
159 $this->setError(_('The Survey data is not filled'));
163 if (is_array($add_questions))
164 $add_questions = array_reverse($add_questions);
166 $survey_questions = $this->_updateQuestionString($add_questions, $del_questions);
167 $result = db_query_params('UPDATE surveys SET survey_title=$1, survey_questions=$2, is_active=$3 WHERE survey_id=$4 AND group_id=$5',
168 array (htmlspecialchars($survey_title),
174 if (db_affected_rows($result) < 1) {
175 $this->setError(_('UPDATE FAILED').db_error());
178 /* Update internal data */
179 return $this->fetchData($survey_id);
183 * updateOrder - use this function to update question order
185 * @param int Question number
186 * @param boolean decide up or down. it is up if it is true
187 * @return boolean success.
189 function updateOrder($question_number, $is_up = true) {
190 $group_id = $this->Group->GetID();
191 $survey_id = $this->getID();
193 /* Ths Survey is not ready to update */
195 $this->setError(_('The Survey data is not filled'));
206 $survey_questions = $this->_updateQuestionStringOrder($question_number, $delta);
207 $result = db_query_params('UPDATE surveys SET survey_questions=$1 WHERE survey_id=$2 AND group_id=$3',
208 array ($survey_questions,
212 if (db_affected_rows($result) < 1) {
213 $this->setError(_('UPDATE FAILED').db_error());
217 /* Update internal data */
218 return $this->fetchData($survey_id);
222 * delete - use this function to delete this survey
223 * (We don't support delete yet)
225 * @return boolean success.
228 $group_id = $this->Group->GetID();
229 $survey_id = $this->getID();
231 $res = db_query_params('DELETE FROM surveys where survey_id=$1 AND group_id=$2',
232 array($survey_id, $group_id)
234 if (!$res || db_affected_rows($res) < 1) {
235 $this->setError(_('Delete failed').db_error());
239 /* Delete internal data */
240 $this->data_array = null;
245 * fetchData - re-fetch the data for this survey from the database.
247 * @param int The survey_id.
248 * @return boolean success.
250 function fetchData($survey_id) {
251 $group_id = $this->Group->GetID();
253 $res = db_query_params('SELECT * FROM surveys where survey_id=$1 AND group_id=$2',
254 array($survey_id, $group_id)) ;
256 if (!$res || db_numrows($res) < 1) {
257 $this->setError(_('No Survey is found').db_error());
260 $this->data_array = db_fetch_array($res);
261 db_free_result($res);
266 * getGroup - get the Group object this Survey is associated with.
268 * @return object The Group object.
270 function &getGroup() {
275 * getID - Get the id of this Survey
277 * @return int The question_id
280 return $this->data_array['survey_id'];
284 * isActriv - return if it is active
286 * @return int is active
288 function isActive() {
289 return $this->data_array['is_active'];
293 * getTitle - Get the Survey title
295 * @return string the survey title
297 function getTitle() {
298 return $this->data_array['survey_title'];
302 * getQuestionString - Get the question string
304 * @return string the question
306 function getQuestionString() {
307 return $this->data_array['survey_questions'];
311 * getNumberOfQuestion - Get the number of questions
313 * @return int the number questions
315 function getNumberOfQuestions() {
316 return count($this->getQuestionArray());
320 * getNumberOfVotes - Get the number of votes
322 * @return int the number votes
324 function getNumberOfVotes() {
325 $group_id = $this->Group->GetID();
326 $survey_id = $this->getID();
328 $res = db_query_params ('SELECT 1 FROM survey_responses WHERE survey_id=$1 AND group_id=$2 GROUP BY user_id',
331 $ret = db_numrows($res);
332 db_free_result($res);
338 * isUserVote - Figure out the user voted or not
341 * @return true of false
343 function isUserVote($user_id) {
344 $group_id = $this->Group->GetID();
345 $survey_id = $this->getID();
347 $res = db_query_params ('SELECT 1 FROM survey_responses where survey_id=$1 AND group_id=$2 AND user_id=$3',
351 $ret = db_numrows($res);
352 db_free_result($res);
358 * getQuestionArray - Get the question string numbers in array
360 * @return string the question
362 function &getQuestionArray() {
364 $questions = $this->getQuestionString();
369 $arr_from_str = explode(',', $questions);
371 /* Remove non existed questions */
372 for ($i=0; $i<count($arr_from_str); $i++) {
373 if ($this->_isValidQuestionID($arr_from_str[$i])) {
374 $ret_arr[] = $arr_from_str[$i];
382 * getQuestionInstances - Get the SurveyQuestion array belongs to this Survey by order
384 * @return string the question
386 function &getQuestionInstances() {
389 if (!$this->all_question_array || !is_array($this->all_question_array)) {
390 $this->_fillSurveyQuestions();
393 $arr = & $this->getQuestionArray();
395 for ($i=0; $i<count($arr); $i++) {
396 for ($j=0; $j<count($this->all_question_array); $j++) {
397 /* If it is, copy into new array in order */
398 if ($this->all_question_array[$j]->getID()==$arr[$i]) {
399 $ret[] = $this->all_question_array[$j];
409 * getAddableQuestionInstances - Get the addable SurveyQuestion from all questions
411 * @return string the question
413 function &getAddableQuestionInstances() {
416 if (!$this->all_question_array || !is_array($this->all_question_array)) {
417 $this->_fillSurveyQuestions();
420 $arr = & $this->getQuestionArray();
422 /* Copy questions only if it is not in question string */
423 for ($i=0; $i<count($this->all_question_array); $i++) {
424 if (array_search($this->all_question_array[$i]->getID(), $arr) == false &&
425 $this->all_question_array[$i]->getID()!=$arr[0]) {
426 $ret[] = $this->all_question_array[$i];
430 $ret = $this->all_question_array;
436 /***************************************************************
437 * private question string deal methods
438 * TODO: Add a joint table for surveys and survey_questions.
439 * Deal with DBMS not comma separated string
440 ***************************************************************/
443 * _fillSurveyQuestions - Get all Survey Questions using SurveyQuestionFactory
445 * @return boolean success
447 function _fillSurveyQuestions() {
448 $sqf = new SurveyQuestionFactory($this->getGroup());
449 $this->all_question_array = & $sqf->getSurveyQuestions();
454 * _isValidQuestionID - Check it is correct question id
456 * @param int questioin id
457 * @return boolean true if it is valid question id
459 function _isValidQuestionID($question_id) {
460 if (!$this->all_question_array || !is_array($this->all_question_array)) {
461 $this->_fillSurveyQuestions();
464 for ($i=0; $i<count($this->all_question_array); $i++) {
465 if ($question_id == $this->all_question_array[$i]->getID()) {
474 * _makeQuestionString - Make comma separated question number string
476 * @param int array Array of question number
477 * @return string question_strong (example: 1, 2, 3, 7);
479 function _makeQuestionString($arr) {
481 /* No questions to add */
482 if (!$arr || !is_array($arr) || count($arr)<1) {
485 return join(',', $arr);
489 * _updateQuestionString - Update comma saparated question number string
491 * @param int array Array of questions to add
492 * @param int array Array of questions to delete
493 * @return string question_strong (example: 1, 2, 3, 7);
495 function _updateQuestionString(&$arr_to_add, &$arr_to_del) {
496 /* Get array of current question string */
497 $arr = & $this->getQuestionArray();
499 /* questions to add */
503 if ($arr_to_add && is_array($arr_to_add) && count($arr_to_add)>0) {
504 for ($i = 0; $i < count($arr_to_add); $i++) {
505 /* Avoid double question */
506 if ($arr_to_add[$i] && array_search($arr_to_add[$i], $arr) == false && $arr_to_add[$i]!=$arr[0]) {
507 $arr[] = $arr_to_add[$i];
513 /* questions to delete */
514 if ($arr_to_del && is_array($arr_to_del) && count($arr_to_del)>0) {
516 for ($i = 0; $i < count($arr); $i++) {
517 /* If the value is no in the delete array, copy it into new array */
518 if ($arr[$i] && array_search($arr[$i], $arr_to_del)==false && $arr_to_del[0]!=$arr[$i]) {
519 $new_arr[] = $arr[$i];
522 /* copy new_arr to arr */
526 /* converty array to String */
527 return $this->_makeQuestionString($arr);
531 * _updateArrayOrder - Update array order
533 * @param int question number
534 * @param int increment or decrement (must be 1 or -1)
535 * @return string question_strong (example: 1, 2, 3, 7);
537 function _updateQuestionStringOrder($question_number, $delta) {
538 /* Get array of current question string */
539 $arr = & $this->getQuestionArray();
541 /* We are expectiong array */
542 if (!$arr || !is_array($arr)) {
543 return $this->getQuestionString();
546 $index = array_search($question_number, $arr);
548 /* The question number is not in the array
549 * We have nothing to change
551 if ($index==false && $question_number!=$arr[0]) {
552 return $this->getQuestionString();
555 $new_index = $index + $delta;
557 /* Out of boundary */
558 if ($new_index < 0 || $new_index >= count($arr)) {
559 return $this->getQuestionString();
564 $arr[$index] = $arr[$new_index];
565 $arr[$new_index] = $tmp;
567 /* converty array to String */
568 return $this->_makeQuestionString($arr);
574 // c-file-style: "bsd"