ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjSurvey.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once "./Services/Object/classes/class.ilObject.php";
5 
15 class ilObjSurvey extends ilObject
16 {
17  const STATUS_OFFLINE = 0;
18  const STATUS_ONLINE = 1;
19 
23 
24  const INVITATION_OFF = 0;
25  const INVITATION_ON = 1;
26 
27  const MODE_UNLIMITED = 0;
29 
30  const ANONYMIZE_OFF = 0;
31  const ANONYMIZE_ON = 1;
33  const ANONYMIZE_CODE_ALL = 3;
34 
37 
45 
52  var $author;
53 
60 
66  var $outro;
67 
73  var $status;
74 
81 
88 
94  var $end_date;
95 
102 
109 
116 
122 
128 
135 
141 
145 
146  // 360°
147  protected $mode_360; // [bool]
148  protected $mode_360_self_eval; // [bool]
149  protected $mode_360_self_appr; // [bool]
150  protected $mode_360_self_rate; // [bool]
151  protected $mode_360_results; // [int]
152  protected $mode_360_skill_service; // [bool]
153 
154  const RESULTS_360_NONE = 0;
155  const RESULTS_360_OWN = 1;
156  const RESULTS_360_ALL = 2;
157 
158  // reminder/notification
159  protected $reminder_status; // [bool]
160  protected $reminder_start; // [ilDate]
161  protected $reminder_end; // [ilDate]
162  protected $reminder_frequency; // [int]
163  protected $reminder_target; // [int]
164  protected $reminder_last_sent; // [bool]
165  protected $tutor_ntf_status; // [bool]
166  protected $tutor_ntf_recipients; // [array]
167  protected $tutor_ntf_target; // [int]
168 
171 
172 
179  function ilObjSurvey($a_id = 0,$a_call_by_reference = true)
180  {
181  global $ilUser, $lng;
182 
183  $this->type = "svy";
184  $this->survey_id = -1;
185  $this->introduction = "";
186  $this->outro = $lng->txt("survey_finished");
187  $this->author = $ilUser->getFullname();
188  $this->status = self::STATUS_OFFLINE;
189  $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
190  $this->questions = array();
191  $this->invitation = self::INVITATION_OFF;
192  $this->invitation_mode = self::MODE_PREDEFINED_USERS;
193  $this->anonymize = self::ANONYMIZE_OFF;
194  $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
195  $this->surveyCodeSecurity = TRUE;
196  $this->template_id = NULL;
197  $this->pool_usage = true;
198 
199  parent::__construct($a_id,$a_call_by_reference);
200  }
201 
205  function create($a_upload = false)
206  {
207  parent::create();
208  if(!$a_upload)
209  {
210  $this->createMetaData();
211  }
212  }
213 
219  function createMetaData()
220  {
222  $this->saveAuthorToMetadata();
223  }
224 
231  function update()
232  {
233  $this->updateMetaData();
234 
235  if (!parent::update())
236  {
237  return false;
238  }
239 
240  // put here object specific stuff
241 
242  return true;
243  }
244 
245  function createReference()
246  {
248  $this->saveToDb();
249  return $result;
250  }
251 
257  function read($a_force_db = false)
258  {
259  parent::read($a_force_db);
260  $this->loadFromDb();
261  }
262 
269  function addQuestion($question_id)
270  {
271  array_push($this->questions, $question_id);
272  }
273 
274 
281  function delete()
282  {
283  $remove = parent::delete();
284  // always call parent delete function first!!
285  if (!$remove)
286  {
287  return false;
288  }
289 
290  $this->deleteMetaData();
291 
292  // Delete all survey questions, constraints and materials
293  foreach ($this->questions as $question_id)
294  {
295  $this->removeQuestion($question_id);
296  }
297  $this->deleteSurveyRecord();
298 
300  return true;
301  }
302 
309  {
310  global $ilDB;
311 
312  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_svy WHERE survey_id = %s",
313  array('integer'),
314  array($this->getSurveyId())
315  );
316 
317  $result = $ilDB->queryF("SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
318  array('integer'),
319  array($this->getSurveyId())
320  );
321  $questionblocks = array();
322  while ($row = $ilDB->fetchAssoc($result))
323  {
324  array_push($questionblocks, $row["questionblock_fi"]);
325  }
326  if (count($questionblocks))
327  {
328  $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
329  }
330  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
331  array('integer'),
332  array($this->getSurveyId())
333  );
334  $this->deleteAllUserData();
335 
336  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_anonymous WHERE survey_fi = %s",
337  array('integer'),
338  array($this->getSurveyId())
339  );
340 
341  // delete export files
342  include_once "./Services/Utilities/classes/class.ilUtil.php";
343  $svy_data_dir = ilUtil::getDataDir()."/svy_data";
344  $directory = $svy_data_dir."/svy_".$this->getId();
345  if (is_dir($directory))
346  {
347  include_once "./Services/Utilities/classes/class.ilUtil.php";
348  ilUtil::delDir($directory);
349  }
350 
351  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
352  $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
353  // remaining usages are not in text anymore -> delete them
354  // and media objects (note: delete method of ilObjMediaObject
355  // checks whether object is used in another context; if yes,
356  // the object is not deleted!)
357  foreach($mobs as $mob)
358  {
359  ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
360  $mob_obj =& new ilObjMediaObject($mob);
361  $mob_obj->delete();
362  }
363  }
364 
370  function deleteAllUserData()
371  {
372  global $ilDB;
373 
374  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
375  array('integer'),
376  array($this->getSurveyId())
377  );
378  $active_array = array();
379  while ($row = $ilDB->fetchAssoc($result))
380  {
381  array_push($active_array, $row["finished_id"]);
382  }
383 
384  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_finished WHERE survey_fi = %s",
385  array('integer'),
386  array($this->getSurveyId())
387  );
388 
389  foreach ($active_array as $active_fi)
390  {
391  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE active_fi = %s",
392  array('integer'),
393  array($active_fi)
394  );
395  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_times WHERE finished_fi = %s",
396  array('integer'),
397  array($active_fi)
398  );
399  }
400  }
401 
407  function removeSelectedSurveyResults($finished_ids)
408  {
409  global $ilDB;
410 
411  foreach ($finished_ids as $finished_id)
412  {
413  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE finished_id = %s",
414  array('integer'),
415  array($finished_id)
416  );
417  $row = $ilDB->fetchAssoc($result);
418 
419  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE active_fi = %s",
420  array('integer'),
421  array($row["finished_id"])
422  );
423 
424  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_finished WHERE finished_id = %s",
425  array('integer'),
426  array($finished_id)
427  );
428 
429  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_times WHERE finished_fi = %s",
430  array('integer'),
431  array($row["finished_id"])
432  );
433  }
434  }
435 
436  function &getSurveyParticipants($finished_ids = null)
437  {
438  global $ilDB;
439 
440  $sql = "SELECT * FROM svy_finished".
441  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
442  if($finished_ids)
443  {
444  $sql .= " AND ".$ilDB->in("finished_id", $finished_ids, "", "integer");
445  }
446 
447  $result = $ilDB->query($sql);
448  $participants = array();
449  if ($result->numRows() > 0)
450  {
451  while ($row = $ilDB->fetchAssoc($result))
452  {
453  $userdata = $this->getUserDataFromActiveId($row["finished_id"]);
454  $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
455  }
456  }
457  return $participants;
458  }
459 
473  function notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params = 0)
474  {
475  global $tree;
476 
477  switch ($a_event)
478  {
479  case "link":
480 
481  //var_dump("<pre>",$a_params,"</pre>");
482  //echo "Module name ".$this->getRefId()." triggered by link event. Objects linked into target object ref_id: ".$a_ref_id;
483  //exit;
484  break;
485 
486  case "cut":
487 
488  //echo "Module name ".$this->getRefId()." triggered by cut event. Objects are removed from target object ref_id: ".$a_ref_id;
489  //exit;
490  break;
491 
492  case "copy":
493 
494  //var_dump("<pre>",$a_params,"</pre>");
495  //echo "Module name ".$this->getRefId()." triggered by copy event. Objects are copied into target object ref_id: ".$a_ref_id;
496  //exit;
497  break;
498 
499  case "paste":
500 
501  //echo "Module name ".$this->getRefId()." triggered by paste (cut) event. Objects are pasted into target object ref_id: ".$a_ref_id;
502  //exit;
503  break;
504 
505  case "new":
506 
507  //echo "Module name ".$this->getRefId()." triggered by paste (new) event. Objects are applied to target object ref_id: ".$a_ref_id;
508  //exit;
509  break;
510  }
511 
512  // At the beginning of the recursive process it avoids second call of the notify function with the same parameter
513  if ($a_node_id==$_GET["ref_id"])
514  {
515  $parent_obj =& $this->ilias->obj_factory->getInstanceByRefId($a_node_id);
516  $parent_type = $parent_obj->getType();
517  if($parent_type == $this->getType())
518  {
519  $a_node_id = (int) $tree->getParentId($a_node_id);
520  }
521  }
522 
523  parent::notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params);
524  }
525 
532  function isComplete()
533  {
534  if (($this->getTitle()) and (count($this->questions)))
535  {
536  return 1;
537  }
538  else
539  {
540  return 0;
541  }
542  }
543 
550  function _isComplete($obj_id)
551  {
552  $survey = new ilObjSurvey($obj_id, false);
553  $survey->loadFromDb();
554  if (($survey->getTitle()) and (count($survey->questions)))
555  {
556  return 1;
557  }
558  else
559  {
560  return 0;
561  }
562  }
563 
570  function &_getGlobalSurveyData($obj_id)
571  {
572  $survey = new ilObjSurvey($obj_id, false);
573  $survey->loadFromDb();
574  $result = array();
575  if (($survey->getTitle()) and ($survey->author) and (count($survey->questions)))
576  {
577  $result["complete"] = true;
578  }
579  else
580  {
581  $result["complete"] = false;
582  }
583  $result["evaluation_access"] = $survey->getEvaluationAccess();
584  return $result;
585  }
586 
593  {
594  global $ilDB;
595 
596  $complete = 0;
597  if ($this->isComplete())
598  {
599  $complete = 1;
600  }
601  if ($this->getSurveyId() > 0)
602  {
603  $affectedRows = $ilDB->manipulateF("UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
604  array('text','integer','integer'),
605  array($this->isComplete(), time(), $this->getSurveyId())
606  );
607  }
608  }
609 
617  function duplicateQuestionForSurvey($question_id, $a_force = false)
618  {
619  global $ilUser;
620 
621  $questiontype = $this->getQuestionType($question_id);
622  $question_gui = $this->getQuestionGUI($questiontype, $question_id);
623 
624  // check if question is a pool question at all, if not do nothing
625  if($this->getId() == $question_gui->object->getObjId() && !$a_force)
626  {
627  return $question_id;
628  }
629 
630  $duplicate_id = $question_gui->object->duplicate(true);
631  return $duplicate_id;
632  }
633 
639  function insertQuestion($question_id)
640  {
641  global $ilDB;
642 
643  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
644  if (!SurveyQuestion::_isComplete($question_id))
645  {
646  return FALSE;
647  }
648  else
649  {
650  // get maximum sequence index in test
651  $result = $ilDB->queryF("SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
652  array('integer'),
653  array($this->getSurveyId())
654  );
655  $sequence = $result->numRows();
656  $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
657  $next_id = $ilDB->nextId('svy_svy_qst');
658  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
659  array('integer', 'integer', 'integer', 'integer', 'integer'),
660  array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
661  );
662  $this->loadQuestionsFromDb();
663  return TRUE;
664  }
665  }
666 
667 
673  function insertQuestionblock($questionblock_id)
674  {
675  global $ilDB;
676  $result = $ilDB->queryF("SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle,".
677  " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst".
678  " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi".
679  " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi".
680  " AND svy_qblk.questionblock_id = %s".
681  " ORDER BY svy_svy_qst.sequence",
682  array('integer'),
683  array($questionblock_id)
684  );
685  $questions = array();
686  $show_questiontext = 0;
687  $show_blocktitle = 0;
688  while ($row = $ilDB->fetchAssoc($result))
689  {
690  $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
691  array_push($questions, $duplicate_id);
692  $title = $row["title"];
693  $show_questiontext = $row["show_questiontext"];
694  $show_blocktitle = $row["show_blocktitle"];
695  }
696  $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
697  }
698 
704  function getAllRTEContent()
705  {
706  $result = array();
707  array_push($result, $this->getIntroduction());
708  array_push($result, $this->getOutro());
709  return $result;
710  }
711 
718  {
719  include_once("./Services/RTE/classes/class.ilRTE.php");
720  $completecontent = "";
721  foreach ($this->getAllRTEContent() as $content)
722  {
723  $completecontent .= $content;
724  }
725  ilRTE::_cleanupMediaObjectUsage($completecontent, $this->getType() . ":html",
726  $this->getId());
727  }
728 
729  public function saveUserSettings($usr_id, $key, $title, $value)
730  {
731  global $ilDB;
732 
733  $next_id = $ilDB->nextId('svy_settings');
734  $affectedRows = $ilDB->insert("svy_settings", array(
735  "settings_id" => array("integer", $next_id),
736  "usr_id" => array("integer", $usr_id),
737  "keyword" => array("text", $key),
738  "title" => array("text", $title),
739  "value" => array("clob", $value)
740  ));
741  }
742 
743  public function deleteUserSettings($id)
744  {
745  global $ilDB;
746 
747  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_settings WHERE settings_id = %s",
748  array('integer'),
749  array($id)
750  );
751  return $affectedRows;
752  }
753 
754  public function getUserSettings($usr_id, $key)
755  {
756  global $ilDB;
757 
758  $result = $ilDB->queryF("SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
759  array('integer', 'text'),
760  array($usr_id, $key)
761  );
762  $found = array();
763  if ($result->numRows())
764  {
765  while ($row = $ilDB->fetchAssoc($result))
766  {
767  $found[$row['settings_id']] = $row;
768  }
769  }
770  return $found;
771  }
772 
778  function saveToDb()
779  {
780  global $ilDB;
781 
782  // date handling
783  $rmd_start = $this->getReminderStart();
784  if(is_object($rmd_start))
785  {
786  $rmd_start = $rmd_start->get(IL_CAL_DATE);
787  }
788  $rmd_end = $this->getReminderEnd();
789  if(is_object($rmd_end))
790  {
791  $rmd_end = $rmd_end->get(IL_CAL_DATE);
792  }
793 
794  include_once("./Services/RTE/classes/class.ilRTE.php");
795  if ($this->getSurveyId() < 1)
796  {
797  $next_id = $ilDB->nextId('svy_svy');
798  $affectedRows = $ilDB->insert("svy_svy", array(
799  "survey_id" => array("integer", $next_id),
800  "obj_fi" => array("integer", $this->getId()),
801  "author" => array("text", $this->getAuthor()),
802  "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
803  "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
804  "status" => array("text", $this->getStatus()),
805  "startdate" => array("text", $this->getStartDate()),
806  "enddate" => array("text", $this->getEndDate()),
807  "evaluation_access" => array("text", $this->getEvaluationAccess()),
808  "invitation" => array("text", $this->getInvitation()),
809  "invitation_mode" => array("text", $this->getInvitationMode()),
810  "complete" => array("text", $this->isComplete()),
811  "created" => array("integer", time()),
812  "anonymize" => array("text", $this->getAnonymize()),
813  "show_question_titles" => array("text", $this->getShowQuestionTitles()),
814  "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
815  "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : NULL),
816  "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : NULL),
817  "tstamp" => array("integer", time()),
818  "template_id" => array("integer", $this->getTemplate()),
819  "pool_usage" => array("integer", $this->getPoolUsage()),
820  // 360°
821  "mode_360" => array("integer", $this->get360Mode()),
822  "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
823  "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
824  "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
825  "mode_360_results" => array("integer", $this->get360Results()),
826  "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
827  // reminder/notification
828  "reminder_status" => array("integer", (int)$this->getReminderStatus()),
829  "reminder_start" => array("datetime", $rmd_start),
830  "reminder_end" => array("datetime", $rmd_end),
831  "reminder_frequency" => array("integer", (int)$this->getReminderFrequency()),
832  "reminder_target" => array("integer", (int)$this->getReminderTarget()),
833  "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
834  "tutor_ntf_status" => array("integer", (int)$this->getTutorNotificationStatus()),
835  "tutor_ntf_reci" => array("text", implode(";", (array)$this->getTutorNotificationRecipients())),
836  "tutor_ntf_target" => array("integer", (int)$this->getTutorNotificationTarget())
837  ));
838  $this->setSurveyId($next_id);
839  }
840  else
841  {
842  $affectedRows = $ilDB->update("svy_svy", array(
843  "author" => array("text", $this->getAuthor()),
844  "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
845  "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
846  "status" => array("text", $this->getStatus()),
847  "startdate" => array("text", $this->getStartDate()),
848  "enddate" => array("text", $this->getEndDate()),
849  "evaluation_access" => array("text", $this->getEvaluationAccess()),
850  "invitation" => array("text", $this->getInvitation()),
851  "invitation_mode" => array("text", $this->getInvitationMode()),
852  "complete" => array("text", $this->isComplete()),
853  "anonymize" => array("text", $this->getAnonymize()),
854  "show_question_titles" => array("text", $this->getShowQuestionTitles()),
855  "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
856  "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : NULL),
857  "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : NULL),
858  "tstamp" => array("integer", time()),
859  "template_id" => array("integer", $this->getTemplate()),
860  "pool_usage" => array("integer", $this->getPoolUsage()),
861  // 360°
862  "mode_360" => array("integer", $this->get360Mode()),
863  "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
864  "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
865  "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
866  "mode_360_results" => array("integer", $this->get360Results()),
867  "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
868  // reminder/notification
869  "reminder_status" => array("integer", $this->getReminderStatus()),
870  "reminder_start" => array("datetime", $rmd_start),
871  "reminder_end" => array("datetime", $rmd_end),
872  "reminder_frequency" => array("integer", $this->getReminderFrequency()),
873  "reminder_target" => array("integer", $this->getReminderTarget()),
874  "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
875  "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
876  "tutor_ntf_reci" => array("text", implode(";", (array)$this->getTutorNotificationRecipients())),
877  "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget())
878  ), array(
879  "survey_id" => array("integer", $this->getSurveyId())
880  ));
881  }
882  if ($affectedRows)
883  {
884  // save questions to db
885  $this->saveQuestionsToDb();
886  }
887 
888  // moved activation to ilObjectActivation
889  if($this->ref_id)
890  {
891  include_once "./Services/Object/classes/class.ilObjectActivation.php";
892  ilObjectActivation::getItem($this->ref_id);
893 
894  $item = new ilObjectActivation;
895  if(!$this->isActivationLimited())
896  {
898  }
899  else
900  {
901  $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
902  $item->setTimingStart($this->getActivationStartDate());
903  $item->setTimingEnd($this->getActivationEndDate());
904  $item->toggleVisible($this->getActivationVisibility());
905  }
906 
907  $item->update($this->ref_id);
908  }
909  }
910 
917  function saveQuestionsToDb()
918  {
919  global $ilDB;
920  // save old questions state
921  $old_questions = array();
922  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
923  array('integer'),
924  array($this->getSurveyId())
925  );
926  if ($result->numRows())
927  {
928  while ($row = $ilDB->fetchAssoc($result))
929  {
930  $old_questions[$row["question_fi"]] = $row;
931  }
932  }
933 
934  // delete existing question relations
935  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_svy_qst WHERE survey_fi = %s",
936  array('integer'),
937  array($this->getSurveyId())
938  );
939  // create new question relations
940  foreach ($this->questions as $key => $value)
941  {
942  $next_id = $ilDB->nextId('svy_svy_qst');
943  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, heading, sequence, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
944  array('integer','integer','integer','text','integer','integer'),
945  array($next_id, $this->getSurveyId(), $value, (strlen($old_questions[$value]["heading"])) ? $old_questions[$value]["heading"] : NULL, $key, time())
946  );
947  }
948  }
949 
957  function getAnonymousId($id)
958  {
959  global $ilDB;
960  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
961  array('text'),
962  array($id)
963  );
964  if ($result->numRows())
965  {
966  $row = $ilDB->fetchAssoc($result);
967  return $row["anonymous_id"];
968  }
969  else
970  {
971  return "";
972  }
973  }
974 
981  function getQuestionGUI($questiontype, $question_id)
982  {
983  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestionGUI.php";
984  return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
985  }
986 
994  function getQuestionType($question_id)
995  {
996  global $ilDB;
997  if ($question_id < 1) return -1;
998  $result = $ilDB->queryF("SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
999  "svy_question.questiontype_fi = svy_qtype.questiontype_id",
1000  array('integer'),
1001  array($question_id)
1002  );
1003  if ($result->numRows() == 1)
1004  {
1005  $data = $ilDB->fetchAssoc($result);
1006  return $data["type_tag"];
1007  }
1008  else
1009  {
1010  return "";
1011  }
1012  }
1013 
1020  function getSurveyId()
1021  {
1022  return $this->survey_id;
1023  }
1024 
1028  function setAnonymize($a_anonymize)
1029  {
1030  switch ($a_anonymize)
1031  {
1032  case self::ANONYMIZE_OFF:
1033  case self::ANONYMIZE_ON:
1034  case self::ANONYMIZE_FREEACCESS:
1035  case self::ANONYMIZE_CODE_ALL:
1036  $this->anonymize = $a_anonymize;
1037  break;
1038  default:
1039  $this->anonymize = self::ANONYMIZE_OFF;
1040  break;
1041  }
1042  }
1043 
1049  function getAnonymize()
1050  {
1051  return ($this->anonymize) ? $this->anonymize : 0;
1052  }
1053 
1055  {
1056  if ($this->getAnonymize() == self::ANONYMIZE_CODE_ALL)
1057  {
1058  return true;
1059  }
1060  else
1061  {
1062  return false;
1063  }
1064  }
1065 
1072  {
1073  if ($this->getAnonymize() == self::ANONYMIZE_FREEACCESS || !$this->getAnonymize())
1074  {
1075  return true;
1076  }
1077  else
1078  {
1079  return false;
1080  }
1081  }
1082 
1088  function loadFromDb()
1089  {
1090  global $ilDB;
1091  $result = $ilDB->queryF("SELECT * FROM svy_svy WHERE obj_fi = %s",
1092  array('integer'),
1093  array($this->getId())
1094  );
1095  if ($result->numRows() == 1)
1096  {
1097  $data = $ilDB->fetchAssoc($result);
1098  $this->setSurveyId($data["survey_id"]);
1099  $this->setAuthor($data["author"]);
1100  include_once("./Services/RTE/classes/class.ilRTE.php");
1101  $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1102  if (strcmp($data["outro"], "survey_finished") == 0)
1103  {
1104  $this->setOutro($this->lng->txt("survey_finished"));
1105  }
1106  else
1107  {
1108  $this->setOutro(ilRTE::_replaceMediaObjectImageSrc($data["outro"], 1));
1109  }
1110  $this->setInvitation($data["invitation"]);
1111  $this->setInvitationMode($data["invitation_mode"]);
1112  $this->setShowQuestionTitles($data["show_question_titles"]);
1113  $this->setStartDate($data["startdate"]);
1114  $this->setEndDate($data["enddate"]);
1115  $this->setAnonymize($data["anonymize"]);
1116  $this->setEvaluationAccess($data["evaluation_access"]);
1117  $this->loadQuestionsFromDb();
1118  $this->setStatus($data["status"]);
1119  $this->setMailNotification($data['mailnotification']);
1120  $this->setMailAddresses($data['mailaddresses']);
1121  $this->setMailParticipantData($data['mailparticipantdata']);
1122  $this->setTemplate($data['template_id']);
1123  $this->setPoolUsage($data['pool_usage']);
1124  // 360°
1125  $this->set360Mode($data['mode_360']);
1126  $this->set360SelfEvaluation($data['mode_360_self_eval']);
1127  $this->set360SelfRaters($data['mode_360_self_rate']);
1128  $this->set360SelfAppraisee($data['mode_360_self_appr']);
1129  $this->set360Results($data['mode_360_results']);
1130  $this->set360SkillService($data['mode_360_skill_service']);
1131  // reminder/notification
1132  $this->setReminderStatus($data["reminder_status"]);
1133  $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1134  $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1135  $this->setReminderFrequency($data["reminder_frequency"]);
1136  $this->setReminderTarget($data["reminder_target"]);
1137  $this->setReminderLastSent($data["reminder_last_sent"]);
1138  $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1139  $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1140  $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1141  }
1142 
1143  // moved activation to ilObjectActivation
1144  if($this->ref_id)
1145  {
1146  include_once "./Services/Object/classes/class.ilObjectActivation.php";
1147  $activation = ilObjectActivation::getItem($this->ref_id);
1148  switch($activation["timing_type"])
1149  {
1151  $this->setActivationLimited(true);
1152  $this->setActivationStartDate($activation["timing_start"]);
1153  $this->setActivationEndDate($activation["timing_end"]);
1154  $this->setActivationVisibility($activation["visible"]);
1155  break;
1156 
1157  default:
1158  $this->setActivationLimited(false);
1159  break;
1160  }
1161  }
1162  }
1163 
1171  {
1172  global $ilDB;
1173  $this->questions = array();
1174  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1175  array('integer'),
1176  array($this->getSurveyId())
1177  );
1178  while ($data = $ilDB->fetchAssoc($result))
1179  {
1180  $this->questions[$data["sequence"]] = $data["question_fi"];
1181  }
1182  }
1183 
1191  function setAuthor($author = "")
1192  {
1193  $this->author = $author;
1194  }
1195 
1205  function saveAuthorToMetadata($a_author = "")
1206  {
1207  $md =& new ilMD($this->getId(), 0, $this->getType());
1208  $md_life =& $md->getLifecycle();
1209  if (!$md_life)
1210  {
1211  if (strlen($a_author) == 0)
1212  {
1213  global $ilUser;
1214  $a_author = $ilUser->getFullname();
1215  }
1216 
1217  $md_life =& $md->addLifecycle();
1218  $md_life->save();
1219  $con =& $md_life->addContribute();
1220  $con->setRole("Author");
1221  $con->save();
1222  $ent =& $con->addEntity();
1223  $ent->setEntity($a_author);
1224  $ent->save();
1225  }
1226  }
1227 
1235  function getAuthor()
1236  {
1237  $author = array();
1238  include_once "./Services/MetaData/classes/class.ilMD.php";
1239  $md =& new ilMD($this->getId(), 0, $this->getType());
1240  $md_life =& $md->getLifecycle();
1241  if ($md_life)
1242  {
1243  $ids =& $md_life->getContributeIds();
1244  foreach ($ids as $id)
1245  {
1246  $md_cont =& $md_life->getContribute($id);
1247  if (strcmp($md_cont->getRole(), "Author") == 0)
1248  {
1249  $entids =& $md_cont->getEntityIds();
1250  foreach ($entids as $entid)
1251  {
1252  $md_ent =& $md_cont->getEntity($entid);
1253  array_push($author, $md_ent->getEntity());
1254  }
1255  }
1256  }
1257  }
1258  return join($author, ",");
1259  }
1260 
1267  public function getShowQuestionTitles()
1268  {
1269  return ($this->display_question_titles) ? 1 : 0;
1270  }
1271 
1278  public function setShowQuestionTitles($a_show)
1279  {
1280  $this->display_question_titles = ($a_show) ? 1 : 0;
1281  }
1282 
1290  {
1291  $this->display_question_titles = 1;
1292  }
1293 
1301  {
1302  $this->display_question_titles = 0;
1303  }
1304 
1313  {
1314  global $ilDB;
1315  global $ilAccess;
1316  $this->invitation = $invitation;
1318  {
1319  $this->disinviteAllUsers();
1320  }
1321  else if ($invitation == self::INVITATION_ON)
1322  {
1323  if ($this->getInvitationMode() == self::MODE_UNLIMITED)
1324  {
1325  $result = $ilDB->query("SELECT usr_id FROM usr_data");
1326  while ($row = $ilDB->fetchAssoc($result))
1327  {
1328  if ($ilAccess->checkAccessOfUser($row["usr_id"], "read", "", $this->getRefId(), "svy", $this->getId()))
1329  {
1330  $this->inviteUser($row['usr_id']);
1331  }
1332  }
1333  }
1334  }
1335  }
1336 
1345  {
1346  $this->invitation_mode = $invitation_mode;
1347  }
1348 
1358  {
1359  $this->invitation_mode = $invitation_mode;
1360  $this->setInvitation($invitation);
1361  }
1362 
1369  public function setIntroduction($introduction = "")
1370  {
1371  $this->introduction = $introduction;
1372  }
1373 
1380  public function setOutro($outro = "")
1381  {
1382  $this->outro = $outro;
1383  }
1384 
1392  function getInvitation()
1393  {
1394  return ($this->invitation) ? $this->invitation : self::INVITATION_OFF;
1395  }
1396 
1404  function getInvitationMode()
1405  {
1406  include_once "./Services/Administration/classes/class.ilSetting.php";
1407  $surveySetting = new ilSetting("survey");
1408  $unlimited_invitation = $surveySetting->get("unlimited_invitation");
1409  if (!$unlimited_invitation && $this->invitation_mode == self::MODE_UNLIMITED)
1410  {
1412  }
1413  else
1414  {
1415  return ($this->invitation_mode) ? $this->invitation_mode : self::MODE_UNLIMITED;
1416  }
1417  }
1418 
1426  function getStatus()
1427  {
1428  return ($this->status) ? $this->status : self::STATUS_OFFLINE;
1429  }
1430 
1438  function isOnline()
1439  {
1440  return ($this->status == self::STATUS_ONLINE) ? true : false;
1441  }
1442 
1450  function isOffline()
1451  {
1452  return ($this->status == self::STATUS_OFFLINE) ? true : false;
1453  }
1454 
1463  function setStatus($status = self::STATUS_OFFLINE)
1464  {
1465  $result = "";
1466  if (($status == self::STATUS_ONLINE) && (count($this->questions) == 0))
1467  {
1468  $this->status = self::STATUS_OFFLINE;
1469  $result = $this->lng->txt("cannot_switch_to_online_no_questions");
1470  }
1471  else
1472  {
1473  $this->status = $status;
1474  }
1475  return $result;
1476  }
1477 
1485  function getStartDate()
1486  {
1487  return (strlen($this->start_date)) ? $this->start_date : NULL;
1488  }
1489 
1496  function canStartSurvey($anonymous_id = NULL, $a_no_rbac = false)
1497  {
1498  global $ilAccess;
1499 
1500  $result = TRUE;
1501  $messages = array();
1502  $edit_settings = false;
1503  // check start date
1504  if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches))
1505  {
1506  $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1507  $now = mktime();
1508  if ($now < $epoch_time)
1509  {
1510  array_push($messages,$this->lng->txt('start_date_not_reached').' ('.
1512  $result = FALSE;
1513  $edit_settings = true;
1514  }
1515  }
1516  // check end date
1517  if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches))
1518  {
1519  $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1520  $now = mktime();
1521  if ($now > $epoch_time)
1522  {
1523  array_push($messages,$this->lng->txt('end_date_reached').' ('.
1525  $result = FALSE;
1526  $edit_settings = true;
1527  }
1528  }
1529 
1530  // check online status
1531  if ($this->getStatus() == self::STATUS_OFFLINE)
1532  {
1533  array_push($messages, $this->lng->txt("survey_is_offline"));
1534  $result = FALSE;
1535  $edit_settings = true;
1536  }
1537  // check rbac permissions
1538  if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id))
1539  {
1540  array_push($messages, $this->lng->txt("cannot_participate_survey"));
1541  $result = FALSE;
1542  }
1543  /*
1544  // 2. check previous access
1545  if (!$result["error"])
1546  {
1547  global $ilUser;
1548  $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1549  if ($survey_started === 1)
1550  {
1551  array_push($messages, $this->lng->txt("already_completed_survey"));
1552  $result = FALSE;
1553  }
1554  }
1555  */
1556  return array(
1557  "result" => $result,
1558  "messages" => $messages,
1559  "edit_settings" => $edit_settings
1560  );
1561  }
1562 
1570  function setStartDate($start_date = "")
1571  {
1572  $this->start_date = $start_date;
1573  }
1574 
1583  function setStartDateAndTime($start_date = "", $start_time)
1584  {
1585  $y = ''; $m = ''; $d = ''; $h = ''; $i = ''; $s = '';
1586  if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches))
1587  {
1588  $y = $matches[1];
1589  $m = $matches[2];
1590  $d = $matches[3];
1591  }
1592  if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches))
1593  {
1594  $h = $matches[1];
1595  $i = $matches[2];
1596  $s = $matches[3];
1597  }
1598  $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1599  }
1600 
1608  function getEndDate()
1609  {
1610  return (strlen($this->end_date)) ? $this->end_date : NULL;
1611  }
1612 
1620  function setEndDate($end_date = "")
1621  {
1622  $this->end_date = $end_date;
1623  }
1624 
1633  function setEndDateAndTime($end_date = "", $end_time)
1634  {
1635  $y = ''; $m = ''; $d = ''; $h = ''; $i = ''; $s = '';
1636  if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches))
1637  {
1638  $y = $matches[1];
1639  $m = $matches[2];
1640  $d = $matches[3];
1641  }
1642  if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches))
1643  {
1644  $h = $matches[1];
1645  $i = $matches[2];
1646  $s = $matches[3];
1647  }
1648  $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1649  }
1650 
1659  {
1660  return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1661  }
1662 
1670  function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1671  {
1672  $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1673  }
1674 
1675  function setActivationVisibility($a_value)
1676  {
1677  $this->activation_visibility = (bool) $a_value;
1678  }
1679 
1681  {
1683  }
1684 
1686  {
1687  return (bool)$this->activation_limited;
1688  }
1689 
1690  function setActivationLimited($a_value)
1691  {
1692  $this->activation_limited = (bool)$a_value;
1693  }
1694 
1702  function getIntroduction()
1703  {
1704  return (strlen($this->introduction)) ? $this->introduction : NULL;
1705  }
1706 
1714  function getOutro()
1715  {
1716  return (strlen($this->outro)) ? $this->outro : NULL;
1717  }
1718 
1726  {
1727  global $ilDB;
1728  $existing_questions = array();
1729  $result = $ilDB->queryF("SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1730  "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1731  array('integer'),
1732  array($this->getSurveyId())
1733  );
1734  while ($data = $ilDB->fetchAssoc($result))
1735  {
1736  if($data["original_id"])
1737  {
1738  array_push($existing_questions, $data["original_id"]);
1739  }
1740  }
1741  return $existing_questions;
1742  }
1743 
1750  function &getQuestionpoolTitles($could_be_offline = FALSE, $showPath = FALSE)
1751  {
1752  include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
1753  return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = TRUE, $could_be_offline, $showPath);
1754  }
1755 
1762  function moveUpQuestion($question_id)
1763  {
1764  $move_questions = array($question_id);
1765  $pages =& $this->getSurveyPages();
1766  $pageindex = -1;
1767  foreach ($pages as $idx => $page)
1768  {
1769  if ($page[0]["question_id"] == $question_id)
1770  {
1771  $pageindex = $idx;
1772  }
1773  }
1774  if ($pageindex > 0)
1775  {
1776  $this->moveQuestions($move_questions, $pages[$pageindex-1][0]["question_id"], 0);
1777  }
1778  else
1779  {
1780  // move up a question in a questionblock
1781  $questions = $this->getSurveyQuestions();
1782  $questions = array_keys($questions);
1783  $index = array_search($question_id, $questions);
1784  if (($index !== FALSE) && ($index > 0))
1785  {
1786  $this->moveQuestions($move_questions, $questions[$index-1], 0);
1787  }
1788  }
1789  }
1790 
1796  public function moveDownQuestion($question_id)
1797  {
1798  $move_questions = array($question_id);
1799  $pages =& $this->getSurveyPages();
1800  $pageindex = -1;
1801  foreach ($pages as $idx => $page)
1802  {
1803  if (($page[0]["question_id"] == $question_id) && (strcmp($page[0]["questionblock_id"], "") == 0))
1804  {
1805  $pageindex = $idx;
1806  }
1807  }
1808  if (($pageindex < count($pages)-1) && ($pageindex >= 0))
1809  {
1810  $this->moveQuestions($move_questions, $pages[$pageindex+1][count($pages[$pageindex+1])-1]["question_id"], 1);
1811  }
1812  else
1813  {
1814  // move down a question in a questionblock
1815  $questions = $this->getSurveyQuestions();
1816  $questions = array_keys($questions);
1817  $index = array_search($question_id, $questions);
1818  if (($index !== FALSE) && ($index < count($questions)-1))
1819  {
1820  $this->moveQuestions($move_questions, $questions[$index+1], 1);
1821  }
1822  }
1823  }
1824 
1831  function moveUpQuestionblock($questionblock_id)
1832  {
1833  $pages =& $this->getSurveyPages();
1834  $move_questions = array();
1835  $pageindex = -1;
1836  foreach ($pages as $idx => $page)
1837  {
1838  if ($page[0]["questionblock_id"] == $questionblock_id)
1839  {
1840  foreach ($page as $pageidx => $question)
1841  {
1842  array_push($move_questions, $question["question_id"]);
1843  }
1844  $pageindex = $idx;
1845  }
1846  }
1847  if ($pageindex > 0)
1848  {
1849  $this->moveQuestions($move_questions, $pages[$pageindex-1][0]["question_id"], 0);
1850  }
1851  }
1852 
1859  function moveDownQuestionblock($questionblock_id)
1860  {
1861  $pages =& $this->getSurveyPages();
1862  $move_questions = array();
1863  $pageindex = -1;
1864  foreach ($pages as $idx => $page)
1865  {
1866  if ($page[0]["questionblock_id"] == $questionblock_id)
1867  {
1868  foreach ($page as $pageidx => $question)
1869  {
1870  array_push($move_questions, $question["question_id"]);
1871  }
1872  $pageindex = $idx;
1873  }
1874  }
1875  if ($pageindex < count($pages)-1)
1876  {
1877  $this->moveQuestions($move_questions, $pages[$pageindex+1][count($pages[$pageindex+1])-1]["question_id"], 1);
1878  }
1879  }
1880 
1889  function moveQuestions($move_questions, $target_index, $insert_mode)
1890  {
1891  $array_pos = array_search($target_index, $this->questions);
1892  if ($insert_mode == 0)
1893  {
1894  $part1 = array_slice($this->questions, 0, $array_pos);
1895  $part2 = array_slice($this->questions, $array_pos);
1896  }
1897  else if ($insert_mode == 1)
1898  {
1899  $part1 = array_slice($this->questions, 0, $array_pos + 1);
1900  $part2 = array_slice($this->questions, $array_pos + 1);
1901  }
1902  foreach ($move_questions as $question_id)
1903  {
1904  if (!(array_search($question_id, $part1) === FALSE))
1905  {
1906  unset($part1[array_search($question_id, $part1)]);
1907  }
1908  if (!(array_search($question_id, $part2) === FALSE))
1909  {
1910  unset($part2[array_search($question_id, $part2)]);
1911  }
1912  }
1913  $part1 = array_values($part1);
1914  $part2 = array_values($part2);
1915  $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1916  foreach ($move_questions as $question_id)
1917  {
1918  $constraints = $this->getConstraints($question_id);
1919  foreach ($constraints as $idx => $constraint)
1920  {
1921  foreach ($part2 as $next_question_id)
1922  {
1923  if ($constraint["question"] == $next_question_id)
1924  {
1925  // constraint concerning a question that follows -> delete constraint
1926  $this->deleteConstraint($constraint["id"]);
1927  }
1928  }
1929  }
1930  }
1931  $this->saveQuestionsToDb();
1932  }
1933 
1940  function removeQuestion($question_id)
1941  {
1942  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
1943  $question =& $this->_instanciateQuestion($question_id);
1944  $question->delete($question_id);
1945  $this->removeConstraintsConcerningQuestion($question_id);
1946  }
1947 
1955  {
1956  global $ilDB;
1957  $result = $ilDB->queryF("SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1958  array('integer','integer'),
1959  array($question_id, $this->getSurveyId())
1960  );
1961  if ($result->numRows() > 0)
1962  {
1963  $remove_constraints = array();
1964  while ($row = $ilDB->fetchAssoc($result))
1965  {
1966  array_push($remove_constraints, $row["constraint_fi"]);
1967  }
1968  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1969  array('integer','integer'),
1970  array($question_id, $this->getSurveyId())
1971  );
1972  foreach ($remove_constraints as $key => $constraint_id)
1973  {
1974  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_constraint WHERE constraint_id = %s",
1975  array('integer'),
1976  array($constraint_id)
1977  );
1978  }
1979  }
1980  }
1981 
1989  function removeQuestions($remove_questions, $remove_questionblocks)
1990  {
1991  global $ilDB;
1992 
1993  $block_sizes = array();
1994  foreach ($this->getSurveyQuestions() as $question_id => $data)
1995  {
1996  if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks))
1997  {
1998  unset($this->questions[array_search($question_id, $this->questions)]);
1999  $this->removeQuestion($question_id);
2000  }
2001  else if($data["questionblock_id"])
2002  {
2003  $block_sizes[$data["questionblock_id"]]++;
2004  }
2005  }
2006 
2007  // blocks with just 1 question need to be deleted
2008  foreach($block_sizes as $block_id => $size)
2009  {
2010  if($size < 2)
2011  {
2012  $remove_questionblocks[] = $block_id;
2013  }
2014  }
2015 
2016  foreach (array_unique($remove_questionblocks) as $questionblock_id)
2017  {
2018  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk WHERE questionblock_id = %s",
2019  array('integer'),
2020  array($questionblock_id)
2021  );
2022  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
2023  array('integer','integer'),
2024  array($questionblock_id, $this->getSurveyId())
2025  );
2026  }
2027 
2028  $this->questions = array_values($this->questions);
2029  $this->saveQuestionsToDb();
2030  }
2031 
2038  function unfoldQuestionblocks($questionblocks)
2039  {
2040  global $ilDB;
2041  foreach ($questionblocks as $index)
2042  {
2043  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk WHERE questionblock_id = %s",
2044  array('integer'),
2045  array($index)
2046  );
2047  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
2048  array('integer','integer'),
2049  array($index, $this->getSurveyId())
2050  );
2051  }
2052  }
2053 
2054  function removeQuestionFromBlock($question_id, $questionblock_id)
2055  {
2056  global $ilDB;
2057 
2058  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
2059  array('integer','integer','integer'),
2060  array($questionblock_id, $this->getSurveyId(), $question_id)
2061  );
2062  }
2063 
2064  function addQuestionToBlock($question_id, $questionblock_id)
2065  {
2066  global $ilDB;
2067 
2068 
2069  $next_id = $ilDB->nextId('svy_qblk_qst');
2070  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2071  "question_fi) VALUES (%s, %s, %s, %s)",
2072  array('integer','integer','integer','integer'),
2073  array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
2074  );
2075 
2076  $this->deleteConstraints($question_id); // #13713
2077  }
2078 
2085  function &getQuestionblockQuestions($questionblock_id)
2086  {
2087  global $ilDB;
2088  $titles = array();
2089  $result = $ilDB->queryF("SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM ".
2090  "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
2091  "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
2092  array('integer'),
2093  array($questionblock_id)
2094  );
2095  $survey_id = "";
2096  while ($row = $ilDB->fetchAssoc($result))
2097  {
2098  $titles[$row["question_fi"]] = $row["title"];
2099  $survey_id = $row["survey_fi"];
2100  }
2101  $result = $ilDB->queryF("SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
2102  array('integer'),
2103  array($survey_id)
2104  );
2105  $resultarray = array();
2106  $counter = 1;
2107  while ($row = $ilDB->fetchAssoc($result))
2108  {
2109  if (array_key_exists($row["question_fi"], $titles))
2110  {
2111  $resultarray[$counter++] = $titles[$row["question_fi"]];
2112  }
2113  }
2114  return $resultarray;
2115  }
2116 
2123  function &getQuestionblockQuestionIds($questionblock_id)
2124  {
2125  global $ilDB;
2126  $result = $ilDB->queryF("SELECT question_fi FROM svy_qblk_qst WHERE questionblock_fi = %s",
2127  array("integer"),
2128  array($questionblock_id)
2129  );
2130  $ids = array();
2131  if ($result->numRows())
2132  {
2133  while ($data = $ilDB->fetchAssoc($result))
2134  {
2135  array_push($ids, $data['question_fi']);
2136  }
2137  }
2138  return $ids;
2139  }
2140 
2148  function getQuestionblock($questionblock_id)
2149  {
2150  global $ilDB;
2151  $result = $ilDB->queryF("SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2152  array('integer'),
2153  array($questionblock_id)
2154  );
2155  return $ilDB->fetchAssoc($result);
2156  }
2157 
2165  function _getQuestionblock($questionblock_id)
2166  {
2167  global $ilDB;
2168  $result = $ilDB->queryF("SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2169  array('integer'),
2170  array($questionblock_id)
2171  );
2172  $row = $ilDB->fetchAssoc($result);
2173  return $row;
2174  }
2175 
2184  function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false)
2185  {
2186  global $ilDB;
2187  $next_id = $ilDB->nextId('svy_qblk');
2188  $ilDB->manipulateF("INSERT INTO svy_qblk (questionblock_id, title, show_questiontext,".
2189  " show_blocktitle, owner_fi, tstamp) " .
2190  "VALUES (%s, %s, %s, %s, %s, %s)",
2191  array('integer','text','integer','integer','integer','integer'),
2192  array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time())
2193  );
2194  return $next_id;
2195  }
2196 
2204  function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
2205  {
2206  global $ilDB;
2207 
2208  // if the selected questions are not in a continous selection, move all questions of the
2209  // questionblock at the position of the first selected question
2210  $this->moveQuestions($questions, $questions[0], 0);
2211 
2212  // now save the question block
2213  global $ilUser;
2214  $next_id = $ilDB->nextId('svy_qblk');
2215  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk (questionblock_id, title, show_questiontext,".
2216  " show_blocktitle, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
2217  array('integer','text','text','text','integer','integer'),
2218  array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time())
2219  );
2220  if ($affectedRows)
2221  {
2222  $questionblock_id = $next_id;
2223  foreach ($questions as $index)
2224  {
2225  $next_id = $ilDB->nextId('svy_qblk_qst');
2226  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2227  "question_fi) VALUES (%s, %s, %s, %s)",
2228  array('integer','integer','integer','integer'),
2229  array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2230  );
2231  $this->deleteConstraints($index);
2232  }
2233  }
2234  }
2235 
2243  function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
2244  {
2245  global $ilDB;
2246  $affectedRows = $ilDB->manipulateF("UPDATE svy_qblk SET title = %s, show_questiontext = %s,".
2247  " show_blocktitle = %s WHERE questionblock_id = %s",
2248  array('text','text','text','integer'),
2249  array($title, $show_questiontext, $show_blocktitle, $questionblock_id)
2250  );
2251  }
2252 
2259  function deleteConstraints($question_id)
2260  {
2261  global $ilDB;
2262  $result = $ilDB->queryF("SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2263  array('integer','integer'),
2264  array($question_id, $this->getSurveyId())
2265  );
2266  $constraints = array();
2267  while ($row = $ilDB->fetchAssoc($result))
2268  {
2269  array_push($constraints, $row["constraint_fi"]);
2270  }
2271  foreach ($constraints as $constraint_id)
2272  {
2273  $this->deleteConstraint($constraint_id);
2274  }
2275  }
2276 
2284  function deleteConstraint($constraint_id)
2285  {
2286  global $ilDB;
2287  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_constraint WHERE constraint_id = %s",
2288  array('integer'),
2289  array($constraint_id)
2290  );
2291  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2292  array('integer'),
2293  array($constraint_id)
2294  );
2295  }
2296 
2302  public function &getSurveyQuestions($with_answers = false)
2303  {
2304  global $ilDB;
2305  $obligatory_states =& $this->getObligatoryStates();
2306  // get questionblocks
2307  $all_questions = array();
2308  $result = $ilDB->queryF("SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, ".
2309  "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2310  "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2311  "ORDER BY svy_svy_qst.sequence",
2312  array('integer'),
2313  array($this->getSurveyId())
2314  );
2315  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2316  while ($row = $ilDB->fetchAssoc($result))
2317  {
2318  $add = true;
2319  if ($row["plugin"])
2320  {
2321  if (!$this->isPluginActive($row["type_tag"]))
2322  {
2323  $add = false;
2324  }
2325  }
2326  if ($add)
2327  {
2328  $question =& $this->_instanciateQuestion($row["question_id"]);
2329  $questionrow = $question->_getQuestionDataArray($row["question_id"]);
2330  foreach ($row as $key => $value)
2331  {
2332  $questionrow[$key] = $value;
2333  }
2334  $all_questions[$row["question_id"]] = $questionrow;
2335  $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2336  $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2337  if (array_key_exists($row["question_id"], $obligatory_states))
2338  {
2339  $all_questions[$row["question_id"]]["obligatory"] = $obligatory_states[$row["question_id"]];
2340  }
2341  }
2342  }
2343  // get all questionblocks
2344  $questionblocks = array();
2345  if (count($all_questions))
2346  {
2347  $result = $ilDB->queryF("SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2348  "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2349  "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2350  array('integer'),
2351  array($this->getSurveyId())
2352  );
2353  while ($row = $ilDB->fetchAssoc($result))
2354  {
2355  $questionblocks[$row['question_fi']] = $row;
2356  }
2357  }
2358 
2359  foreach ($all_questions as $question_id => $row)
2360  {
2361  $constraints = $this->getConstraints($question_id);
2362  if (isset($questionblocks[$question_id]))
2363  {
2364  $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2365  $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2366  $all_questions[$question_id]["constraints"] = $constraints;
2367  }
2368  else
2369  {
2370  $all_questions[$question_id]["questionblock_title"] = "";
2371  $all_questions[$question_id]["questionblock_id"] = "";
2372  $all_questions[$question_id]["constraints"] = $constraints;
2373  }
2374  if ($with_answers)
2375  {
2376  $answers = array();
2377  $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2378  "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id ".
2379  "ORDER BY sequence ASC",
2380  array('integer'),
2381  array($question_id)
2382  );
2383  if ($result->numRows() > 0)
2384  {
2385  while ($data = $ilDB->fetchAssoc($result))
2386  {
2387  array_push($answers, $data["title"]);
2388  }
2389  }
2390  $all_questions[$question_id]["answers"] = $answers;
2391  }
2392  }
2393  return $all_questions;
2394  }
2395 
2402  function setObligatoryStates($obligatory_questions)
2403  {
2404  global $ilDB;
2405  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2406  array('integer'),
2407  array($this->getSurveyId())
2408  );
2409  if ($result->numRows())
2410  {
2411  while ($row = $ilDB->fetchAssoc($result))
2412  {
2413  if (!array_key_exists($row["question_fi"], $obligatory_questions))
2414  {
2415  $obligatory_questions[$row["question_fi"]] = 0;
2416  }
2417  }
2418  }
2419 
2420  // set the obligatory states in the database
2421  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_oblig WHERE survey_fi = %s",
2422  array('integer'),
2423  array($this->getSurveyId())
2424  );
2425 
2426  // set the obligatory states in the database
2427  foreach ($obligatory_questions as $question_fi => $obligatory)
2428  {
2429  $next_id = $ilDB->nextId('svy_qst_oblig');
2430  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_oblig (question_obligatory_id, survey_fi, question_fi, " .
2431  "obligatory, tstamp) VALUES (%s, %s, %s, %s, %s)",
2432  array('integer','integer','integer','text','integer'),
2433  array($next_id, $this->getSurveyId(), $question_fi, (strlen($obligatory)) ? $obligatory : 0, time())
2434  );
2435 
2436  // #12420
2437  $ilDB->manipulate("UPDATE svy_question".
2438  " SET obligatory = ".$ilDB->quote($obligatory, "integer").
2439  " WHERE question_id = ".$ilDB->quote($question_fi, "integer"));
2440  }
2441  }
2442 
2450  {
2451  global $ilDB;
2452  $obligatory_states = array();
2453  $result = $ilDB->queryF("SELECT * FROM svy_qst_oblig WHERE survey_fi = %s",
2454  array('integer'),
2455  array($this->getSurveyId())
2456  );
2457  if ($result->numRows())
2458  {
2459  while ($row = $ilDB->fetchAssoc($result))
2460  {
2461  $obligatory_states[$row["question_fi"]] = $row["obligatory"];
2462  }
2463  }
2464  return $obligatory_states;
2465  }
2466 
2472  function &getSurveyPages()
2473  {
2474  global $ilDB;
2475  $obligatory_states =& $this->getObligatoryStates();
2476  // get questionblocks
2477  $all_questions = array();
2478  $result = $ilDB->queryF("SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2479  "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2480  "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id ".
2481  "ORDER BY svy_svy_qst.sequence",
2482  array('integer'),
2483  array($this->getSurveyId())
2484  );
2485  while ($row = $ilDB->fetchAssoc($result))
2486  {
2487  $all_questions[$row["question_id"]] = $row;
2488  }
2489  // get all questionblocks
2490  $questionblocks = array();
2491  if (count($all_questions))
2492  {
2493  $result = $ilDB->queryF("SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst ".
2494  "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s ".
2495  "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2496  array('integer'),
2497  array($this->getSurveyId())
2498  );
2499  while ($row = $ilDB->fetchAssoc($result))
2500  {
2501  $questionblocks[$row['question_fi']] = $row;
2502  }
2503  }
2504 
2505  $all_pages = array();
2506  $pageindex = -1;
2507  $currentblock = "";
2508  foreach ($all_questions as $question_id => $row)
2509  {
2510  if (array_key_exists($question_id, $obligatory_states))
2511  {
2512  $all_questions[$question_id]["obligatory"] = $obligatory_states[$question_id];
2513  }
2514  $constraints = array();
2515  if (isset($questionblocks[$question_id]))
2516  {
2517  if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id']))
2518  {
2519  $pageindex++;
2520  }
2521  $all_questions[$question_id]['page'] = $pageindex;
2522  $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2523  $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2524  $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2525  $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2526  $currentblock = $questionblocks[$question_id]['questionblock_id'];
2527  $constraints = $this->getConstraints($question_id);
2528  $all_questions[$question_id]["constraints"] = $constraints;
2529  }
2530  else
2531  {
2532  $pageindex++;
2533  $all_questions[$question_id]['page'] = $pageindex;
2534  $all_questions[$question_id]["questionblock_title"] = "";
2535  $all_questions[$question_id]["questionblock_id"] = "";
2536  $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2537  $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2538  $currentblock = "";
2539  $constraints = $this->getConstraints($question_id);
2540  $all_questions[$question_id]["constraints"] = $constraints;
2541  }
2542  if (!isset($all_pages[$pageindex]))
2543  {
2544  $all_pages[$pageindex] = array();
2545  }
2546  array_push($all_pages[$pageindex], $all_questions[$question_id]);
2547  }
2548  // calculate position percentage for every page
2549  $max = count($all_pages);
2550  $counter = 1;
2551  foreach ($all_pages as $index => $block)
2552  {
2553  foreach ($block as $blockindex => $question)
2554  {
2555  $all_pages[$index][$blockindex]["position"] = $counter / $max;
2556  }
2557  $counter++;
2558  }
2559  return $all_pages;
2560  }
2561 
2570  function getNextPage($active_page_question_id, $direction)
2571  {
2572  $foundpage = -1;
2573  $pages =& $this->getSurveyPages();
2574  if (strcmp($active_page_question_id, "") == 0)
2575  {
2576  return $pages[0];
2577  }
2578  foreach ($pages as $key => $question_array)
2579  {
2580  foreach ($question_array as $question)
2581  {
2582  if ($active_page_question_id == $question["question_id"])
2583  {
2584  $foundpage = $key;
2585  }
2586  }
2587  }
2588  if ($foundpage == -1)
2589  {
2590  // error: page not found
2591  }
2592  else
2593  {
2594  $foundpage += $direction;
2595  if ($foundpage < 0)
2596  {
2597  return 0;
2598  }
2599  if ($foundpage >= count($pages))
2600  {
2601  return 1;
2602  }
2603  return $pages[$foundpage];
2604  }
2605  }
2606 
2613  function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = FALSE, $permission = "read")
2614  {
2615  include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
2616  return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2617  }
2618 
2625  {
2626  global $ilDB;
2627 
2628  $result_array = array();
2629  $result = $ilDB->queryF("SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, ".
2630  "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND ".
2631  "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2632  array('integer'),
2633  array($id)
2634  );
2635  $pc = array();
2636  if ($result->numRows())
2637  {
2638  $pc = $ilDB->fetchAssoc($result);
2639  }
2640  return $pc;
2641  }
2642 
2648  function getConstraints($question_id)
2649  {
2650  global $ilDB;
2651 
2652  $result_array = array();
2653  $result = $ilDB->queryF("SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation ".
2654  "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND ".
2655  "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s ".
2656  "AND svy_qst_constraint.survey_fi = %s",
2657  array('integer','integer'),
2658  array($question_id, $this->getSurveyId())
2659  );
2660  while ($row = $ilDB->fetchAssoc($result))
2661  {
2662  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2663  $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2664  SurveyQuestion::_includeClass($question_type);
2665  $question = new $question_type();
2666  $question->loadFromDb($row["question_fi"]);
2667  $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2668  array_push($result_array, array("id" => $row["constraint_id"], "question" => $row["question_fi"], "short" => $row["shortname"], "long" => $row["longname"], "value" => $row["value"], "conjunction" => $row["conjunction"], "valueoutput" => $valueoutput));
2669  }
2670  return $result_array;
2671  }
2672 
2679  {
2680  global $ilDB;
2681  $result_array = array();
2682  $result = $ilDB->queryF("SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* ".
2683  "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id ".
2684  "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2685  array('integer'),
2686  array($survey_id)
2687  );
2688  while ($row = $ilDB->fetchAssoc($result))
2689  {
2690  array_push($result_array, array("id" => $row["constraint_id"], "for_question" => $row["for_question"], "question" => $row["question_fi"], "short" => $row["shortname"], "long" => $row["longname"], "relation_id" => $row["relation_id"], "value" => $row["value"], 'conjunction' => $row['conjunction']));
2691  }
2692  return $result_array;
2693  }
2694 
2695 
2701  function &getVariables($question_id)
2702  {
2703  global $ilDB;
2704 
2705  $result_array = array();
2706  $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN ".
2707  "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s ".
2708  "ORDER BY svy_variable.sequence",
2709  array('integer'),
2710  array($question_id)
2711  );
2712  while ($row = $ilDB->fetchObject($result))
2713  {
2714  $result_array[$row->sequence] = $row;
2715  }
2716  return $result_array;
2717  }
2718 
2727  function addConstraint($if_question_id, $relation, $value, $conjunction)
2728  {
2729  global $ilDB;
2730 
2731  $next_id = $ilDB->nextId('svy_constraint');
2732  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES ".
2733  "(%s, %s, %s, %s, %s)",
2734  array('integer','integer','integer','float', 'integer'),
2735  array($next_id, $if_question_id, $relation, $value, $conjunction)
2736  );
2737  if ($affectedRows)
2738  {
2739  return $next_id;
2740  }
2741  else
2742  {
2743  return null;
2744  }
2745  }
2746 
2747 
2754  public function addConstraintToQuestion($to_question_id, $constraint_id)
2755  {
2756  global $ilDB;
2757 
2758  $next_id = $ilDB->nextId('svy_qst_constraint');
2759  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, ".
2760  "constraint_fi) VALUES (%s, %s, %s, %s)",
2761  array('integer','integer','integer','integer'),
2762  array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2763  );
2764  }
2765 
2776  function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2777  {
2778  global $ilDB;
2779  $affectedRows = $ilDB->manipulateF("UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s ".
2780  "WHERE constraint_id = %s",
2781  array('integer','integer','float','integer','integer'),
2782  array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2783  );
2784  }
2785 
2786  public function updateConjunctionForQuestions($questions, $conjunction)
2787  {
2788  global $ilDB;
2789  foreach ($questions as $question_id)
2790  {
2791  $affectedRows = $ilDB->manipulateF("UPDATE svy_constraint SET conjunction = %s ".
2792  "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2793  array('integer','integer'),
2794  array($conjunction, $question_id)
2795  );
2796  }
2797  }
2798 
2804  function getAllRelations($short_as_key = false)
2805  {
2806  global $ilDB;
2807 
2808  // #7987
2809  $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2810  $custom_order = array_flip($custom_order);
2811 
2812  $result_array = array();
2813  $result = $ilDB->query("SELECT * FROM svy_relation");
2814  while ($row = $ilDB->fetchAssoc($result))
2815  {
2816  if ($short_as_key)
2817  {
2818  $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2819  }
2820  else
2821  {
2822  $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2823  }
2824  }
2825 
2826  $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2827  foreach($result_array as $idx => $item)
2828  {
2829  unset($result_array[$idx]["order"]);
2830  }
2831 
2832  return $result_array;
2833  }
2834 
2838  public function disinviteAllUsers()
2839  {
2840  global $ilDB;
2841  $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2842  array('integer'),
2843  array($this->getSurveyId())
2844  );
2845  while ($row = $ilDB->fetchAssoc($result))
2846  {
2847  $this->disinviteUser($row['user_fi']);
2848  }
2849  }
2850 
2856  public function disinviteUser($user_id)
2857  {
2858  global $ilDB;
2859 
2860  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_inv_usr WHERE survey_fi = %s AND user_fi = %s",
2861  array('integer','integer'),
2862  array($this->getSurveyId(), $user_id)
2863  );
2864  include_once './Services/User/classes/class.ilObjUser.php';
2865  ilObjUser::_dropDesktopItem($user_id, $this->getRefId(), "svy");
2866  }
2867 
2874  function inviteUser($user_id)
2875  {
2876  global $ilDB;
2877 
2878  $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE user_fi = %s AND survey_fi = %s",
2879  array('integer','integer'),
2880  array($user_id, $this->getSurveyId())
2881  );
2882  if ($result->numRows() < 1)
2883  {
2884  $next_id = $ilDB->nextId('svy_inv_usr');
2885  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_inv_usr (invited_user_id, survey_fi, user_fi, tstamp) " .
2886  "VALUES (%s, %s, %s, %s)",
2887  array('integer','integer','integer','integer'),
2888  array($next_id, $this->getSurveyId(), $user_id, time())
2889  );
2890  }
2891  if ($this->getInvitation() == self::INVITATION_ON)
2892  {
2893  include_once './Services/User/classes/class.ilObjUser.php';
2894  ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2895  }
2896  }
2897 
2904  function inviteGroup($group_id)
2905  {
2906  global $ilAccess;
2907  $invited = 0;
2908  include_once "./Modules/Group/classes/class.ilObjGroup.php";
2909  $group = new ilObjGroup($group_id);
2910  $members = $group->getGroupMemberIds();
2911  foreach ($members as $user_id)
2912  {
2913  if ($ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
2914  {
2915  $this->inviteUser($user_id);
2916  if ($this->getInvitation() == self::INVITATION_ON)
2917  {
2918  include_once './Services/User/classes/class.ilObjUser.php';
2919  ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2920  }
2921  }
2922  }
2923  return $invited;
2924  }
2925 
2932  function inviteRole($role_id)
2933  {
2934  global $rbacreview;
2935  global $ilAccess;
2936  $invited = 0;
2937  $members = $rbacreview->assignedUsers($role_id);
2938  foreach ($members as $user_id)
2939  {
2940  if ($ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
2941  {
2942  $this->inviteUser($user_id);
2943  if ($this->getInvitation() == self::INVITATION_ON)
2944  {
2945  include_once './Services/User/classes/class.ilObjUser.php';
2946  ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2947  }
2948  }
2949  }
2950  return $invited;
2951  }
2952 
2959  function &getInvitedUsers()
2960  {
2961  global $ilDB;
2962 
2963  $result_array = array();
2964  $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2965  array('integer'),
2966  array($this->getSurveyId())
2967  );
2968  while ($row = $ilDB->fetchAssoc($result))
2969  {
2970  array_push($result_array, $row["user_fi"]);
2971  }
2972  return $result_array;
2973  }
2974 
2982  function deleteWorkingData($question_id, $active_id)
2983  {
2984  global $ilDB;
2985 
2986  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2987  array('integer','integer'),
2988  array($question_id, $active_id)
2989  );
2990  }
2991 
3000  function loadWorkingData($question_id, $active_id)
3001  {
3002  global $ilDB;
3003  $result_array = array();
3004  $result = $ilDB->queryF("SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
3005  array('integer','integer'),
3006  array($question_id, $active_id)
3007  );
3008  if ($result->numRows() >= 1)
3009  {
3010  while ($row = $ilDB->fetchAssoc($result))
3011  {
3012  array_push($result_array, $row);
3013  }
3014  return $result_array;
3015  }
3016  else
3017  {
3018  return $result_array;
3019  }
3020  }
3021 
3028  function fillSurveyForUser($user_id = ANONYMOUS_USER_ID)
3029  {
3030  global $ilDB;
3031  // create an anonymous key
3032  $anonymous_id = $this->createNewAccessCode();
3033  $this->saveUserAccessCode($user_id, $anonymous_id);
3034  // create the survey_finished dataset and set the survey finished already
3035  $active_id = $ilDB->nextId('svy_finished');
3036  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp) ".
3037  "VALUES (%s, %s, %s, %s, %s, %s)",
3038  array('integer','integer','integer','text','text','integer'),
3039  array($active_id, $this->getSurveyId(), $user_id, $anonymous_id, 1, time())
3040  );
3041  // fill the questions randomly
3042  $pages =& $this->getSurveyPages();
3043  foreach ($pages as $key => $question_array)
3044  {
3045  foreach ($question_array as $question)
3046  {
3047  // instanciate question
3048  require_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3049  $question =& SurveyQuestion::_instanciateQuestion($question["question_id"]);
3050  $question->saveRandomData($active_id);
3051  }
3052  }
3053  }
3054 
3061  function startSurvey($user_id, $anonymous_id, $appraisee_id)
3062  {
3063  global $ilDB;
3064 
3065  if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) return;
3066 
3067  if (strcmp($user_id, "") == 0)
3068  {
3069  if ($user_id == ANONYMOUS_USER_ID)
3070  {
3071  $user_id = 0;
3072  }
3073  }
3074  $next_id = $ilDB->nextId('svy_finished');
3075  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) ".
3076  "VALUES (%s, %s, %s, %s, %s, %s, %s)",
3077  array('integer','integer','integer','text','text','integer','integer'),
3078  array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
3079  );
3080  return $next_id;
3081  }
3082 
3089  function finishSurvey($finished_id)
3090  {
3091  global $ilDB;
3092 
3093  $ilDB->manipulateF("UPDATE svy_finished SET state = %s, tstamp = %s".
3094  " WHERE survey_fi = %s AND finished_id = %s",
3095  array('text','integer','integer','integer'),
3096  array(1, time(), $this->getSurveyId(), $finished_id)
3097  );
3098 
3099  $this->checkTutorNotification();
3100  }
3101 
3109  function setPage($finished_id, $page_id)
3110  {
3111  global $ilDB;
3112 
3113  $affectedRows = $ilDB->manipulateF("UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
3114  array('integer','integer'),
3115  array(($page_id) ? $page_id : 0, $finished_id)
3116  );
3117  }
3118 
3119  function sendNotificationMail($user_id, $anonymize_id, $appr_id)
3120  {
3121  include_once "./Services/User/classes/class.ilObjUser.php";
3122  include_once "./Services/User/classes/class.ilUserUtil.php";
3123 
3124  // #12755
3125  $placeholders = array(
3126  "FIRST_NAME" => "firstname",
3127  "LAST_NAME" => "lastname",
3128  "LOGIN" => "login",
3129  // old style
3130  "firstname" => "firstname"
3131  );
3132 
3133  $recipients = preg_split('/,/', $this->mailaddresses);
3134  foreach ($recipients as $recipient)
3135  {
3136  // #11298
3137  include_once "./Services/Notification/classes/class.ilSystemNotification.php";
3138  $ntf = new ilSystemNotification();
3139  $ntf->setLangModules(array("survey"));
3140  $ntf->setRefId($this->getRefId());
3141  $ntf->setSubjectLangId('finished_mail_subject');
3142 
3143  $messagetext = $this->mailparticipantdata;
3144  if(trim($messagetext))
3145  {
3146  $data = ilObjUser::_getUserData(array($user_id));
3147  $data = $data[0];
3148  foreach ($placeholders as $key => $mapping)
3149  {
3150  if ($this->getAnonymize())
3151  {
3152  $messagetext = str_replace('[' . $key . ']', '', $messagetext);
3153  }
3154  else
3155  {
3156  $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
3157  }
3158  }
3159  $ntf->setIntroductionDirect($messagetext);
3160  }
3161  else
3162  {
3163  $ntf->setIntroductionLangId('survey_notification_finished_introduction');
3164  }
3165 
3166  // 360°? add appraisee data
3167  if($appr_id)
3168  {
3169  $ntf->addAdditionalInfo('survey_360_appraisee',
3171  }
3172 
3173  $active_id = $this->getActiveID($user_id, $anonymize_id, $appr_id);
3174  $ntf->addAdditionalInfo('results',
3175  $this->getParticipantTextResults($active_id), true);
3176 
3177  $ntf->setGotoLangId('survey_notification_tutor_link');
3178  $ntf->setReasonLangId('survey_notification_finished_reason');
3179 
3180  $ntf->sendMail(array($recipient), null, null);
3181  }
3182  }
3183 
3184  protected function getParticipantTextResults($active_id)
3185  {
3186  $textresult = "";
3187  $userResults =& $this->getUserSpecificResults(array($active_id));
3188  $questions =& $this->getSurveyQuestions(true);
3189  $questioncounter = 1;
3190  foreach ($questions as $question_id => $question_data)
3191  {
3192  $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
3193  $found = $userResults[$question_id][$active_id];
3194  $text = "";
3195  if (is_array($found))
3196  {
3197  $text = implode("\n", $found);
3198  }
3199  else
3200  {
3201  $text = $found;
3202  }
3203  if (strlen($text) == 0) $text = self::getSurveySkippedValue();
3204  $text = str_replace("<br />", "\n", $text);
3205  $textresult .= $text . "\n\n";
3206  }
3207  return $textresult;
3208  }
3209 
3211  {
3212  $counter = 0;
3213  $questions =& $this->getSurveyQuestions();
3214  $counter++;
3215  foreach ($questions as $data)
3216  {
3217  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3218  $question = SurveyQuestion::_instanciateQuestion($data["question_id"]);
3219 
3220  $eval = $this->getCumulatedResults($question);
3221  }
3222  }
3223 
3231  function isAllowedToTakeMultipleSurveys($userid = "")
3232  {
3233  // #7927: special users are deprecated
3234  return false;
3235 
3236  /*
3237  $result = FALSE;
3238  if ($this->getAnonymize())
3239  {
3240  if ($this->isAccessibleWithoutCode())
3241  {
3242  if (strlen($username) == 0)
3243  {
3244  global $ilUser;
3245  $userid = $ilUser->getId();
3246  }
3247  global $ilSetting;
3248  $surveysetting = new ilSetting("survey");
3249  $allowedUsers = strlen($surveysetting->get("multiple_survey_users")) ? explode(",",$surveysetting->get("multiple_survey_users")) : array();
3250  if (in_array($userid, $allowedUsers))
3251  {
3252  $result = TRUE;
3253  }
3254  }
3255  }
3256  return $result;
3257  */
3258  }
3259 
3267  function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
3268  {
3269  global $ilDB;
3270 
3271  // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
3272  if($anonymize_id)
3273  {
3274  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3275  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3276  array('integer','text','integer'),
3277  array($this->getSurveyId(), $anonymize_id, $appr_id)
3278  );
3279  }
3280  else
3281  {
3282  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3283  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3284  array('integer','integer','integer'),
3285  array($this->getSurveyId(), $user_id, $appr_id)
3286  );
3287  }
3288  if ($result->numRows() == 0)
3289  {
3290  return false;
3291  }
3292  else
3293  {
3294  $row = $ilDB->fetchAssoc($result);
3295 
3296  // yes, we are doing it this way
3297  $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
3298 
3299  return (int)$row["state"];
3300  }
3301 
3302  /*
3303  if ($this->getAnonymize())
3304  {
3305  if ((($user_id != ANONYMOUS_USER_ID) && sizeof($anonymize_id)) && (!($this->isAccessibleWithoutCode() && $this->isAllowedToTakeMultipleSurveys())))
3306  {
3307  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3308  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3309  array('integer','integer','integer'),
3310  array($this->getSurveyId(), $user_id, $appr_id)
3311  );
3312  }
3313  else
3314  {
3315  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3316  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3317  array('integer','text','integer'),
3318  array($this->getSurveyId(), $anonymize_id, $appr_id)
3319  );
3320  }
3321  }
3322  else
3323  {
3324  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3325  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3326  array('integer','integer','integer'),
3327  array($this->getSurveyId(), $user_id, $appr_id)
3328  );
3329  }
3330  if ($result->numRows() == 0)
3331  {
3332  return false;
3333  }
3334  else
3335  {
3336  $row = $ilDB->fetchAssoc($result);
3337  $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
3338  return (int)$row["state"];
3339  }
3340  */
3341  }
3342 
3350  function getActiveID($user_id, $anonymize_id, $appr_id)
3351  {
3352  global $ilDB;
3353 
3354  // see self::isSurveyStarted()
3355 
3356  // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
3357  if($anonymize_id)
3358  {
3359  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3360  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3361  array('integer','text','integer'),
3362  array($this->getSurveyId(), $anonymize_id, $appr_id)
3363  );
3364  }
3365  else
3366  {
3367  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3368  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3369  array('integer','integer','integer'),
3370  array($this->getSurveyId(), $user_id, $appr_id)
3371  );
3372  }
3373  if ($result->numRows() == 0)
3374  {
3375  return false;
3376  }
3377  else
3378  {
3379  $row = $ilDB->fetchAssoc($result);
3380  return $row["finished_id"];
3381  }
3382 
3383  /*
3384  if ($this->getAnonymize())
3385  {
3386  if ((($user_id != ANONYMOUS_USER_ID) && (strlen($anonymize_id) == 0)) && (!($this->isAccessibleWithoutCode() && $this->isAllowedToTakeMultipleSurveys())))
3387  {
3388  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3389  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3390  array('integer','integer','integer'),
3391  array($this->getSurveyId(), $user_id, $appr_id)
3392  );
3393  }
3394  else
3395  {
3396  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3397  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3398  array('integer','text','integer'),
3399  array($this->getSurveyId(), $anonymize_id, $appr_id)
3400  );
3401  }
3402  }
3403  else
3404  {
3405  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3406  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3407  array('integer','integer','integer'),
3408  array($this->getSurveyId(), $user_id, $appr_id)
3409  );
3410  }
3411  if ($result->numRows() == 0)
3412  {
3413  return false;
3414  }
3415  else
3416  {
3417  $row = $ilDB->fetchAssoc($result);
3418  return $row["finished_id"];
3419  }
3420  */
3421  }
3422 
3430  function getLastActivePage($active_id)
3431  {
3432  global $ilDB;
3433  $result = $ilDB->queryF("SELECT lastpage FROM svy_finished WHERE finished_id = %s",
3434  array('integer'),
3435  array($active_id)
3436  );
3437  if ($result->numRows() == 0)
3438  {
3439  return "";
3440  }
3441  else
3442  {
3443  $row = $ilDB->fetchAssoc($result);
3444  return ($row["lastpage"]) ? $row["lastpage"] : '';
3445  }
3446  }
3447 
3456  function checkConstraint($constraint_data, $working_data)
3457  {
3458  if (count($working_data) == 0)
3459  {
3460  return 0;
3461  }
3462 
3463  if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0))
3464  {
3465  return 0;
3466  }
3467 
3468  $found = false;
3469  foreach ($working_data as $data)
3470  {
3471  switch ($constraint_data["short"])
3472  {
3473  case "<":
3474  if ($data["value"] < $constraint_data["value"])
3475  {
3476  $found = true;
3477  }
3478  break;
3479 
3480  case "<=":
3481  if ($data["value"] <= $constraint_data["value"])
3482  {
3483  $found = true;
3484  }
3485  break;
3486 
3487  case "=":
3488  if ($data["value"] == $constraint_data["value"])
3489  {
3490  $found = true;
3491  }
3492  break;
3493 
3494  case "<>":
3495  if ($data["value"] <> $constraint_data["value"])
3496  {
3497  $found = true;
3498  }
3499  break;
3500 
3501  case ">=":
3502  if ($data["value"] >= $constraint_data["value"])
3503  {
3504  $found = true;
3505  }
3506  break;
3507 
3508  case ">":
3509  if ($data["value"] > $constraint_data["value"])
3510  {
3511  $found = true;
3512  }
3513  break;
3514  }
3515  if ($found)
3516  {
3517  break;
3518  }
3519  }
3520 
3521  return (int)$found;
3522  }
3523 
3525  {
3526  global $ilDB;
3527 
3528  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3529  array('integer'),
3530  array($survey_id)
3531  );
3532  return ($result->numRows()) ? true : false;
3533  }
3534 
3542  {
3543  global $ilDB, $ilLog;
3544 
3545  $users = array();
3546  $result = $ilDB->queryF("SELECT * FROM svy_finished WHERE survey_fi = %s",
3547  array('integer'),
3548  array($this->getSurveyId())
3549  );
3550  if ($result->numRows())
3551  {
3552  while ($row = $ilDB->fetchAssoc($result))
3553  {
3554  array_push($users, $row["finished_id"]);
3555  }
3556  }
3557  return $users;
3558  }
3559 
3566  function &getUserSpecificResults($finished_ids)
3567  {
3568  global $ilDB;
3569 
3570  $evaluation = array();
3571  $questions =& $this->getSurveyQuestions();
3572  foreach ($questions as $question_id => $question_data)
3573  {
3574  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3575  $question_type = SurveyQuestion::_getQuestionType($question_id);
3576  SurveyQuestion::_includeClass($question_type);
3577  $question = new $question_type();
3578  $question->loadFromDb($question_id);
3579  $data =& $question->getUserAnswers($this->getSurveyId(), $finished_ids);
3580  $evaluation[$question_id] = $data;
3581  }
3582  return $evaluation;
3583  }
3584 
3592  function getUserDataFromActiveId($active_id)
3593  {
3594  global $ilDB;
3595 
3596  $surveySetting = new ilSetting("survey");
3597  $use_anonymous_id = array_key_exists("use_anonymous_id", $_GET) ? $_GET["use_anonymous_id"] : $surveySetting->get("use_anonymous_id");
3598  $result = $ilDB->queryF("SELECT * FROM svy_finished WHERE finished_id = %s",
3599  array('integer'),
3600  array($active_id)
3601  );
3602  $row = array();
3603  $foundrows = $result->numRows();
3604  if ($foundrows)
3605  {
3606  $row = $ilDB->fetchAssoc($result);
3607  }
3608  $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3609  $userdata = array(
3610  "fullname" => $name,
3611  "sortname" => $name,
3612  "firstname" => "",
3613  "lastname" => "",
3614  "login" => "",
3615  "gender" => "",
3616  "active_id" => "$active_id"
3617  );
3618  if ($foundrows)
3619  {
3620  if (($row["user_fi"] > 0) && ($row["user_fi"] != ANONYMOUS_USER_ID) && ($this->getAnonymize() == 0))
3621  {
3622  include_once './Services/User/classes/class.ilObjUser.php';
3623  if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0)
3624  {
3625  $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3626  }
3627  else
3628  {
3629  $user = new ilObjUser($row["user_fi"]);
3630  $userdata["fullname"] = $user->getFullname();
3631  $gender = $user->getGender();
3632  if (strlen($gender) == 1) $gender = $this->lng->txt("gender_$gender");
3633  $userdata["gender"] = $gender;
3634  $userdata["firstname"] = $user->getFirstname();
3635  $userdata["lastname"] = $user->getLastname();
3636  $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3637  $userdata["login"] = $user->getLogin();
3638  }
3639  }
3640  }
3641  return $userdata;
3642  }
3643 
3653  function &getEvaluationByUser($questions, $active_id)
3654  {
3655  global $ilDB;
3656 
3657  // collect all answers
3658  $answers = array();
3659  $result = $ilDB->queryF("SELECT * FROM svy_answer WHERE active_fi = %s",
3660  array('integer'),
3661  array($active_id)
3662  );
3663  while ($row = $ilDB->fetchAssoc($result))
3664  {
3665  if (!is_array($answers[$row["question_fi"]]))
3666  {
3667  $answers[$row["question_fi"]] = array();
3668  }
3669  array_push($answers[$row["question_fi"]], $row);
3670  }
3671  $userdata = $this->getUserDataFromActiveId($active_id);
3672  $resultset = array(
3673  "name" => $userdata["fullname"],
3674  "firstname" => $userdata["firstname"],
3675  "lastname" => $userdata["lastname"],
3676  "login" => $userdata["login"],
3677  "gender" => $userdata["gender"],
3678  "answers" => array()
3679  );
3680  foreach ($questions as $key => $question)
3681  {
3682  if (array_key_exists($key, $answers))
3683  {
3684  $resultset["answers"][$key] = $answers[$key];
3685  }
3686  else
3687  {
3688  $resultset["answers"][$key] = array();
3689  }
3690  sort($resultset["answers"][$key]);
3691  }
3692  return $resultset;
3693  }
3694 
3703  function getCumulatedResults(&$question, $finished_ids)
3704  {
3705  global $ilDB;
3706 
3707  if(!$finished_ids)
3708  {
3709  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3710  array('integer'),
3711  array($this->getSurveyId())
3712  );
3713  $nr_of_users = $result->numRows();
3714  }
3715  else
3716  {
3717  $nr_of_users = sizeof($finished_ids);
3718  }
3719 
3720  $result_array =& $question->getCumulatedResults($this->getSurveyId(), $nr_of_users, $finished_ids);
3721  return $result_array;
3722  }
3723 
3732  {
3733  global $ilDB;
3734 
3735  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3736  array('integer'),
3737  array($survey_id)
3738  );
3739  return $result->numRows();
3740  }
3741 
3742  function &getQuestions($question_ids)
3743  {
3744  global $ilDB;
3745 
3746  $result_array = array();
3747  $result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag FROM svy_question, svy_qtype WHERE ".
3748  "svy_question.questiontype_fi = svy_qtype.questiontype_id AND svy_question.tstamp > 0 AND ".
3749  $ilDB->in('svy_question.question_id', $question_ids, false, 'integer'));
3750  while ($row = $ilDB->fetchAssoc($result))
3751  {
3752  array_push($result_array, $row);
3753  }
3754  return $result_array;
3755  }
3756 
3762  function getQuestionsTable($arrFilter)
3763  {
3764  global $ilUser;
3765  global $ilDB;
3766  $where = "";
3767  if (is_array($arrFilter))
3768  {
3769  if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title']))
3770  {
3771  $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3772  }
3773  if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description']))
3774  {
3775  $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3776  }
3777  if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author']))
3778  {
3779  $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3780  }
3781  if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type']))
3782  {
3783  $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3784  }
3785  if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl']))
3786  {
3787  $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3788  }
3789  }
3790 
3791  $spls =& $this->getAvailableQuestionpools($use_obj_id = TRUE, $could_be_offline = FALSE, $showPath = FALSE);
3792  $forbidden = "";
3793  $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3794  $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3795  $existing = "";
3796  $existing_questions =& $this->getExistingQuestions();
3797  if (count($existing_questions))
3798  {
3799  $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3800  }
3801 
3802  include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
3804 
3805  $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id".
3806  " FROM svy_question, svy_qtype, object_reference".
3807  " WHERE svy_question.original_id IS NULL".$forbidden.$existing.
3808  " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0".
3809  " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3810 
3811  $rows = array();
3812  if ($query_result->numRows())
3813  {
3814  while ($row = $ilDB->fetchAssoc($query_result))
3815  {
3816  if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt']))
3817  {
3818  if(!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt']))
3819  {
3820  continue;
3821  }
3822  }
3823 
3824  $row['ttype'] = $trans[$row['type_tag']];
3825  if ($row["plugin"])
3826  {
3827  if ($this->isPluginActive($row["type_tag"]))
3828  {
3829  array_push($rows, $row);
3830  }
3831  }
3832  else
3833  {
3834  array_push($rows, $row);
3835  }
3836  }
3837  }
3838  return $rows;
3839  }
3840 
3846  function getQuestionblocksTable($arrFilter)
3847  {
3848  global $ilUser, $ilDB;
3849 
3850  $where = "";
3851  if (is_array($arrFilter))
3852  {
3853  if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title']))
3854  {
3855  $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3856  }
3857  }
3858 
3859  $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE ".
3860  "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi ".
3861  "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, ".
3862  "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3863  $rows = array();
3864  if ($query_result->numRows())
3865  {
3866  $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3867  $surveytitles = array();
3868  foreach ($survey_ref_ids as $survey_ref_id)
3869  {
3870  $survey_id = ilObject::_lookupObjId($survey_ref_id);
3871  $surveytitles[$survey_id] = ilObject::_lookupTitle($survey_id);
3872  }
3873  while ($row = $ilDB->fetchAssoc($query_result))
3874  {
3875  $questions_array =& $this->getQuestionblockQuestions($row["questionblock_id"]);
3876  $counter = 1;
3877  foreach ($questions_array as $key => $value)
3878  {
3879  $questions_array[$key] = "$counter. $value";
3880  $counter++;
3881  }
3882  if (strlen($surveytitles[$row["obj_fi"]])) // only questionpools which are not in trash
3883  {
3884  $rows[$row["questionblock_id"]] = array(
3885  "questionblock_id" => $row["questionblock_id"],
3886  "title" => $row["title"],
3887  "svy" => $surveytitles[$row["obj_fi"]],
3888  "contains" => join($questions_array, ", "),
3889  "owner" => $row["owner_fi"]
3890  );
3891  }
3892  }
3893  }
3894  return $rows;
3895  }
3896 
3903  function toXML()
3904  {
3905  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
3906  $a_xml_writer = new ilXmlWriter;
3907  // set xml header
3908  $a_xml_writer->xmlHeader();
3909  $attrs = array(
3910  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3911  "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3912  );
3913  $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3914  $attrs = array(
3915  "id" => $this->getSurveyId(),
3916  "title" => $this->getTitle()
3917  );
3918  $a_xml_writer->xmlStartTag("survey", $attrs);
3919 
3920  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
3921  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
3922  $a_xml_writer->xmlStartTag("objectives");
3923  $attrs = array(
3924  "label" => "introduction"
3925  );
3926  $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), TRUE, TRUE, $attrs);
3927  $attrs = array(
3928  "label" => "outro"
3929  );
3930  $this->addMaterialTag($a_xml_writer, $this->getOutro(), TRUE, TRUE, $attrs);
3931  $a_xml_writer->xmlEndTag("objectives");
3932 
3933  if ($this->getAnonymize())
3934  {
3935  $attribs = array("enabled" => "1");
3936  }
3937  else
3938  {
3939  $attribs = array("enabled" => "0");
3940  }
3941  $a_xml_writer->xmlElement("anonymisation", $attribs);
3942  $a_xml_writer->xmlStartTag("restrictions");
3943  if ($this->getAnonymize() == 2)
3944  {
3945  $attribs = array("type" => "free");
3946  }
3947  else
3948  {
3949  $attribs = array("type" => "restricted");
3950  }
3951  $a_xml_writer->xmlElement("access", $attribs);
3952  if ($this->getStartDate())
3953  {
3954  $attrs = array("type" => "date");
3955  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3956  $a_xml_writer->xmlElement("startingtime", $attrs, sprintf("%04d-%02d-%02dT%02d:%02d:00", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
3957  }
3958  if ($this->getEndDate())
3959  {
3960  $attrs = array("type" => "date");
3961  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3962  $a_xml_writer->xmlElement("endingtime", $attrs, sprintf("%04d-%02d-%02dT%02d:%02d:00", $matches[1], $matches[2], $matches[3], $matches[4], $matches[5], $matches[6]));
3963 
3964  }
3965  $a_xml_writer->xmlEndTag("restrictions");
3966 
3967  // constraints
3968  $pages =& $this->getSurveyPages();
3969  $hasconstraints = FALSE;
3970  foreach ($pages as $question_array)
3971  {
3972  foreach ($question_array as $question)
3973  {
3974  if (count($question["constraints"]))
3975  {
3976  $hasconstraints = TRUE;
3977  }
3978  }
3979  }
3980 
3981  if ($hasconstraints)
3982  {
3983  $a_xml_writer->xmlStartTag("constraints");
3984  foreach ($pages as $question_array)
3985  {
3986  foreach ($question_array as $question)
3987  {
3988  if (count($question["constraints"]))
3989  {
3990  // found constraints
3991  foreach ($question["constraints"] as $constraint)
3992  {
3993  $attribs = array(
3994  "sourceref" => $question["question_id"],
3995  "destref" => $constraint["question"],
3996  "relation" => $constraint["short"],
3997  "value" => $constraint["value"],
3998  "conjunction" => $constraint["conjunction"]
3999  );
4000  $a_xml_writer->xmlElement("constraint", $attribs);
4001  }
4002  }
4003  }
4004  }
4005  $a_xml_writer->xmlEndTag("constraints");
4006  }
4007 
4008  // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
4009  $a_xml_writer->xmlStartTag("metadata");
4010 
4011  $custom_properties = array();
4012  $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
4013  $custom_properties["status"] = $this->getStatus();
4014  $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
4015  $custom_properties["pool_usage"] = (int)$this->getPoolUsage();
4016 
4017  // #14967
4018  $custom_properties["mode_360"] = (int)$this->get360Mode();
4019  $custom_properties["mode_360_self_eval"] = (int)$this->get360SelfEvaluation();
4020  $custom_properties["mode_360_self_rate"] = (int)$this->get360SelfRaters();
4021  $custom_properties["mode_360_self_appr"] = (int)$this->get360SelfAppraisee();
4022  $custom_properties["mode_360_results"] = $this->get360Results();
4023  $custom_properties["mode_360_skill_service"] = (int)$this->get360SkillService();
4024 
4025  // :TODO: skills?
4026 
4027  // reminder/tutor notification are (currently?) not exportable
4028 
4029  foreach($custom_properties as $label => $value)
4030  {
4031  $a_xml_writer->xmlStartTag("metadatafield");
4032  $a_xml_writer->xmlElement("fieldlabel", NULL, $label);
4033  $a_xml_writer->xmlElement("fieldentry", NULL, $value);
4034  $a_xml_writer->xmlEndTag("metadatafield");
4035  }
4036 
4037  $a_xml_writer->xmlStartTag("metadatafield");
4038  $a_xml_writer->xmlElement("fieldlabel", NULL, "SCORM");
4039  include_once "./Services/MetaData/classes/class.ilMD.php";
4040  $md = new ilMD($this->getId(),0, $this->getType());
4041  $writer = new ilXmlWriter();
4042  $md->toXml($writer);
4043  $metadata = $writer->xmlDumpMem();
4044  $a_xml_writer->xmlElement("fieldentry", NULL, $metadata);
4045  $a_xml_writer->xmlEndTag("metadatafield");
4046 
4047  $a_xml_writer->xmlEndTag("metadata");
4048  $a_xml_writer->xmlEndTag("survey");
4049 
4050  $attribs = array("id" => $this->getId());
4051  $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
4052  // add questionblock descriptions
4053  $obligatory_states =& $this->getObligatoryStates();
4054  foreach ($pages as $question_array)
4055  {
4056  if (count($question_array) > 1)
4057  {
4058  $attribs = array("id" => $question_array[0]["question_id"]);
4059  $attribs = array("showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
4060  "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"]);
4061  $a_xml_writer->xmlStartTag("questionblock", $attribs);
4062  if (strlen($question_array[0]["questionblock_title"]))
4063  {
4064  $a_xml_writer->xmlElement("questionblocktitle", NULL, $question_array[0]["questionblock_title"]);
4065  }
4066  }
4067  foreach ($question_array as $question)
4068  {
4069  if (strlen($question["heading"]))
4070  {
4071  $a_xml_writer->xmlElement("textblock", NULL, $question["heading"]);
4072  }
4073  $questionObject =& $this->_instanciateQuestion($question["question_id"]);
4074  if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
4075  }
4076  if (count($question_array) > 1)
4077  {
4078  $a_xml_writer->xmlEndTag("questionblock");
4079  }
4080  }
4081 
4082  $a_xml_writer->xmlEndTag("surveyquestions");
4083  $a_xml_writer->xmlEndTag("surveyobject");
4084  $xml = $a_xml_writer->xmlDumpMem(FALSE);
4085  return $xml;
4086  }
4087 
4095  function &_instanciateQuestion($question_id)
4096  {
4097  if ($question_id < 1) return FALSE;
4098  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
4099  $question_type = SurveyQuestion::_getQuestionType($question_id);
4100  if (strlen($question_type) == 0) return FALSE;
4101  SurveyQuestion::_includeClass($question_type);
4102  $question = new $question_type();
4103  $question->loadFromDb($question_id);
4104  return $question;
4105  }
4106 
4113  function locateImportFiles($a_dir)
4114  {
4115  if (!is_dir($a_dir) || is_int(strpos($a_dir, "..")))
4116  {
4117  return;
4118  }
4119  $importDirectory = "";
4120  $xmlFile = "";
4121 
4122  $current_dir = opendir($a_dir);
4123  $files = array();
4124  while($entryname = readdir($current_dir))
4125  {
4126  $files[] = $entryname;
4127  }
4128 
4129  foreach($files as $file)
4130  {
4131  if(is_dir($a_dir."/".$file) and ($file != "." and $file!=".."))
4132  {
4133  // found directory created by zip
4134  $importDirectory = $a_dir."/".$file;
4135  }
4136  }
4137  closedir($current_dir);
4138  if (strlen($importDirectory))
4139  {
4140  // find the xml file
4141  $current_dir = opendir($importDirectory);
4142  $files = array();
4143  while($entryname = readdir($current_dir))
4144  {
4145  $files[] = $entryname;
4146  }
4147  foreach($files as $file)
4148  {
4149  if(@is_file($importDirectory."/".$file) && ($file != "." && $file!="..") && (ereg("^[0-9]{10}_{2}[0-9]+_{2}(svy_)*[0-9]+\.[a-z]{1,3}\$", $file) || ereg("^[0-9]{10}_{2}[0-9]+_{2}(survey__)*[0-9]+\.[a-z]{1,3}\$", $file)))
4150  {
4151  // found xml file
4152  $xmlFile = $importDirectory."/".$file;
4153  }
4154  }
4155  }
4156  return array("dir" => $importDirectory, "xml" => $xmlFile);
4157  }
4158 
4165  function importObject($file_info, $svy_qpl_id)
4166  {
4167  if ($svy_qpl_id < 1) $svy_qpl_id = -1;
4168  // check if file was uploaded
4169  $source = $file_info["tmp_name"];
4170  $error = "";
4171  if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK)
4172  {
4173  $error = $this->lng->txt("import_no_file_selected");
4174  }
4175  // check correct file type
4176  $isXml = FALSE;
4177  $isZip = FALSE;
4178  if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0))
4179  {
4180  $isXml = TRUE;
4181  }
4182  // too many different mime-types, so we use the suffix
4183  $suffix = pathinfo($file_info["name"]);
4184  if (strcmp(strtolower($suffix["extension"]), "zip") == 0)
4185  {
4186  $isZip = TRUE;
4187  }
4188  if (!$isXml && !$isZip)
4189  {
4190  $error = $this->lng->txt("import_wrong_file_type");
4191  global $ilLog;
4192  $ilLog->write("Survey: Import error. Filetype was \"" . $file_info["type"] ."\"");
4193  }
4194  if (strlen($error) == 0)
4195  {
4196  // import file as a survey
4197  $import_dir = $this->getImportDirectory();
4198  $import_subdir = "";
4199  $importfile = "";
4200  include_once "./Services/Utilities/classes/class.ilUtil.php";
4201  if ($isZip)
4202  {
4203  $importfile = $import_dir."/".$file_info["name"];
4204  ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
4205  ilUtil::unzip($importfile);
4206  $found = $this->locateImportFiles($import_dir);
4207  if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0)))
4208  {
4209  $error = $this->lng->txt("wrong_import_file_structure");
4210  return $error;
4211  }
4212  $importfile = $found["xml"];
4213  $import_subdir = $found["dir"];
4214  }
4215  else
4216  {
4217  $importfile = tempnam($import_dir, "survey_import");
4218  ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
4219  }
4220  $fh = fopen($importfile, "r");
4221  if (!$fh)
4222  {
4223  $error = $this->lng->txt("import_error_opening_file");
4224  return $error;
4225  }
4226  $xml = fread($fh, filesize($importfile));
4227  $result = fclose($fh);
4228  if (!$result)
4229  {
4230  $error = $this->lng->txt("import_error_closing_file");
4231  return $error;
4232  }
4233 
4234  unset($_SESSION["import_mob_xhtml"]);
4235  if (strpos($xml, "questestinterop"))
4236  {
4237  include_once "./Services/Survey/classes/class.SurveyImportParserPre38.php";
4238  $import = new SurveyImportParserPre38($svy_qpl_id, "", TRUE);
4239  $import->setSurveyObject($this);
4240  $import->setXMLContent($xml);
4241  $import->startParsing();
4242  }
4243  else
4244  {
4245  include_once "./Services/Survey/classes/class.SurveyImportParser.php";
4246  $import = new SurveyImportParser($svy_qpl_id, "", TRUE);
4247  $import->setSurveyObject($this);
4248  $import->setXMLContent($xml);
4249  $import->startParsing();
4250  }
4251 
4252  if (is_array($_SESSION["import_mob_xhtml"]))
4253  {
4254  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
4255  include_once "./Services/RTE/classes/class.ilRTE.php";
4256  include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
4257  foreach ($_SESSION["import_mob_xhtml"] as $mob)
4258  {
4259  $importfile = $import_subdir . "/" . $mob["uri"];
4260  if (file_exists($importfile))
4261  {
4262  if (!$mob["type"])
4263  {
4264  $mob["type"] = "svy:html";
4265  }
4266 
4267  $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
4268 
4269  // survey mob
4270  if ($mob["type"] == "svy:html")
4271  {
4272  ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
4273  $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
4274  $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
4275  }
4276  // question mob
4277  else if($import->questions[$mob["id"]])
4278  {
4279  $new_qid = $import->questions[$mob["id"]];
4280  ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
4281  $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
4282  $qtext = $new_question->getQuestiontext();
4283  $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
4284  $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
4285  $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
4286  $new_question->setQuestiontext($qtext);
4287  $new_question->saveToDb();
4288 
4289  // also fix existing original in pool
4290  if($new_question->getOriginalId())
4291  {
4292  $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
4293  $pool_question->setQuestiontext($qtext);
4294  $pool_question->saveToDb();
4295  }
4296  }
4297  }
4298  else
4299  {
4300  global $ilLog;
4301  $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
4302  }
4303  }
4306  $this->saveToDb();
4307  }
4308 
4309  // delete import directory
4311  }
4312  return $error;
4313  }
4314 
4323  public function cloneObject($a_target_id,$a_copy_id = 0)
4324  {
4325  global $ilDB;
4326 
4327  $this->loadFromDb();
4328 
4329  // Copy settings
4330  $newObj = parent::cloneObject($a_target_id,$a_copy_id);
4331  $this->cloneMetaData($newObj);
4332  $newObj->updateMetaData();
4333 
4334  $newObj->setAuthor($this->getAuthor());
4335  $newObj->setIntroduction($this->getIntroduction());
4336  $newObj->setOutro($this->getOutro());
4337  $newObj->setStatus($this->getStatus());
4338  $newObj->setEvaluationAccess($this->getEvaluationAccess());
4339  $newObj->setStartDate($this->getStartDate());
4340  $newObj->setEndDate($this->getEndDate());
4341  $newObj->setInvitation($this->getInvitation());
4342  $newObj->setInvitationMode($this->getInvitationMode());
4343  $newObj->setAnonymize($this->getAnonymize());
4344  $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
4345  $newObj->setTemplate($this->getTemplate());
4346 
4347  // #12661
4348  if($this->get360Mode())
4349  {
4350  $newObj->set360Mode(true);
4351  $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
4352  $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
4353  $newObj->set360SelfRaters($this->get360SelfRaters());
4354  $newObj->set360Results($this->get360Results());
4355  $newObj->set360SkillService($this->get360SkillService());
4356  }
4357 
4358  // reminder/notification
4359  $newObj->setReminderStatus($this->getReminderStatus());
4360  $newObj->setReminderStart($this->getReminderStart());
4361  $newObj->setReminderEnd($this->getReminderEnd());
4362  $newObj->setReminderFrequency($this->getReminderFrequency());
4363  $newObj->setReminderTarget($this->getReminderTarget());
4364  // reminder_last_sent must not be copied!
4365  $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
4366  $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
4367  $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
4368 
4369  $question_pointer = array();
4370  // clone the questions
4371  $mapping = array();
4372  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
4373  foreach ($this->questions as $key => $question_id)
4374  {
4375  $question = ilObjSurvey::_instanciateQuestion($question_id);
4376  if($question) // #10824
4377  {
4378  $question->id = -1;
4379  $original_id = SurveyQuestion::_getOriginalId($question_id, false);
4380  $question->saveToDb($original_id);
4381  $newObj->questions[$key] = $question->getId();
4382  $question_pointer[$question_id] = $question->getId();
4383  $mapping[$question_id] = $question->getId();
4384  }
4385  }
4386 
4387  $newObj->saveToDb();
4388  $newObj->cloneTextblocks($mapping);
4389 
4390  // clone the questionblocks
4391  $questionblocks = array();
4392  $questionblock_questions = array();
4393  $result = $ilDB->queryF("SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
4394  array('integer'),
4395  array($this->getSurveyId())
4396  );
4397  if ($result->numRows() > 0)
4398  {
4399  while ($row = $ilDB->fetchAssoc($result))
4400  {
4401  array_push($questionblock_questions, $row);
4402  $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
4403  }
4404  }
4405  // create new questionblocks
4406  foreach ($questionblocks as $key => $value)
4407  {
4408  $questionblock = ilObjSurvey::_getQuestionblock($key);
4409  $questionblock_id = ilObjSurvey::_addQuestionblock($questionblock["title"], $questionblock["owner_fi"], $questionblock["show_questiontext"], $questionblock["show_blocktitle"]);
4410  $questionblocks[$key] = $questionblock_id;
4411  }
4412  // create new questionblock questions
4413  foreach ($questionblock_questions as $key => $value)
4414  {
4415  if($questionblocks[$value["questionblock_fi"]] &&
4416  $question_pointer[$value["question_fi"]])
4417  {
4418  $next_id = $ilDB->nextId('svy_qblk_qst');
4419  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) ".
4420  "VALUES (%s, %s, %s, %s)",
4421  array('integer','integer','integer','integer'),
4422  array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
4423  );
4424  }
4425  }
4426 
4427  // clone the constraints
4428  $constraints = ilObjSurvey::_getConstraints($this->getSurveyId());
4429  $newConstraints = array();
4430  foreach ($constraints as $key => $constraint)
4431  {
4432  if ($question_pointer[$constraint["for_question"]] &&
4433  $question_pointer[$constraint["question"]])
4434  {
4435  if (!array_key_exists($constraint['id'], $newConstraints))
4436  {
4437  $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
4438  $newConstraints[$constraint['id']] = $constraint_id;
4439  }
4440  $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
4441  }
4442  }
4443 
4444  // clone the obligatory states
4445  $result = $ilDB->queryF("SELECT * FROM svy_qst_oblig WHERE survey_fi = %s",
4446  array('integer'),
4447  array($this->getSurveyId())
4448  );
4449  if ($result->numRows() > 0)
4450  {
4451  while ($row = $ilDB->fetchAssoc($result))
4452  {
4453  if($question_pointer[$row["question_fi"]])
4454  {
4455  $next_id = $ilDB->nextId('svy_qst_oblig');
4456  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_oblig (question_obligatory_id, survey_fi, question_fi, ".
4457  "obligatory, tstamp) VALUES (%s, %s, %s, %s, %s)",
4458  array('integer','integer','integer','text','integer'),
4459  array($next_id, $newObj->getSurveyId(), $question_pointer[$row["question_fi"]], $row["obligatory"], time())
4460  );
4461  }
4462  }
4463  }
4464  return $newObj;
4465  }
4466 
4467  function getTextblock($question_id)
4468  {
4469  global $ilDB;
4470  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE question_fi = %s",
4471  array('integer'),
4472  array($question_id)
4473  );
4474  if ($result->numRows())
4475  {
4476  $row = $ilDB->fetchAssoc($result);
4477  return $row["heading"];
4478  }
4479  else
4480  {
4481  return "";
4482  }
4483  }
4484 
4490  function cloneTextblocks($mapping)
4491  {
4492  foreach ($mapping as $original_id => $new_id)
4493  {
4494  $textblock = $this->getTextblock($original_id);
4495  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
4496  $this->saveHeading(ilUtil::stripSlashes($textblock, TRUE, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
4497  }
4498  }
4499 
4506  {
4507  include_once "./Services/Utilities/classes/class.ilUtil.php";
4508  $svy_data_dir = ilUtil::getDataDir()."/svy_data";
4509  ilUtil::makeDir($svy_data_dir);
4510  if(!is_writable($svy_data_dir))
4511  {
4512  $this->ilias->raiseError("Survey Data Directory (".$svy_data_dir
4513  .") not writeable.",$this->ilias->error_obj->FATAL);
4514  }
4515 
4516  // create learning module directory (data_dir/lm_data/lm_<id>)
4517  $svy_dir = $svy_data_dir."/svy_".$this->getId();
4518  ilUtil::makeDir($svy_dir);
4519  if(!@is_dir($svy_dir))
4520  {
4521  $this->ilias->raiseError("Creation of Survey Directory failed.",$this->ilias->error_obj->FATAL);
4522  }
4523  // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
4524  $export_dir = $svy_dir."/export";
4525  ilUtil::makeDir($export_dir);
4526  if(!@is_dir($export_dir))
4527  {
4528  $this->ilias->raiseError("Creation of Export Directory failed.",$this->ilias->error_obj->FATAL);
4529  }
4530  }
4531 
4536  {
4537  include_once "./Services/Utilities/classes/class.ilUtil.php";
4538  $export_dir = ilUtil::getDataDir()."/svy_data"."/svy_".$this->getId()."/export";
4539 
4540  return $export_dir;
4541  }
4542 
4546  function getExportFiles($dir)
4547  {
4548  // quit if import dir not available
4549  if (!@is_dir($dir) or
4550  !is_writeable($dir))
4551  {
4552  return array();
4553  }
4554 
4555  // open directory
4556  $dir = dir($dir);
4557 
4558  // initialize array
4559  $file = array();
4560 
4561  // get files and save the in the array
4562  while ($entry = $dir->read())
4563  {
4564  if ($entry != "." && $entry != ".." && ereg("^[0-9]{10}_{2}[0-9]+_{2}(svy_)*[0-9]+\.[a-z]{1,3}\$", $entry))
4565  {
4566  $file[] = $entry;
4567  }
4568  }
4569 
4570  // close import directory
4571  $dir->close();
4572  // sort files
4573  sort ($file);
4574  reset ($file);
4575 
4576  return $file;
4577  }
4578 
4585  {
4586  include_once "./Services/Utilities/classes/class.ilUtil.php";
4587  $svy_data_dir = ilUtil::getDataDir()."/svy_data";
4588  ilUtil::makeDir($svy_data_dir);
4589 
4590  if(!is_writable($svy_data_dir))
4591  {
4592  $this->ilias->raiseError("Survey Data Directory (".$svy_data_dir
4593  .") not writeable.",$this->ilias->error_obj->FATAL);
4594  }
4595 
4596  // create test directory (data_dir/svy_data/svy_<id>)
4597  $svy_dir = $svy_data_dir."/svy_".$this->getId();
4598  ilUtil::makeDir($svy_dir);
4599  if(!@is_dir($svy_dir))
4600  {
4601  $this->ilias->raiseError("Creation of Survey Directory failed.",$this->ilias->error_obj->FATAL);
4602  }
4603 
4604  // create import subdirectory (data_dir/svy_data/svy_<id>/import)
4605  $import_dir = $svy_dir."/import";
4606  ilUtil::makeDir($import_dir);
4607  if(!@is_dir($import_dir))
4608  {
4609  $this->ilias->raiseError("Creation of Import Directory failed.",$this->ilias->error_obj->FATAL);
4610  }
4611  }
4612 
4617  {
4618  include_once "./Services/Utilities/classes/class.ilUtil.php";
4619  $import_dir = ilUtil::getDataDir()."/svy_data".
4620  "/svy_".$this->getId()."/import";
4621  if (!is_dir($import_dir))
4622  {
4623  ilUtil::makeDirParents($import_dir);
4624  }
4625  if(@is_dir($import_dir))
4626  {
4627  return $import_dir;
4628  }
4629  else
4630  {
4631  return false;
4632  }
4633  }
4634 
4635  function saveHeading($heading = "", $insertbefore)
4636  {
4637  global $ilDB;
4638  if ($heading)
4639  {
4640  $affectedRows = $ilDB->manipulateF("UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4641  array('text','integer','integer'),
4642  array($heading, $this->getSurveyId(), $insertbefore)
4643  );
4644  }
4645  else
4646  {
4647  $affectedRows = $ilDB->manipulateF("UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4648  array('text','integer','integer'),
4649  array(NULL, $this->getSurveyId(), $insertbefore)
4650  );
4651  }
4652  }
4653 
4654  function isAnonymousKey($key)
4655  {
4656  global $ilDB;
4657 
4658  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
4659  array('text','integer'),
4660  array($key, $this->getSurveyId())
4661  );
4662  return ($result->numRows() == 1) ? true : false;
4663  }
4664 
4665  function getUserSurveyCode($user_id)
4666  {
4667  global $ilDB;
4668 
4669  if (($user_id == ANONYMOUS_USER_ID) || (($this->isAccessibleWithoutCode() && $this->isAllowedToTakeMultipleSurveys()))) return "";
4670  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_finished WHERE survey_fi = %s AND user_fi = %s",
4671  array('integer','integer'),
4672  array($this->getSurveyId(), $user_id)
4673  );
4674  if ($result->numRows() == 1)
4675  {
4676  $row = $ilDB->fetchAssoc($result);
4677  return $row["anonymous_id"];
4678  }
4679  else
4680  {
4681  return "";
4682  }
4683  }
4684 
4685  function bindSurveyCodeToUser($user_id, $code)
4686  {
4687  global $ilDB;
4688 
4689  if($user_id == ANONYMOUS_USER_ID)
4690  {
4691  return;
4692  }
4693 
4694  if($this->checkSurveyCode($code))
4695  {
4696  $ilDB->manipulate("UPDATE svy_anonymous".
4697  " SET user_key = ".$ilDB->quote(md5($user_id), "text").
4698  " WHERE survey_key = ".$ilDB->quote($code, "text"));
4699  }
4700  }
4701 
4703  {
4704  global $ilDB;
4705 
4706  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
4707  array('text','integer'),
4708  array($key, $this->getSurveyId())
4709  );
4710  return ($result->numRows() == 1) ? true : false;
4711  }
4712 
4713  function checkSurveyCode($code)
4714  {
4715  if ($this->isAnonymousKey($code))
4716  {
4717  if ($this->isSurveyStarted("", $code) == 1)
4718  {
4719  return false;
4720  }
4721  else
4722  {
4723  return true;
4724  }
4725  }
4726  else
4727  {
4728  return false;
4729  }
4730  }
4731 
4739  {
4740  global $ilDB;
4741 
4742  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND user_key IS NULL",
4743  array('integer'),
4744  array($this->getSurveyId())
4745  );
4746  return $result->numRows();
4747  }
4748 
4756  function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
4757  {
4758  global $ilDB, $ilUser;
4759 
4760  include_once "./Services/Link/classes/class.ilLink.php";
4761 
4762  $sql = "SELECT svy_anonymous.*, svy_finished.state".
4763  " FROM svy_anonymous".
4764  " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)".
4765  " WHERE svy_anonymous.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
4766  " AND svy_anonymous.user_key IS NULL";
4767 
4768  if($a_codes)
4769  {
4770  $sql .= " AND ".$ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
4771  }
4772  else if($a_ids)
4773  {
4774  $sql .= " AND ".$ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
4775  }
4776 
4777  $result = $ilDB->query($sql);
4778  $export = array();
4779  $default_lang = $ilUser->getPref("survey_code_language");
4780  while ($row = $ilDB->fetchAssoc($result))
4781  {
4782  $item = array();
4783  $item[] = $row["survey_key"];
4784 
4785  if($row["externaldata"])
4786  {
4787  $ext = unserialize($row["externaldata"]);
4788  $item[] = $ext["email"];
4789  $item[] = $ext["lastname"];
4790  $item[] = $ext["firstname"];
4791  }
4792  else
4793  {
4794  $item[] = "";
4795  $item[] = "";
4796  $item[] = "";
4797  }
4798 
4799  // No relative (today, tomorrow...) dates in export.
4800  $date = new ilDate($row['tstamp'],IL_CAL_UNIX);
4801  $item[] = $date->get(IL_CAL_DATE);
4802 
4803  $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4804  $item[] = ($row["sent"]) ? 1 : 0;
4805 
4806  $params = array("accesscode" => $row["survey_key"]);
4807  if ($default_lang)
4808  {
4809  $params["lang"] = $default_lang;
4810  }
4811  $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4812 
4813  $export[] = '"'.implode('";"', $item).'"';
4814  }
4815  return implode("\n", $export);
4816  }
4817 
4825  public function getSurveyCodesTableData(array $ids = null, $lang = null)
4826  {
4827  global $ilDB;
4828 
4829  include_once "./Services/Link/classes/class.ilLink.php";
4830 
4831  $codes = array();
4832 
4833  $sql = "SELECT svy_anonymous.*, svy_finished.state".
4834  " FROM svy_anonymous".
4835  " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)".
4836  " WHERE svy_anonymous.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer") /*.
4837  " AND svy_anonymous.user_key IS NULL" */; // #15860
4838 
4839  if($ids)
4840  {
4841  $sql .= " AND ".$ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4842  }
4843 
4844  $sql .= " ORDER BY tstamp, survey_key ASC";
4845  $result = $ilDB->query($sql);
4846  if ($result->numRows() > 0)
4847  {
4848  while ($row = $ilDB->fetchAssoc($result))
4849  {
4850  $href = "";
4851  $used = false;
4852  if ($this->isSurveyCodeUsed($row["survey_key"]))
4853  {
4854  $used = true;
4855  }
4856  else
4857  {
4858  $params = array("accesscode" => $row["survey_key"]);
4859  if ($lang)
4860  {
4861  $params["lang"] = $lang;
4862  }
4863  $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4864  }
4865 
4866 
4867  $item = array(
4868  'id' => $row["anonymous_id"],
4869  'code' => $row["survey_key"],
4870  'date' => $row["tstamp"],
4871  'used' => $used,
4872  'sent' => $row['sent'],
4873  'href' => $href,
4874  'email' => '',
4875  'last_name' => '',
4876  'first_name' => ''
4877  );
4878 
4879  if($row["externaldata"])
4880  {
4881  $ext = unserialize($row["externaldata"]);
4882  $item['email'] = $ext['email'];
4883  $item['last_name'] = $ext['lastname'];
4884  $item['first_name'] = $ext['firstname'];
4885  }
4886 
4887  array_push($codes, $item);
4888  }
4889  }
4890  return $codes;
4891  }
4892 
4893  function isSurveyCodeUsed($code)
4894  {
4895  global $ilDB;
4896  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4897  array('integer','text'),
4898  array($this->getSurveyId(), $code)
4899  );
4900  return ($result->numRows() > 0) ? true : false;
4901  }
4902 
4903  function isSurveyCodeUnique($code)
4904  {
4905  global $ilDB;
4906  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4907  array('integer','text'),
4908  array($this->getSurveyId(), $code)
4909  );
4910  return ($result->numRows() > 0) ? false : true;
4911  }
4912 
4913  function createSurveyCodes($nrOfCodes)
4914  {
4915  global $ilDB;
4916 
4917  $res = array();
4918 
4919  for ($i = 0; $i < $nrOfCodes; $i++)
4920  {
4921  $next_id = $ilDB->nextId('svy_anonymous');
4922  $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) ".
4923  "VALUES (%s, %s, %s, %s)",
4924  array('integer','text','integer','integer'),
4925  array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4926  );
4927  $res[] = $next_id;
4928  }
4929 
4930  return $res;
4931  }
4932 
4934  {
4935  global $ilDB;
4936 
4937  $ids = array();
4938  foreach ($data as $dataset)
4939  {
4940  $anonymize_key = $this->createNewAccessCode();
4941  $next_id = $ilDB->nextId('svy_anonymous');
4942  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) ".
4943  "VALUES (%s, %s, %s, %s, %s)",
4944  array('integer','text','integer','text','integer'),
4945  array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
4946  );
4947  $ids[] = $next_id;
4948  }
4949  return $ids;
4950  }
4951 
4952  function sendCodes($not_sent, $subject, $message, $lang)
4953  {
4954  /*
4955  * 0 = all
4956  * 1 = not sent
4957  * 2 = finished
4958  * 3 = not finished
4959  */
4960  $check_finished = ($not_sent > 1);
4961 
4962  include_once "./Services/Mail/classes/class.ilMail.php";
4963  include_once "./Services/Link/classes/class.ilLink.php";
4964  $user_id = $this->getOwner();
4965  $mail = new ilMail($user_id);
4966  $recipients = $this->getExternalCodeRecipients($check_finished);
4967  foreach ($recipients as $data)
4968  {
4969  if($data['email'] && $data['code'])
4970  {
4971  $do_send = false;
4972  switch ((int)$not_sent)
4973  {
4974  case 1:
4975  $do_send = !(bool)$data['sent'];
4976  break;
4977 
4978  case 2:
4979  $do_send = $data['finished'];
4980  break;
4981 
4982  case 3:
4983  $do_send = !$data['finished'];
4984  break;
4985 
4986  default:
4987  $do_send = true;
4988  break;
4989  }
4990  if ($do_send)
4991  {
4992  // build text
4993  $messagetext = $message;
4994  $url = ilLink::_getLink($this->getRefId(), "svy",
4995  array(
4996  "accesscode" => $data["code"],
4997  "lang" => $lang
4998  ));
4999  $messagetext = str_replace('[url]', "<" . $url . ">", $messagetext);
5000  foreach ($data as $key => $value)
5001  {
5002  $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
5003  }
5004 
5005  // send mail
5006  $mail->sendMail(
5007  $data['email'], // to
5008  "", // cc
5009  "", // bcc
5010  $subject, // subject
5011  $messagetext, // message
5012  array(), // attachments
5013  array('normal') // type
5014  );
5015  }
5016  }
5017  }
5018 
5019  global $ilDB;
5020  $ilDB->manipulateF("UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
5021  array('integer','integer'),
5022  array(1, $this->getSurveyId())
5023  );
5024  }
5025 
5026  function getExternalCodeRecipients($a_check_finished = false)
5027  {
5028  global $ilDB;
5029  $result = $ilDB->queryF("SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
5030  array('integer'),
5031  array($this->getSurveyId())
5032  );
5033  $res = array();
5034  while ($row = $ilDB->fetchAssoc($result))
5035  {
5036  if(!$row['externaldata'])
5037  {
5038  continue;
5039  }
5040 
5041  $externaldata = unserialize($row['externaldata']);
5042  if(!$externaldata['email'])
5043  {
5044  continue;
5045  }
5046 
5047  $externaldata['code'] = $row['code'];
5048  $externaldata['sent'] = $row['sent'];
5049 
5050  if($a_check_finished)
5051  {
5052  $externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
5053  }
5054 
5055  array_push($res, $externaldata);
5056  }
5057  return $res;
5058  }
5059 
5065  function deleteSurveyCode($survey_code)
5066  {
5067  global $ilDB;
5068 
5069  if (strlen($survey_code) > 0)
5070  {
5071  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
5072  array('integer', 'text'),
5073  array($this->getSurveyId(), $survey_code)
5074  );
5075  }
5076  }
5077 
5084  function getUserAccessCode($user_id)
5085  {
5086  global $ilDB;
5087  $access_code = "";
5088  $result = $ilDB->queryF("SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
5089  array('integer','text'),
5090  array($this->getSurveyId(), md5($user_id))
5091  );
5092  if ($result->numRows())
5093  {
5094  $row = $ilDB->fetchAssoc($result);
5095  $access_code = $row["survey_key"];
5096  }
5097  return $access_code;
5098  }
5099 
5106  function saveUserAccessCode($user_id, $access_code)
5107  {
5108  global $ilDB;
5109  $next_id = $ilDB->nextId('svy_anonymous');
5110  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) ".
5111  "VALUES (%s, %s, %s, %s, %s)",
5112  array('integer','text', 'integer', 'text', 'integer'),
5113  array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
5114  );
5115  }
5116 
5123  {
5124  // create a 5 character code
5125  $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
5126  mt_srand();
5127  $code = "";
5128  for ($i = 1; $i <=5; $i++)
5129  {
5130  $index = mt_rand(0, strlen($codestring)-1);
5131  $code .= substr($codestring, $index, 1);
5132  }
5133  // verify it against the database
5134  while (!$this->isSurveyCodeUnique($code))
5135  {
5136  $code = $this->createNewAccessCode();
5137  }
5138  return $code;
5139  }
5140 
5141 
5152  function &processCSVRow($row, $quoteAll = FALSE, $separator = ";")
5153  {
5154  $resultarray = array();
5155  foreach ($row as $rowindex => $entry)
5156  {
5157  if(is_array($entry))
5158  {
5159  $entry = implode("/", $entry);
5160  }
5161  $surround = FALSE;
5162  if ($quoteAll)
5163  {
5164  $surround = TRUE;
5165  }
5166  if (strpos($entry, "\"") !== FALSE)
5167  {
5168  $entry = str_replace("\"", "\"\"", $entry);
5169  $surround = TRUE;
5170  }
5171  if (strpos($entry, $separator) !== FALSE)
5172  {
5173  $surround = TRUE;
5174  }
5175  // replace all CR LF with LF (for Excel for Windows compatibility
5176  $entry = str_replace(chr(13).chr(10), chr(10), $entry);
5177  if ($surround)
5178  {
5179  $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
5180  }
5181  else
5182  {
5183  $resultarray[$rowindex] = utf8_decode($entry);
5184  }
5185  }
5186  return $resultarray;
5187  }
5188 
5189  function _getLastAccess($finished_id)
5190  {
5191  global $ilDB;
5192 
5193  $result = $ilDB->queryF("SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
5194  array('integer'),
5195  array($finished_id)
5196  );
5197  if ($result->numRows())
5198  {
5199  $row = $ilDB->fetchAssoc($result);
5200  return $row["tstamp"];
5201  }
5202  else
5203  {
5204  $result = $ilDB->queryF("SELECT tstamp FROM svy_finished WHERE finished_id = %s",
5205  array('integer'),
5206  array($finished_id)
5207  );
5208  if ($result->numRows())
5209  {
5210  $row = $ilDB->fetchAssoc($result);
5211  return $row["tstamp"];
5212  }
5213  }
5214  return "";
5215  }
5216 
5223  function prepareTextareaOutput($txt_output)
5224  {
5225  include_once "./Services/Utilities/classes/class.ilUtil.php";
5226  return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
5227  }
5228 
5236  function isHTML($a_text)
5237  {
5238  if (preg_match("/<[^>]*?>/", $a_text))
5239  {
5240  return TRUE;
5241  }
5242  else
5243  {
5244  return FALSE;
5245  }
5246  }
5247 
5256  function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE, $attribs = NULL)
5257  {
5258  include_once "./Services/RTE/classes/class.ilRTE.php";
5259  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
5260 
5261  $a_xml_writer->xmlStartTag("material", $attribs);
5262  $attrs = array(
5263  "type" => "text/plain"
5264  );
5265  if ($this->isHTML($a_material))
5266  {
5267  $attrs["type"] = "text/xhtml";
5268  }
5269  $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
5270  $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
5271 
5272  if ($add_mobs)
5273  {
5274  $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
5275  foreach ($mobs as $mob)
5276  {
5277  $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
5278  if (strpos($mattext, $mob_id) !== FALSE)
5279  {
5280  $mob_obj =& new ilObjMediaObject($mob);
5281  $imgattrs = array(
5282  "label" => $mob_id,
5283  "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
5284  "type" => "svy:html",
5285  "id" => $this->getId()
5286  );
5287  $a_xml_writer->xmlElement("matimage", $imgattrs, NULL);
5288  }
5289  }
5290  }
5291  if ($close_material_tag) $a_xml_writer->xmlEndTag("material");
5292  }
5293 
5303  {
5304  if ($this->getAnonymize() != self::ANONYMIZE_OFF)
5305  {
5306  if ($this->surveyCodeSecurity == FALSE)
5307  {
5308  return TRUE;
5309  }
5310  }
5311  return FALSE;
5312  }
5313 
5321  function processPrintoutput2FO($print_output)
5322  {
5323  global $ilLog;
5324 
5325  if (extension_loaded("tidy"))
5326  {
5327  $config = array(
5328  "indent" => false,
5329  "output-xml" => true,
5330  "numeric-entities" => true
5331  );
5332  $tidy = new tidy();
5333  $tidy->parseString($print_output, $config, 'utf8');
5334  $tidy->cleanRepair();
5335  $print_output = tidy_get_output($tidy);
5336  $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
5337  }
5338  else
5339  {
5340  $print_output = str_replace("&nbsp;", "&#160;", $print_output);
5341  $print_output = str_replace("&otimes;", "X", $print_output);
5342 
5343  // #17680 - metric questions use &#160; in print view
5344  $print_output = str_replace("&gt;", ">", $print_output);
5345  $print_output = str_replace("&lt;", "<", $print_output);
5346  $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
5347  $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
5348  $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
5349  }
5350  $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
5351 
5352  // additional font support
5353  $xsl = str_replace(
5354  'font-family="Helvetica, unifont"',
5355  'font-family="'.$GLOBALS['ilSetting']->get('rpc_pdf_font','Helvetica, unifont').'"',
5356  $xsl
5357  );
5358 
5359  $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
5360  $xh = xslt_create();
5361  $params = array();
5362  $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", NULL, $args, $params);
5363  xslt_error($xh);
5364  xslt_free($xh);
5365  $ilLog->write($output);
5366  return $output;
5367  }
5368 
5375  function deliverPDFfromFO($fo)
5376  {
5377  global $ilLog;
5378 
5379  include_once "./Services/Utilities/classes/class.ilUtil.php";
5380  $fo_file = ilUtil::ilTempnam() . ".fo";
5381  $fp = fopen($fo_file, "w"); fwrite($fp, $fo); fclose($fp);
5382 
5383  include_once './Services/WebServices/RPC/classes/class.ilRpcClientFactory.php';
5384  try
5385  {
5386  $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
5387  ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
5388  return true;
5389  }
5390  catch(XML_RPC2_FaultException $e)
5391  {
5392  $ilLog->write(__METHOD__.': '.$e->getMessage());
5393  return false;
5394  }
5395  catch(Exception $e)
5396  {
5397  $ilLog->write(__METHOD__.': '.$e->getMessage());
5398  return false;
5399  }
5400 
5401  /*
5402  include_once "./Services/Transformation/classes/class.ilFO2PDF.php";
5403  $fo2pdf = new ilFO2PDF();
5404  $fo2pdf->setFOString($fo);
5405  $result = $fo2pdf->send();
5406  ilUtil::deliverData($result, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
5407  */
5408  }
5409 
5410  function _checkCondition($a_svy_id,$a_operator,$a_value,$a_usr_id = 0)
5411  {
5412  global $ilUser;
5413 
5414  $a_usr_id = $a_usr_id ? $a_usr_id : $ilUser->getId();
5415 
5416  switch($a_operator)
5417  {
5418  case 'finished':
5419  //if (ilExerciseMembers::_lookupStatus($a_exc_id, $ilias->account->getId()) == "passed")
5420  include_once("./Modules/Survey/classes/class.ilObjSurveyAccess.php");
5421  if (ilObjSurveyAccess::_lookupFinished($a_svy_id, $a_usr_id))
5422  {
5423  return true;
5424  }
5425  else
5426  {
5427  return false;
5428  }
5429  break;
5430 
5431  default:
5432  return true;
5433  }
5434  return true;
5435  }
5436 
5443  function isPluginActive($a_pname)
5444  {
5445  global $ilPluginAdmin;
5446  if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname))
5447  {
5448  return TRUE;
5449  }
5450  else
5451  {
5452  return FALSE;
5453  }
5454  }
5455 
5461  public function setSurveyId($survey_id)
5462  {
5463  $this->survey_id = $survey_id;
5464  }
5465 
5472  public function &getUserData($ids)
5473  {
5474  global $ilDB;
5475 
5476  if (!is_array($ids) || count($ids) ==0) return array();
5477 
5478  $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
5479  $result_array = array();
5480  while ($row = $ilDB->fetchAssoc($result))
5481  {
5482  $result_array[$row["usr_id"]]= $row;
5483  }
5484  return $result_array;
5485  }
5486 
5487  function &getGroupData($ids)
5488  {
5489  if (!is_array($ids) || count($ids) ==0) return array();
5490  $result = array();
5491  foreach ($ids as $ref_id)
5492  {
5493  $obj_id = ilObject::_lookupObjId($ref_id);
5494  $result[$ref_id] = array("ref_id" => $ref_id, "title" => ilObject::_lookupTitle($obj_id), "description" => ilObject::_lookupDescription($obj_id));
5495  }
5496  return $result;
5497  }
5498 
5499  function &getRoleData($ids)
5500  {
5501  if (!is_array($ids) || count($ids) ==0) return array();
5502  $result = array();
5503  foreach ($ids as $obj_id)
5504  {
5505  $result[$obj_id] = array("obj_id" => $obj_id, "title" => ilObject::_lookupTitle($obj_id), "description" => ilObject::_lookupDescription($obj_id));
5506  }
5507  return $result;
5508  }
5509 
5511  {
5512  return $this->mailnotification;
5513  }
5514 
5515  function setMailNotification($a_notification)
5516  {
5517  $this->mailnotification = ($a_notification) ? true : false;
5518  }
5519 
5520  function getMailAddresses()
5521  {
5522  return $this->mailaddresses;
5523  }
5524 
5525  function setMailAddresses($a_addresses)
5526  {
5527  $this->mailaddresses = $a_addresses;
5528  }
5529 
5531  {
5533  }
5534 
5535  function setMailParticipantData($a_data)
5536  {
5537  $this->mailparticipantdata = $a_data;
5538  }
5539 
5540  public function getSurveyTimes()
5541  {
5542  global $ilDB;
5543 
5544  $result = $ilDB->queryF("SELECT * FROM svy_times, svy_finished WHERE svy_finished.survey_fi = %s",
5545  array('integer'),
5546  array($this->getId())
5547  );
5548  $times = array();;
5549  while ($row = $ilDB->fetchAssoc($result))
5550  {
5551  if (strlen($row['left_page']) && strlen($row['entered_page']))
5552  $times[$row['finished_fi']] += ($row['left_page']-$row['entered_page']);
5553  }
5554  return $times;
5555  }
5556 
5557  function setStartTime($finished_id, $first_question)
5558  {
5559  global $ilDB;
5560  $time = time();
5561  $_SESSION['svy_entered_page'] = $time;
5562  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_times (finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s)",
5563  array('integer', 'integer', 'integer', 'integer'),
5564  array($finished_id, $time, NULL, $first_question)
5565  );
5566  }
5567 
5568  function setEndTime($finished_id)
5569  {
5570  global $ilDB;
5571  $time = time();
5572  $affectedRows = $ilDB->manipulateF("UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
5573  array('integer', 'integer', 'integer'),
5574  array($time, $finished_id, $_SESSION['svy_entered_page'])
5575  );
5576  unset($_SESSION['svy_entered_page']);
5577  }
5578 
5579  function getWorkingtimeForParticipant($finished_id)
5580  {
5581  global $ilDB;
5582 
5583  $result = $ilDB->queryF("SELECT * FROM svy_times WHERE finished_fi = %s",
5584  array('integer'),
5585  array($finished_id)
5586  );
5587  $total = 0;
5588  while ($row = $ilDB->fetchAssoc($result))
5589  {
5590  if ($row['left_page'] > 0 && $row['entered_page'] > 0)
5591  $total += $row['left_page'] - $row['entered_page'];
5592  }
5593  return $total;
5594  }
5595 
5597  {
5598  $this->template_id = (int)$template_id;
5599  }
5600 
5601  function getTemplate()
5602  {
5603  return $this->template_id;
5604  }
5605 
5606  function updateOrder(array $a_order)
5607  {
5608  if(sizeof($this->questions) == sizeof($a_order))
5609  {
5610  $this->questions = array_flip($a_order);
5611  $this->saveQuestionsToDB();
5612  }
5613  }
5614 
5615  function getPoolUsage()
5616  {
5617  return $this->pool_usage;
5618  }
5619 
5620  function setPoolUsage($a_value)
5621  {
5622  $this->pool_usage = (bool)$a_value;
5623  }
5624 
5630  function isPoolActive()
5631  {
5632  $use_pool = (bool)$this->getPoolUsage();
5633  $template_settings = $this->getTemplate();
5634  if($template_settings)
5635  {
5636  include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
5637  $template_settings = new ilSettingsTemplate($template_settings);
5638  $template_settings = $template_settings->getSettings();
5639  $template_settings = $template_settings["use_pool"];
5640  if($template_settings && $template_settings["hide"])
5641  {
5642  $use_pool = (bool)$template_settings["value"];
5643  }
5644  }
5645  return $use_pool;
5646  }
5647 
5654  {
5655  if(!$template_id)
5656  {
5657  return;
5658  }
5659 
5660  include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
5661  $template = new ilSettingsTemplate($template_id);
5662  $template_settings = $template->getSettings();
5663  if($template_settings)
5664  {
5665  if($template_settings["show_question_titles"] !== NULL)
5666  {
5667  if($template_settings["show_question_titles"]["value"])
5668  {
5669  $this->setShowQuestionTitles(true);
5670  }
5671  else
5672  {
5673  $this->setShowQuestionTitles(false);
5674  }
5675  }
5676 
5677  if($template_settings["use_pool"] !== NULL)
5678  {
5679  if($template_settings["use_pool"]["value"])
5680  {
5681  $this->setPoolUsage(true);
5682  }
5683  else
5684  {
5685  $this->setPoolUsage(false);
5686  }
5687  }
5688 
5689  if($template_settings["anonymization_options"]["value"])
5690  {
5691  $anon_map = array('personalized' => self::ANONYMIZE_OFF,
5692  'anonymize_with_code' => self::ANONYMIZE_ON,
5693  'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
5694  $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
5695  }
5696 
5697  /* other settings: not needed here
5698  * - enabled_end_date
5699  * - enabled_start_date
5700  * - rte_switch
5701  */
5702  }
5703 
5704  $this->setTemplate($template_id);
5705  $this->saveToDb();
5706  }
5707 
5708  public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
5709  {
5710  global $ilDB;
5711 
5712  $a_email = trim($a_email);
5713 
5714  // :TODO:
5715  if($a_email && !ilUtil::is_email($a_email))
5716  {
5717  return;
5718  }
5719 
5720  $data = array("email" => $a_email,
5721  "lastname" => trim($a_last_name),
5722  "firstname" => trim($a_first_name));
5723 
5724  $fields = array(
5725  "externaldata" => array("text", serialize($data)),
5726  "sent" => array("integer", $a_sent)
5727  );
5728 
5729  $ilDB->update("svy_anonymous", $fields,
5730  array("anonymous_id" => array("integer", $a_id)));
5731  }
5732 
5733 
5734  //
5735  // 360°
5736  //
5737 
5738  public function set360Mode($a_value)
5739  {
5740  $this->mode_360 = (bool)$a_value;
5741  }
5742 
5743  public function get360Mode()
5744  {
5745  return (bool)$this->mode_360;
5746  }
5747 
5748  public function set360SelfEvaluation($a_value)
5749  {
5750  $this->mode_360_self_eval = (bool)$a_value;
5751  }
5752 
5753  public function get360SelfEvaluation()
5754  {
5755  return (bool)$this->mode_360_self_eval;
5756  }
5757 
5758  public function set360SelfAppraisee($a_value)
5759  {
5760  $this->mode_360_self_appr = (bool)$a_value;
5761  }
5762 
5763  public function get360SelfAppraisee()
5764  {
5765  return (bool)$this->mode_360_self_appr;
5766  }
5767 
5768  public function set360SelfRaters($a_value)
5769  {
5770  $this->mode_360_self_rate = (bool)$a_value;
5771  }
5772 
5773  public function get360SelfRaters()
5774  {
5775  return (bool)$this->mode_360_self_rate;
5776  }
5777 
5778  public function set360Results($a_value)
5779  {
5780  $this->mode_360_results = (int)$a_value;
5781  }
5782 
5783  public function get360Results()
5784  {
5785  return (int)$this->mode_360_results;
5786  }
5787 
5788  public function addAppraisee($a_user_id)
5789  {
5790  global $ilDB;
5791 
5792  if(!$this->isAppraisee($a_user_id) &&
5793  $a_user_id != ANONYMOUS_USER_ID)
5794  {
5795  $fields = array(
5796  "obj_id" => array("integer", $this->getSurveyId()),
5797  "user_id" => array("integer", $a_user_id)
5798  );
5799  $ilDB->insert("svy_360_appr", $fields);
5800  }
5801  }
5802 
5803  public function isAppraisee($a_user_id)
5804  {
5805  global $ilDB;
5806 
5807  $set = $ilDB->query("SELECT user_id".
5808  " FROM svy_360_appr".
5809  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5810  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5811  return (bool)$ilDB->numRows($set);
5812  }
5813 
5814  public function isAppraiseeClosed($a_user_id)
5815  {
5816  global $ilDB;
5817 
5818  $set = $ilDB->query("SELECT has_closed".
5819  " FROM svy_360_appr".
5820  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5821  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5822  $row = $ilDB->fetchAssoc($set);
5823  return $row["has_closed"];
5824  }
5825 
5826  public function deleteAppraisee($a_user_id)
5827  {
5828  global $ilDB;
5829 
5830  $ilDB->manipulate("DELETE FROM svy_360_appr".
5831  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5832  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5833 
5834  $set = $ilDB->query("SELECT user_id".
5835  " FROM svy_360_rater".
5836  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5837  " AND appr_id = ".$ilDB->quote($a_user_id, "integer"));
5838  while($row = $ilDB->fetchAssoc($set))
5839  {
5840  $this->deleteRater($a_user_id, $row["user_id"]);
5841  }
5842  // appraisee will not be part of raters table
5843  if($this->get360SelfEvaluation())
5844  {
5845  $this->deleteRater($a_user_id, $a_user_id);
5846  }
5847  }
5848 
5849  public function getAppraiseesData()
5850  {
5851  global $ilDB;
5852 
5853  $res = array();
5854 
5855  $set = $ilDB->query("SELECT * FROM svy_360_appr".
5856  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer"));
5857  while($row = $ilDB->fetchAssoc($set))
5858  {
5859  $name = ilObjUser::_lookupName($row["user_id"]);
5860  $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5861  $res[$row["user_id"]] = $name;
5862 
5863  $finished = 0;
5864  $raters = $this->getRatersData($row["user_id"]);
5865  foreach($raters as $rater)
5866  {
5867  if($rater["finished"])
5868  {
5869  $finished++;
5870  }
5871  }
5872  $res[$row["user_id"]]["finished"] = $finished."/".sizeof($raters);
5873  $res[$row["user_id"]]["closed"] = $row["has_closed"];
5874  }
5875 
5876  return $res;
5877  }
5878 
5879  public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5880  {
5881  global $ilDB;
5882 
5883  if($this->isAppraisee($a_appraisee_id) &&
5884  !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id))
5885  {
5886  $fields = array(
5887  "obj_id" => array("integer", $this->getSurveyId()),
5888  "appr_id" => array("integer", $a_appraisee_id),
5889  "user_id" => array("integer", $a_user_id),
5890  "anonymous_id" => array("integer", $a_anonymous_id)
5891  );
5892  $ilDB->insert("svy_360_rater", $fields);
5893  }
5894  }
5895 
5896  public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5897  {
5898  global $ilDB;
5899 
5900  // user is rater if already appraisee and active self-evaluation
5901  if($this->isAppraisee($a_user_id) &&
5902  $this->get360SelfEvaluation() &&
5903  (!$a_appraisee_id || $a_appraisee_id == $a_user_id))
5904  {
5905  return true;
5906  }
5907 
5908  // :TODO: should we get rid of code as well?
5909 
5910  $sql = "SELECT user_id".
5911  " FROM svy_360_rater".
5912  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5913  " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5914  " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer");
5915  if($a_appraisee_id)
5916  {
5917  $sql .= " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer");
5918  }
5919  $set = $ilDB->query($sql);
5920  return (bool)$ilDB->numRows($set);
5921  }
5922 
5923  public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5924  {
5925  global $ilDB;
5926 
5927  $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5928  if($finished_id)
5929  {
5930  $this->removeSelectedSurveyResults(array($finished_id));
5931  }
5932 
5933  $ilDB->manipulate("DELETE FROM svy_360_rater".
5934  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5935  " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer").
5936  " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5937  " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer"));
5938  }
5939 
5940  public function getRatersData($a_appraisee_id)
5941  {
5942  global $ilDB;
5943 
5944  $res = $anonymous_ids = array();
5945 
5946  $set = $ilDB->query("SELECT * FROM svy_360_rater".
5947  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5948  " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer"));
5949  while($row = $ilDB->fetchAssoc($set))
5950  {
5951  if($row["anonymous_id"])
5952  {
5953  $res["a".$row["anonymous_id"]] = array(
5954  "lastname" => "unknown code ".$row["anonymous_id"],
5955  "sent" => $row["mail_sent"],
5956  "finished" => null
5957  );
5958  $anonymous_ids[] = $row["anonymous_id"];
5959  }
5960  else
5961  {
5962  $name = ilObjUser::_lookupName($row["user_id"]);
5963  $name["user_id"] = "u".$name["user_id"];
5964  $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5965  $name["sent"] = $row["mail_sent"];
5966  $name["finished"] = (bool)$this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
5967  $res["u".$row["user_id"]] = $name;
5968  }
5969  }
5970 
5971  if(sizeof($anonymous_ids))
5972  {
5973  $data = $this->getSurveyCodesTableData($anonymous_ids);
5974  foreach($data as $item)
5975  {
5976  if(isset($res["a".$item["id"]]))
5977  {
5978  $res["a".$item["id"]] = array(
5979  "user_id" => "a".$item["id"],
5980  "lastname" => $item["last_name"],
5981  "firstname" => $item["first_name"],
5982  "login" => "",
5983  "email" => $item["email"],
5984  "code" => $item["code"],
5985  "href" => $item["href"],
5986  "sent" => $res["a".$item["id"]]["sent"],
5987  "finished" => (bool)$this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
5988  );
5989  }
5990  }
5991  }
5992 
5993  return $res;
5994  }
5995 
5996  public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
5997  {
5998  global $ilDB;
5999 
6000  $res = array();
6001 
6002  $sql = "SELECT appr_id FROM svy_360_rater".
6003  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer");
6004 
6005  if($a_user_id)
6006  {
6007  $sql .= " AND user_id = ".$ilDB->quote($a_user_id, "integer");
6008  }
6009  else
6010  {
6011  $sql .= " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer");
6012  }
6013 
6014  $set = $ilDB->query($sql);
6015  while($row = $ilDB->fetchAssoc($set))
6016  {
6017  $res[] = $row["appr_id"];
6018  }
6019 
6020  // user may evaluate himself if already appraisee
6021  if($this->get360SelfEvaluation() &&
6022  $this->isAppraisee($a_user_id) &&
6023  !in_array($a_user_id, $res))
6024  {
6025  $res[] = $a_user_id;
6026  }
6027 
6028  return $res;
6029  }
6030 
6031  public function getAnonymousIdByCode($a_code)
6032  {
6033  global $ilDB;
6034 
6035  $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous".
6036  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6037  " AND survey_key = ".$ilDB->quote($a_code, "text"));
6038  $res = $ilDB->fetchAssoc($set);
6039  return $res["anonymous_id"];
6040  }
6041 
6042  function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
6043  {
6044  global $ilDB;
6045 
6046  $sql = "SELECT * FROM svy_finished".
6047  " WHERE survey_fi =".$ilDB->quote($this->getSurveyId(), "integer").
6048  " AND appr_id = ".$ilDB->quote($appr_id, "integer");
6049  if ($user_id)
6050  {
6051  $sql .= " AND user_fi = ".$ilDB->quote($user_id, "integer");
6052  }
6053  else
6054  {
6055  $sql .= " AND anonymous_id = ".$ilDB->quote($anonymous_code, "text");
6056  }
6057  $result = $ilDB->query($sql);
6058  if ($result->numRows() == 0)
6059  {
6060  return false;
6061  }
6062  else
6063  {
6064  $row = $ilDB->fetchAssoc($result);
6065  return (int)$row["state"];
6066  }
6067  }
6068 
6069  function getUserSurveyExecutionStatus($a_code = null)
6070  {
6071  global $ilUser, $ilDB;
6072 
6073  $user_id = $ilUser->getId();
6074 
6075  // code is obligatory?
6076  if(!$this->isAccessibleWithoutCode())
6077  {
6078  if(!$a_code)
6079  {
6080  // registered raters do not need code
6081  if($this->get360Mode() &&
6082  $user_id != ANONYMOUS_USER_ID &&
6083  $this->isRater(0, $user_id))
6084  {
6085  // auto-generate code
6086  $a_code = $this->createNewAccessCode();
6087  $this->saveUserAccessCode($user_id, $a_code);
6088  }
6089  else
6090  {
6091  return null;
6092  }
6093  }
6094  }
6095  else if($user_id == ANONYMOUS_USER_ID || $this->getAnonymize())
6096  {
6097  if(!$a_code)
6098  {
6099  // auto-generate code
6100  $a_code = $this->createNewAccessCode();
6101  $this->saveUserAccessCode($user_id, $a_code);
6102  }
6103  }
6104  else
6105  {
6106  $a_code = null;
6107  }
6108 
6109  $res = array();
6110 
6111  $sql = "SELECT * FROM svy_finished".
6112  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
6113  // if proper user id is given, use it or current code
6114  if($user_id != ANONYMOUS_USER_ID)
6115  {
6116  $sql .= " AND (user_fi = ".$ilDB->quote($user_id, "integer").
6117  " OR anonymous_id = ".$ilDB->quote($a_code, "text").")";
6118  }
6119  // use anonymous code to find finished id(s)
6120  else
6121  {
6122  $sql .= " AND anonymous_id = ".$ilDB->quote($a_code, "text");
6123  }
6124  $set = $ilDB->query($sql);
6125  while($row = $ilDB->fetchAssoc($set))
6126  {
6127  $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
6128  "user_id" => $row["user_fi"],
6129  "code" => $row["anonymous_id"],
6130  "finished" => (bool)$row["state"]);
6131  }
6132 
6133  return array("code"=>$a_code, "runs"=>$res);
6134  }
6135 
6136  function findCodeForUser($a_user_id)
6137  {
6138  global $ilDB;
6139 
6140  if($a_user_id != ANONYMOUS_USER_ID)
6141  {
6142  $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf".
6143  " WHERE sf.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6144  " AND sf.user_fi = ".$ilDB->quote($a_user_id, "integer"));
6145  $a_code = $ilDB->fetchAssoc($set);
6146  return $a_code["anonymous_id"];
6147  }
6148  }
6149 
6150  function isUnusedCode($a_code, $a_user_id)
6151  {
6152  global $ilDB;
6153 
6154  $set = $ilDB->query("SELECT user_fi FROM svy_finished".
6155  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6156  " AND anonymous_id = ".$ilDB->quote($a_code, "text"));
6157  $user_id = $ilDB->fetchAssoc($set);
6158  $user_id = $user_id["user_fi"];
6159 
6160  if($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID))
6161  {
6162  return false;
6163  }
6164  return true;
6165  }
6166 
6167  function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
6168  {
6169  global $ilDB;
6170 
6171  $res = array();
6172 
6173  $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished".
6174  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6175  " AND appr_id = ".$ilDB->quote($a_appr_id, "integer"));
6176  while($row = $ilDB->fetchAssoc($set))
6177  {
6178  if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id)
6179  {
6180  continue;
6181  }
6182  $res[] = $row["finished_id"];
6183  }
6184 
6185  return $res;
6186  }
6187 
6195  function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
6196  {
6197  global $ilDB;
6198 
6199  $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished".
6200  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6201  " AND appr_id = ".$ilDB->quote($a_appr_id, "integer").
6202  " AND user_fi = ".$ilDB->quote($a_rat_id, "integer"));
6203  $row = $ilDB->fetchAssoc($set);
6204  return $row["finished_id"];
6205  }
6206 
6207 
6208  // 360° using competence/skill service
6209 
6215  function set360SkillService($a_val)
6216  {
6217  $this->mode_360_skill_service = $a_val;
6218  }
6219 
6226  {
6228  }
6229 
6230  function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
6231  {
6232  global $ilDB;
6233 
6234  if(!$a_tstamp)
6235  {
6236  $a_tstamp = time();
6237  }
6238 
6239  $ilDB->manipulate("UPDATE svy_360_rater".
6240  " SET mail_sent = ".$ilDB->quote($a_tstamp, "integer").
6241  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
6242  " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer").
6243  " AND user_id = ".$ilDB->quote($a_user_id, "integer").
6244  " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer"));
6245  }
6246 
6247  function closeAppraisee($a_user_id)
6248  {
6249  global $ilDB;
6250 
6251  // close the appraisee
6252  $ilDB->manipulate("UPDATE svy_360_appr".
6253  " SET has_closed = ".$ilDB->quote(time(), "integer").
6254  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
6255  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
6256 
6257  // write competences
6258  include_once("./Services/Skill/classes/class.ilSkillManagementSettings.php");
6259  $skmg_set = new ilSkillManagementSettings();
6260  if ($this->get360SkillService() && $skmg_set->isActivated())
6261  {
6262  include_once("./Modules/Survey/classes/class.ilSurveySkill.php");
6263  $sskill = new ilSurveySkill($this);
6264  $sskill->writeAppraiseeSkills($a_user_id);
6265  }
6266  }
6267 
6269  {
6270  global $ilDB;
6271 
6272  $ilDB->manipulate("UPDATE svy_360_appr".
6273  " SET has_closed = ".$ilDB->quote(null, "integer").
6274  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer"));
6275  }
6276 
6277  public static function validateExternalRaterCode($a_ref_id, $a_code)
6278  {
6279  if(!isset($_SESSION["360_extrtr"][$a_ref_id]))
6280  {
6281  $svy = new self($a_ref_id);
6282  $svy->loadFromDB();
6283 
6284  if($svy->canStartSurvey(null, true) &&
6285  $svy->get360Mode() &&
6286  $svy->isAnonymousKey($a_code))
6287  {
6288  $anonymous_id = $svy->getAnonymousIdByCode($a_code);
6289  if($anonymous_id)
6290  {
6291  if(sizeof($svy->getAppraiseesToRate(null, $anonymous_id)))
6292  {
6293  $_SESSION["360_extrtr"][$a_ref_id] = true;
6294  return true;
6295  }
6296  }
6297  }
6298 
6299  $_SESSION["360_extrtr"][$a_ref_id] = false;
6300  return false;
6301  }
6302 
6303  return $_SESSION["360_extrtr"][$a_ref_id];
6304  }
6305 
6306 
6307  //
6308  // reminder/notification
6309  //
6310 
6311  public function getReminderStatus()
6312  {
6313  return (bool)$this->reminder_status;
6314  }
6315 
6316  public function setReminderStatus($a_value)
6317  {
6318  $this->reminder_status = (bool)$a_value;
6319  }
6320 
6321  public function getReminderStart()
6322  {
6323  return $this->reminder_start;
6324  }
6325 
6326  public function setReminderStart(ilDate $a_value = null)
6327  {
6328  $this->reminder_start = $a_value;
6329  }
6330 
6331  public function getReminderEnd()
6332  {
6333  return $this->reminder_end;
6334  }
6335 
6336  public function setReminderEnd(ilDate $a_value = null)
6337  {
6338  $this->reminder_end = $a_value;
6339  }
6340 
6341  public function getReminderFrequency()
6342  {
6344  }
6345 
6346  public function setReminderFrequency($a_value)
6347  {
6348  $this->reminder_frequency = (int)$a_value;
6349  }
6350 
6351  public function getReminderTarget()
6352  {
6353  return $this->reminder_target;
6354  }
6355 
6356  public function setReminderTarget($a_value)
6357  {
6358  $this->reminder_target = (int)$a_value;
6359  }
6360 
6361  public function getReminderLastSent()
6362  {
6364  }
6365 
6366  public function setReminderLastSent($a_value)
6367  {
6368  $this->reminder_last_sent = $a_value;
6369  }
6370 
6371  public function getTutorNotificationStatus()
6372  {
6373  return (bool)$this->tutor_ntf_status;
6374  }
6375 
6376  public function setTutorNotificationStatus($a_value)
6377  {
6378  $this->tutor_ntf_status = (bool)$a_value;
6379  }
6380 
6382  {
6384  }
6385 
6386  public function setTutorNotificationRecipients(array $a_value)
6387  {
6388  $this->tutor_ntf_recipients = $a_value;
6389  }
6390 
6391  public function getTutorNotificationTarget()
6392  {
6393  return $this->tutor_ntf_target;
6394  }
6395 
6396  public function setTutorNotificationTarget($a_value)
6397  {
6398  $this->tutor_ntf_target = (int)$a_value;
6399  }
6400 
6401  protected function checkTutorNotification()
6402  {
6403  global $ilDB;
6404 
6405  if($this->getTutorNotificationStatus())
6406  {
6407  $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
6408  if($user_ids)
6409  {
6410  $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished".
6411  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6412  " AND state = ".$ilDB->quote(1, "integer").
6413  " AND ".$ilDB->in("user_fi", $user_ids, "", "integer"));
6414  $row = $ilDB->fetchAssoc($set);
6415  if($row["numall"] == sizeof($user_ids))
6416  {
6417  $this->sendTutorNotification();
6418  }
6419  }
6420  }
6421  }
6422 
6423  protected function getNotificationTargetUserIds($a_use_invited)
6424  {
6425  global $tree;
6426 
6427  if((bool)$a_use_invited)
6428  {
6429  $user_ids = $this->getInvitedUsers();
6430  }
6431  else
6432  {
6433  $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
6434  if($parent_grp_ref_id)
6435  {
6436  include_once "Modules/Group/classes/class.ilGroupParticipants.php";
6437  $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
6438  $user_ids = $part->getMembers();
6439  }
6440  else
6441  {
6442  $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
6443  if($parent_crs_ref_id)
6444  {
6445  include_once "Modules/Course/classes/class.ilCourseParticipants.php";
6446  $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
6447  $user_ids = $part->getMembers();
6448  }
6449  }
6450  }
6451  return $user_ids;
6452  }
6453 
6454  protected function sendTutorNotification()
6455  {
6456  include_once "./Services/Mail/classes/class.ilMail.php";
6457  include_once "./Services/User/classes/class.ilObjUser.php";
6458  include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6459  include_once "./Services/User/classes/class.ilUserUtil.php";
6460  include_once "./Services/Link/classes/class.ilLink.php";
6461  $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6462 
6463  foreach($this->getTutorNotificationRecipients() as $user_id)
6464  {
6465  // use language of recipient to compose message
6466  $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6467  $ulng->loadLanguageModule('survey');
6468 
6469  $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
6470  $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id))."\n\n";
6471 
6472  $message .= $ulng->txt('survey_notification_tutor_body').":\n\n";
6473  $message .= $ulng->txt('obj_svy').": ". $this->getTitle()."\n";
6474  $message .= "\n".$ulng->txt('survey_notification_tutor_link').": ".$link;
6475 
6476  $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6477  $mail_obj->appendInstallationSignature(true);
6478  $mail_obj->sendMail(ilObjUser::_lookupLogin($user_id),
6479  "", "", $subject, $message, array(), array("system"));
6480  }
6481  }
6482 
6483  public function checkReminder()
6484  {
6485  global $ilDB, $ilAccess;
6486 
6487  $now = time();
6488  $today = date("Y-m-d");
6489 
6490  // object settings / participation period
6491  if($this->isOffline() ||
6492  !$this->getReminderStatus() ||
6493  ($this->getStartDate() && $now < $this->getStartDate()) ||
6494  ($this->getEndDate() && $now > $this->getEndDate()))
6495  {
6496  return false;
6497  }
6498 
6499  // reminder period
6500  $start = $this->getReminderStart();
6501  if($start)
6502  {
6503  $start = $start->get(IL_CAL_DATE);
6504  }
6505  $end = $this->getReminderEnd();
6506  if($end)
6507  {
6508  $end = $end->get(IL_CAL_DATE);
6509  }
6510  if($today < $start ||
6511  ($end && $today > $end))
6512  {
6513  return false;
6514  }
6515 
6516  // object access period
6517  include_once "Services/Object/classes/class.ilObjectActivation.php";
6518  $item_data = ilObjectActivation::getItem($this->getRefId());
6519  if($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
6520  ($now < $item_data["timing_start"] ||
6521  $now > $item_data["timing_end"]))
6522  {
6523  return false;
6524  }
6525 
6526  // check frequency
6527  $cut = new ilDate($today, IL_CAL_DATE);
6528  $cut->increment(IL_CAL_DAY, $this->getReminderFrequency()*-1);
6529  if(!$this->getReminderLastSent() ||
6530  $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10))
6531  {
6532  // #16871
6533  $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
6534  if($user_ids)
6535  {
6536  // gather participants who already finished
6537  $finished_ids = array();
6538  $set = $ilDB->query("SELECT user_fi FROM svy_finished".
6539  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6540  " AND state = ".$ilDB->quote(1, "text").
6541  " AND ".$ilDB->in("user_fi", $user_ids, "", "integer"));
6542  while($row = $ilDB->fetchAssoc($set))
6543  {
6544  $finished_ids[] = $row["user_fi"];
6545  }
6546 
6547  // some users missing out?
6548  $missing_ids = array_diff($user_ids, $finished_ids);
6549  if($missing_ids)
6550  {
6551  foreach($missing_ids as $idx => $user_id)
6552  {
6553  // should be able to participate
6554  if(!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
6555  {
6556  unset($missing_ids[$idx]);
6557  }
6558  }
6559  }
6560  if($missing_ids)
6561  {
6562  $this->sentReminder($missing_ids);
6563  }
6564  }
6565 
6566  $this->setReminderLastSent($today);
6567  $this->saveToDb();
6568 
6569  return true;
6570  }
6571 
6572  return false;
6573  }
6574 
6575  protected function sentReminder(array $a_recipient_ids)
6576  {
6577  include_once "./Services/Mail/classes/class.ilMail.php";
6578  include_once "./Services/User/classes/class.ilObjUser.php";
6579  include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6580  include_once "./Services/User/classes/class.ilUserUtil.php";
6581  include_once "./Services/Link/classes/class.ilLink.php";
6582  $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6583 
6584  foreach($a_recipient_ids as $user_id)
6585  {
6586  // use language of recipient to compose message
6587  $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6588  $ulng->loadLanguageModule('survey');
6589 
6590  $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
6591  $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id))."\n\n";
6592 
6593  $message .= $ulng->txt('survey_reminder_body').":\n\n";
6594  $message .= $ulng->txt('obj_svy').": ". $this->getTitle()."\n";
6595  $message .= "\n".$ulng->txt('survey_reminder_link').": ".$link;
6596 
6597  $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6598  $mail_obj->appendInstallationSignature(true);
6599  $mail_obj->sendMail(ilObjUser::_lookupLogin($user_id),
6600  "", "", $subject, $message, array(), array("system"));
6601  }
6602  }
6603 
6604  function setActivationStartDate($starting_time = NULL)
6605  {
6606  $this->activation_starting_time = $starting_time;
6607  }
6608 
6609  function setActivationEndDate($ending_time = NULL)
6610  {
6611  $this->activation_ending_time = $ending_time;
6612  }
6613 
6615  {
6616  return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : NULL;
6617  }
6618 
6620  {
6621  return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : NULL;
6622  }
6623 
6624  public static function getSurveySkippedValue()
6625  {
6626  global $lng;
6627 
6628  // #13541
6629 
6630  include_once "./Services/Administration/classes/class.ilSetting.php";
6631  $surveySetting = new ilSetting("survey");
6632  if(!$surveySetting->get("skipped_is_custom", false))
6633  {
6634  return $lng->txt("skipped");
6635  }
6636  else
6637  {
6638  return $surveySetting->get("skipped_custom_value", "");
6639  }
6640  }
6641 
6642 } // END class.ilObjSurvey
6643 
6644 ?>