ILIAS  Release_5_0_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; // personalized, no codes
31  const ANONYMIZE_ON = 1; // anonymized, codes
32  const ANONYMIZE_FREEACCESS = 2; // anonymized, no codes
33  const ANONYMIZE_CODE_ALL = 3; // personalized, codes
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 
169  protected $view_own_results; // [bool]
170  protected $mail_own_results; // [bool]
171 
174 
175 
182  function ilObjSurvey($a_id = 0,$a_call_by_reference = true)
183  {
184  global $ilUser, $lng;
185 
186  $this->type = "svy";
187  $this->survey_id = -1;
188  $this->introduction = "";
189  $this->outro = $lng->txt("survey_finished");
190  $this->author = $ilUser->getFullname();
191  $this->status = self::STATUS_OFFLINE;
192  $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
193  $this->questions = array();
194  $this->invitation = self::INVITATION_OFF;
195  $this->invitation_mode = self::MODE_PREDEFINED_USERS;
196  $this->anonymize = self::ANONYMIZE_OFF;
197  $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
198  $this->surveyCodeSecurity = TRUE;
199  $this->template_id = NULL;
200  $this->pool_usage = true;
201 
202  parent::__construct($a_id,$a_call_by_reference);
203  }
204 
208  function create($a_upload = false)
209  {
210  parent::create();
211  if(!$a_upload)
212  {
213  $this->createMetaData();
214  }
215  }
216 
222  function createMetaData()
223  {
225  $this->saveAuthorToMetadata();
226  }
227 
234  function update()
235  {
236  $this->updateMetaData();
237 
238  if (!parent::update())
239  {
240  return false;
241  }
242 
243  // put here object specific stuff
244 
245  return true;
246  }
247 
248  function createReference()
249  {
251  $this->saveToDb();
252  return $result;
253  }
254 
260  function read($a_force_db = false)
261  {
262  parent::read($a_force_db);
263  $this->loadFromDb();
264  }
265 
272  function addQuestion($question_id)
273  {
274  array_push($this->questions, $question_id);
275  }
276 
277 
284  function delete()
285  {
286  $remove = parent::delete();
287  // always call parent delete function first!!
288  if (!$remove)
289  {
290  return false;
291  }
292 
293  $this->deleteMetaData();
294 
295  // Delete all survey questions, constraints and materials
296  foreach ($this->questions as $question_id)
297  {
298  $this->removeQuestion($question_id);
299  }
300  $this->deleteSurveyRecord();
301 
303  return true;
304  }
305 
312  {
313  global $ilDB;
314 
315  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_svy WHERE survey_id = %s",
316  array('integer'),
317  array($this->getSurveyId())
318  );
319 
320  $result = $ilDB->queryF("SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
321  array('integer'),
322  array($this->getSurveyId())
323  );
324  $questionblocks = array();
325  while ($row = $ilDB->fetchAssoc($result))
326  {
327  array_push($questionblocks, $row["questionblock_fi"]);
328  }
329  if (count($questionblocks))
330  {
331  $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
332  }
333  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
334  array('integer'),
335  array($this->getSurveyId())
336  );
337  $this->deleteAllUserData();
338 
339  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_anonymous WHERE survey_fi = %s",
340  array('integer'),
341  array($this->getSurveyId())
342  );
343 
344  // delete export files
345  include_once "./Services/Utilities/classes/class.ilUtil.php";
346  $svy_data_dir = ilUtil::getDataDir()."/svy_data";
347  $directory = $svy_data_dir."/svy_".$this->getId();
348  if (is_dir($directory))
349  {
350  include_once "./Services/Utilities/classes/class.ilUtil.php";
351  ilUtil::delDir($directory);
352  }
353 
354  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
355  $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
356  // remaining usages are not in text anymore -> delete them
357  // and media objects (note: delete method of ilObjMediaObject
358  // checks whether object is used in another context; if yes,
359  // the object is not deleted!)
360  foreach($mobs as $mob)
361  {
362  ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
363  $mob_obj =& new ilObjMediaObject($mob);
364  $mob_obj->delete();
365  }
366  }
367 
373  function deleteAllUserData()
374  {
375  global $ilDB;
376 
377  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
378  array('integer'),
379  array($this->getSurveyId())
380  );
381  $active_array = array();
382  while ($row = $ilDB->fetchAssoc($result))
383  {
384  array_push($active_array, $row["finished_id"]);
385  }
386 
387  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_finished WHERE survey_fi = %s",
388  array('integer'),
389  array($this->getSurveyId())
390  );
391 
392  foreach ($active_array as $active_fi)
393  {
394  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE active_fi = %s",
395  array('integer'),
396  array($active_fi)
397  );
398  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_times WHERE finished_fi = %s",
399  array('integer'),
400  array($active_fi)
401  );
402  }
403  }
404 
410  function removeSelectedSurveyResults($finished_ids)
411  {
412  global $ilDB;
413 
414  foreach ($finished_ids as $finished_id)
415  {
416  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE finished_id = %s",
417  array('integer'),
418  array($finished_id)
419  );
420  $row = $ilDB->fetchAssoc($result);
421 
422  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE active_fi = %s",
423  array('integer'),
424  array($row["finished_id"])
425  );
426 
427  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_finished WHERE finished_id = %s",
428  array('integer'),
429  array($finished_id)
430  );
431 
432  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_times WHERE finished_fi = %s",
433  array('integer'),
434  array($row["finished_id"])
435  );
436  }
437  }
438 
439  function &getSurveyParticipants($finished_ids = null)
440  {
441  global $ilDB;
442 
443  $sql = "SELECT * FROM svy_finished".
444  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
445  if($finished_ids)
446  {
447  $sql .= " AND ".$ilDB->in("finished_id", $finished_ids, "", "integer");
448  }
449 
450  $result = $ilDB->query($sql);
451  $participants = array();
452  if ($result->numRows() > 0)
453  {
454  while ($row = $ilDB->fetchAssoc($result))
455  {
456  $userdata = $this->getUserDataFromActiveId($row["finished_id"]);
457  $userdata["finished"] = (bool)$row["state"];
458  $userdata["finished_tstamp"] = $row["tstamp"];
459  $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
460  }
461  }
462  return $participants;
463  }
464 
478  function notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params = 0)
479  {
480  global $tree;
481 
482  switch ($a_event)
483  {
484  case "link":
485 
486  //var_dump("<pre>",$a_params,"</pre>");
487  //echo "Module name ".$this->getRefId()." triggered by link event. Objects linked into target object ref_id: ".$a_ref_id;
488  //exit;
489  break;
490 
491  case "cut":
492 
493  //echo "Module name ".$this->getRefId()." triggered by cut event. Objects are removed from target object ref_id: ".$a_ref_id;
494  //exit;
495  break;
496 
497  case "copy":
498 
499  //var_dump("<pre>",$a_params,"</pre>");
500  //echo "Module name ".$this->getRefId()." triggered by copy event. Objects are copied into target object ref_id: ".$a_ref_id;
501  //exit;
502  break;
503 
504  case "paste":
505 
506  //echo "Module name ".$this->getRefId()." triggered by paste (cut) event. Objects are pasted into target object ref_id: ".$a_ref_id;
507  //exit;
508  break;
509 
510  case "new":
511 
512  //echo "Module name ".$this->getRefId()." triggered by paste (new) event. Objects are applied to target object ref_id: ".$a_ref_id;
513  //exit;
514  break;
515  }
516 
517  // At the beginning of the recursive process it avoids second call of the notify function with the same parameter
518  if ($a_node_id==$_GET["ref_id"])
519  {
520  $parent_obj =& $this->ilias->obj_factory->getInstanceByRefId($a_node_id);
521  $parent_type = $parent_obj->getType();
522  if($parent_type == $this->getType())
523  {
524  $a_node_id = (int) $tree->getParentId($a_node_id);
525  }
526  }
527 
528  parent::notify($a_event,$a_ref_id,$a_parent_non_rbac_id,$a_node_id,$a_params);
529  }
530 
537  function isComplete()
538  {
539  if (($this->getTitle()) and (count($this->questions)))
540  {
541  return 1;
542  }
543  else
544  {
545  return 0;
546  }
547  }
548 
555  function _isComplete($obj_id)
556  {
557  $survey = new ilObjSurvey($obj_id, false);
558  $survey->loadFromDb();
559  if (($survey->getTitle()) and (count($survey->questions)))
560  {
561  return 1;
562  }
563  else
564  {
565  return 0;
566  }
567  }
568 
575  function &_getGlobalSurveyData($obj_id)
576  {
577  $survey = new ilObjSurvey($obj_id, false);
578  $survey->loadFromDb();
579  $result = array();
580  if (($survey->getTitle()) and ($survey->author) and (count($survey->questions)))
581  {
582  $result["complete"] = true;
583  }
584  else
585  {
586  $result["complete"] = false;
587  }
588  $result["evaluation_access"] = $survey->getEvaluationAccess();
589  return $result;
590  }
591 
598  {
599  global $ilDB;
600 
601  $complete = 0;
602  if ($this->isComplete())
603  {
604  $complete = 1;
605  }
606  if ($this->getSurveyId() > 0)
607  {
608  $affectedRows = $ilDB->manipulateF("UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
609  array('text','integer','integer'),
610  array($this->isComplete(), time(), $this->getSurveyId())
611  );
612  }
613  }
614 
622  function duplicateQuestionForSurvey($question_id, $a_force = false)
623  {
624  global $ilUser;
625 
626  $questiontype = $this->getQuestionType($question_id);
627  $question_gui = $this->getQuestionGUI($questiontype, $question_id);
628 
629  // check if question is a pool question at all, if not do nothing
630  if($this->getId() == $question_gui->object->getObjId() && !$a_force)
631  {
632  return $question_id;
633  }
634 
635  $duplicate_id = $question_gui->object->duplicate(true);
636  return $duplicate_id;
637  }
638 
644  function insertQuestion($question_id)
645  {
646  global $ilDB;
647 
648  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
649  if (!SurveyQuestion::_isComplete($question_id))
650  {
651  return FALSE;
652  }
653  else
654  {
655  // get maximum sequence index in test
656  $result = $ilDB->queryF("SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
657  array('integer'),
658  array($this->getSurveyId())
659  );
660  $sequence = $result->numRows();
661  $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
662  $next_id = $ilDB->nextId('svy_svy_qst');
663  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
664  array('integer', 'integer', 'integer', 'integer', 'integer'),
665  array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
666  );
667  $this->loadQuestionsFromDb();
668  return TRUE;
669  }
670  }
671 
672 
678  function insertQuestionblock($questionblock_id)
679  {
680  global $ilDB;
681  $result = $ilDB->queryF("SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle,".
682  " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst".
683  " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi".
684  " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi".
685  " AND svy_qblk.questionblock_id = %s".
686  " ORDER BY svy_svy_qst.sequence",
687  array('integer'),
688  array($questionblock_id)
689  );
690  $questions = array();
691  $show_questiontext = 0;
692  $show_blocktitle = 0;
693  while ($row = $ilDB->fetchAssoc($result))
694  {
695  $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
696  array_push($questions, $duplicate_id);
697  $title = $row["title"];
698  $show_questiontext = $row["show_questiontext"];
699  $show_blocktitle = $row["show_blocktitle"];
700  }
701  $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
702  }
703 
709  function getAllRTEContent()
710  {
711  $result = array();
712  array_push($result, $this->getIntroduction());
713  array_push($result, $this->getOutro());
714  return $result;
715  }
716 
723  {
724  include_once("./Services/RTE/classes/class.ilRTE.php");
725  $completecontent = "";
726  foreach ($this->getAllRTEContent() as $content)
727  {
728  $completecontent .= $content;
729  }
730  ilRTE::_cleanupMediaObjectUsage($completecontent, $this->getType() . ":html",
731  $this->getId());
732  }
733 
734  public function saveUserSettings($usr_id, $key, $title, $value)
735  {
736  global $ilDB;
737 
738  $next_id = $ilDB->nextId('svy_settings');
739  $affectedRows = $ilDB->insert("svy_settings", array(
740  "settings_id" => array("integer", $next_id),
741  "usr_id" => array("integer", $usr_id),
742  "keyword" => array("text", $key),
743  "title" => array("text", $title),
744  "value" => array("clob", $value)
745  ));
746  }
747 
748  public function deleteUserSettings($id)
749  {
750  global $ilDB;
751 
752  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_settings WHERE settings_id = %s",
753  array('integer'),
754  array($id)
755  );
756  return $affectedRows;
757  }
758 
759  public function getUserSettings($usr_id, $key)
760  {
761  global $ilDB;
762 
763  $result = $ilDB->queryF("SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
764  array('integer', 'text'),
765  array($usr_id, $key)
766  );
767  $found = array();
768  if ($result->numRows())
769  {
770  while ($row = $ilDB->fetchAssoc($result))
771  {
772  $found[$row['settings_id']] = $row;
773  }
774  }
775  return $found;
776  }
777 
783  function saveToDb()
784  {
785  global $ilDB;
786 
787  // date handling
788  $rmd_start = $this->getReminderStart();
789  if(is_object($rmd_start))
790  {
791  $rmd_start = $rmd_start->get(IL_CAL_DATE);
792  }
793  $rmd_end = $this->getReminderEnd();
794  if(is_object($rmd_end))
795  {
796  $rmd_end = $rmd_end->get(IL_CAL_DATE);
797  }
798 
799  include_once("./Services/RTE/classes/class.ilRTE.php");
800  if ($this->getSurveyId() < 1)
801  {
802  $next_id = $ilDB->nextId('svy_svy');
803  $affectedRows = $ilDB->insert("svy_svy", array(
804  "survey_id" => array("integer", $next_id),
805  "obj_fi" => array("integer", $this->getId()),
806  "author" => array("text", $this->getAuthor()),
807  "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
808  "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
809  "status" => array("text", $this->getStatus()),
810  "startdate" => array("text", $this->getStartDate()),
811  "enddate" => array("text", $this->getEndDate()),
812  "evaluation_access" => array("text", $this->getEvaluationAccess()),
813  "invitation" => array("text", $this->getInvitation()),
814  "invitation_mode" => array("text", $this->getInvitationMode()),
815  "complete" => array("text", $this->isComplete()),
816  "created" => array("integer", time()),
817  "anonymize" => array("text", $this->getAnonymize()),
818  "show_question_titles" => array("text", $this->getShowQuestionTitles()),
819  "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
820  "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : NULL),
821  "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : NULL),
822  "tstamp" => array("integer", time()),
823  "template_id" => array("integer", $this->getTemplate()),
824  "pool_usage" => array("integer", $this->getPoolUsage()),
825  // 360°
826  "mode_360" => array("integer", $this->get360Mode()),
827  "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
828  "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
829  "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
830  "mode_360_results" => array("integer", $this->get360Results()),
831  "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
832  // reminder/notification
833  "reminder_status" => array("integer", (int)$this->getReminderStatus()),
834  "reminder_start" => array("datetime", $rmd_start),
835  "reminder_end" => array("datetime", $rmd_end),
836  "reminder_frequency" => array("integer", (int)$this->getReminderFrequency()),
837  "reminder_target" => array("integer", (int)$this->getReminderTarget()),
838  "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
839  "tutor_ntf_status" => array("integer", (int)$this->getTutorNotificationStatus()),
840  "tutor_ntf_reci" => array("text", implode(";", (array)$this->getTutorNotificationRecipients())),
841  "tutor_ntf_target" => array("integer", (int)$this->getTutorNotificationTarget()),
842  "own_results_view" => array("integer", $this->hasViewOwnResults()),
843  "own_results_mail" => array("integer", $this->hasMailOwnResults())
844  ));
845  $this->setSurveyId($next_id);
846  }
847  else
848  {
849  $affectedRows = $ilDB->update("svy_svy", array(
850  "author" => array("text", $this->getAuthor()),
851  "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
852  "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
853  "status" => array("text", $this->getStatus()),
854  "startdate" => array("text", $this->getStartDate()),
855  "enddate" => array("text", $this->getEndDate()),
856  "evaluation_access" => array("text", $this->getEvaluationAccess()),
857  "invitation" => array("text", $this->getInvitation()),
858  "invitation_mode" => array("text", $this->getInvitationMode()),
859  "complete" => array("text", $this->isComplete()),
860  "anonymize" => array("text", $this->getAnonymize()),
861  "show_question_titles" => array("text", $this->getShowQuestionTitles()),
862  "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
863  "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : NULL),
864  "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : NULL),
865  "tstamp" => array("integer", time()),
866  "template_id" => array("integer", $this->getTemplate()),
867  "pool_usage" => array("integer", $this->getPoolUsage()),
868  // 360°
869  "mode_360" => array("integer", $this->get360Mode()),
870  "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
871  "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
872  "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
873  "mode_360_results" => array("integer", $this->get360Results()),
874  "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
875  // reminder/notification
876  "reminder_status" => array("integer", $this->getReminderStatus()),
877  "reminder_start" => array("datetime", $rmd_start),
878  "reminder_end" => array("datetime", $rmd_end),
879  "reminder_frequency" => array("integer", $this->getReminderFrequency()),
880  "reminder_target" => array("integer", $this->getReminderTarget()),
881  "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
882  "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
883  "tutor_ntf_reci" => array("text", implode(";", (array)$this->getTutorNotificationRecipients())),
884  "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget()),
885  "own_results_view" => array("integer", $this->hasViewOwnResults()),
886  "own_results_mail" => array("integer", $this->hasMailOwnResults())
887  ), array(
888  "survey_id" => array("integer", $this->getSurveyId())
889  ));
890  }
891  if ($affectedRows)
892  {
893  // save questions to db
894  $this->saveQuestionsToDb();
895  }
896 
897  // moved activation to ilObjectActivation
898  if($this->ref_id)
899  {
900  include_once "./Services/Object/classes/class.ilObjectActivation.php";
901  ilObjectActivation::getItem($this->ref_id);
902 
903  $item = new ilObjectActivation;
904  if(!$this->isActivationLimited())
905  {
907  }
908  else
909  {
910  $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
911  $item->setTimingStart($this->getActivationStartDate());
912  $item->setTimingEnd($this->getActivationEndDate());
913  $item->toggleVisible($this->getActivationVisibility());
914  }
915 
916  $item->update($this->ref_id);
917  }
918  }
919 
926  function saveQuestionsToDb()
927  {
928  global $ilDB;
929  // save old questions state
930  $old_questions = array();
931  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
932  array('integer'),
933  array($this->getSurveyId())
934  );
935  if ($result->numRows())
936  {
937  while ($row = $ilDB->fetchAssoc($result))
938  {
939  $old_questions[$row["question_fi"]] = $row;
940  }
941  }
942 
943  // delete existing question relations
944  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_svy_qst WHERE survey_fi = %s",
945  array('integer'),
946  array($this->getSurveyId())
947  );
948  // create new question relations
949  foreach ($this->questions as $key => $value)
950  {
951  $next_id = $ilDB->nextId('svy_svy_qst');
952  $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)",
953  array('integer','integer','integer','text','integer','integer'),
954  array($next_id, $this->getSurveyId(), $value, (strlen($old_questions[$value]["heading"])) ? $old_questions[$value]["heading"] : NULL, $key, time())
955  );
956  }
957  }
958 
966  function getAnonymousId($id)
967  {
968  global $ilDB;
969  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
970  array('text'),
971  array($id)
972  );
973  if ($result->numRows())
974  {
975  $row = $ilDB->fetchAssoc($result);
976  return $row["anonymous_id"];
977  }
978  else
979  {
980  return "";
981  }
982  }
983 
990  function getQuestionGUI($questiontype, $question_id)
991  {
992  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestionGUI.php";
993  return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
994  }
995 
1003  function getQuestionType($question_id)
1004  {
1005  global $ilDB;
1006  if ($question_id < 1) return -1;
1007  $result = $ilDB->queryF("SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
1008  "svy_question.questiontype_fi = svy_qtype.questiontype_id",
1009  array('integer'),
1010  array($question_id)
1011  );
1012  if ($result->numRows() == 1)
1013  {
1014  $data = $ilDB->fetchAssoc($result);
1015  return $data["type_tag"];
1016  }
1017  else
1018  {
1019  return "";
1020  }
1021  }
1022 
1029  function getSurveyId()
1030  {
1031  return $this->survey_id;
1032  }
1033 
1037  function setAnonymize($a_anonymize)
1038  {
1039  switch ($a_anonymize)
1040  {
1041  case self::ANONYMIZE_OFF:
1042  case self::ANONYMIZE_ON:
1043  case self::ANONYMIZE_FREEACCESS:
1044  case self::ANONYMIZE_CODE_ALL:
1045  $this->anonymize = $a_anonymize;
1046  break;
1047  default:
1048  $this->anonymize = self::ANONYMIZE_OFF;
1049  break;
1050  }
1051  }
1052 
1058  function getAnonymize()
1059  {
1060  return ($this->anonymize) ? $this->anonymize : 0;
1061  }
1062 
1069  {
1070  return ($this->getAnonymize() == self::ANONYMIZE_OFF ||
1071  $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1072  }
1073 
1080  {
1081  return ($this->getAnonymize() == self::ANONYMIZE_ON ||
1082  $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1083  }
1084 
1090  function loadFromDb()
1091  {
1092  global $ilDB;
1093  $result = $ilDB->queryF("SELECT * FROM svy_svy WHERE obj_fi = %s",
1094  array('integer'),
1095  array($this->getId())
1096  );
1097  if ($result->numRows() == 1)
1098  {
1099  $data = $ilDB->fetchAssoc($result);
1100  $this->setSurveyId($data["survey_id"]);
1101  $this->setAuthor($data["author"]);
1102  include_once("./Services/RTE/classes/class.ilRTE.php");
1103  $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1104  if (strcmp($data["outro"], "survey_finished") == 0)
1105  {
1106  $this->setOutro($this->lng->txt("survey_finished"));
1107  }
1108  else
1109  {
1110  $this->setOutro(ilRTE::_replaceMediaObjectImageSrc($data["outro"], 1));
1111  }
1112  $this->setInvitation($data["invitation"]);
1113  $this->setInvitationMode($data["invitation_mode"]);
1114  $this->setShowQuestionTitles($data["show_question_titles"]);
1115  $this->setStartDate($data["startdate"]);
1116  $this->setEndDate($data["enddate"]);
1117  $this->setAnonymize($data["anonymize"]);
1118  $this->setEvaluationAccess($data["evaluation_access"]);
1119  $this->loadQuestionsFromDb();
1120  $this->setStatus($data["status"]);
1121  $this->setMailNotification($data['mailnotification']);
1122  $this->setMailAddresses($data['mailaddresses']);
1123  $this->setMailParticipantData($data['mailparticipantdata']);
1124  $this->setTemplate($data['template_id']);
1125  $this->setPoolUsage($data['pool_usage']);
1126  // 360°
1127  $this->set360Mode($data['mode_360']);
1128  $this->set360SelfEvaluation($data['mode_360_self_eval']);
1129  $this->set360SelfRaters($data['mode_360_self_rate']);
1130  $this->set360SelfAppraisee($data['mode_360_self_appr']);
1131  $this->set360Results($data['mode_360_results']);
1132  $this->set360SkillService($data['mode_360_skill_service']);
1133  // reminder/notification
1134  $this->setReminderStatus($data["reminder_status"]);
1135  $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1136  $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1137  $this->setReminderFrequency($data["reminder_frequency"]);
1138  $this->setReminderTarget($data["reminder_target"]);
1139  $this->setReminderLastSent($data["reminder_last_sent"]);
1140  $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1141  $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1142  $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1143 
1144  $this->setViewOwnResults($data["own_results_view"]);
1145  $this->setMailOwnResults($data["own_results_mail"]);
1146  }
1147 
1148  // moved activation to ilObjectActivation
1149  if($this->ref_id)
1150  {
1151  include_once "./Services/Object/classes/class.ilObjectActivation.php";
1152  $activation = ilObjectActivation::getItem($this->ref_id);
1153  switch($activation["timing_type"])
1154  {
1156  $this->setActivationLimited(true);
1157  $this->setActivationStartDate($activation["timing_start"]);
1158  $this->setActivationEndDate($activation["timing_end"]);
1159  $this->setActivationVisibility($activation["visible"]);
1160  break;
1161 
1162  default:
1163  $this->setActivationLimited(false);
1164  break;
1165  }
1166  }
1167  }
1168 
1176  {
1177  global $ilDB;
1178  $this->questions = array();
1179  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1180  array('integer'),
1181  array($this->getSurveyId())
1182  );
1183  while ($data = $ilDB->fetchAssoc($result))
1184  {
1185  $this->questions[$data["sequence"]] = $data["question_fi"];
1186  }
1187  }
1188 
1196  function setAuthor($author = "")
1197  {
1198  $this->author = $author;
1199  }
1200 
1210  function saveAuthorToMetadata($a_author = "")
1211  {
1212  $md =& new ilMD($this->getId(), 0, $this->getType());
1213  $md_life =& $md->getLifecycle();
1214  if (!$md_life)
1215  {
1216  if (strlen($a_author) == 0)
1217  {
1218  global $ilUser;
1219  $a_author = $ilUser->getFullname();
1220  }
1221 
1222  $md_life =& $md->addLifecycle();
1223  $md_life->save();
1224  $con =& $md_life->addContribute();
1225  $con->setRole("Author");
1226  $con->save();
1227  $ent =& $con->addEntity();
1228  $ent->setEntity($a_author);
1229  $ent->save();
1230  }
1231  }
1232 
1240  function getAuthor()
1241  {
1242  $author = array();
1243  include_once "./Services/MetaData/classes/class.ilMD.php";
1244  $md =& new ilMD($this->getId(), 0, $this->getType());
1245  $md_life =& $md->getLifecycle();
1246  if ($md_life)
1247  {
1248  $ids =& $md_life->getContributeIds();
1249  foreach ($ids as $id)
1250  {
1251  $md_cont =& $md_life->getContribute($id);
1252  if (strcmp($md_cont->getRole(), "Author") == 0)
1253  {
1254  $entids =& $md_cont->getEntityIds();
1255  foreach ($entids as $entid)
1256  {
1257  $md_ent =& $md_cont->getEntity($entid);
1258  array_push($author, $md_ent->getEntity());
1259  }
1260  }
1261  }
1262  }
1263  return join($author, ",");
1264  }
1265 
1272  public function getShowQuestionTitles()
1273  {
1274  return ($this->display_question_titles) ? 1 : 0;
1275  }
1276 
1283  public function setShowQuestionTitles($a_show)
1284  {
1285  $this->display_question_titles = ($a_show) ? 1 : 0;
1286  }
1287 
1295  {
1296  $this->display_question_titles = 1;
1297  }
1298 
1306  {
1307  $this->display_question_titles = 0;
1308  }
1309 
1318  {
1319  global $ilDB, $ilAccess;
1320 
1321  $this->invitation = $invitation;
1323  {
1324  $this->disinviteAllUsers();
1325  }
1326  else if ($invitation == self::INVITATION_ON)
1327  {
1328  if ($this->getInvitationMode() == self::MODE_UNLIMITED)
1329  {
1330  $result = $ilDB->query("SELECT usr_id FROM usr_data");
1331  while ($row = $ilDB->fetchAssoc($result))
1332  {
1333  if ($ilAccess->checkAccessOfUser($row["usr_id"], "read", "", $this->getRefId(), "svy", $this->getId()))
1334  {
1335  $this->inviteUser($row['usr_id']);
1336  }
1337  }
1338  }
1339  }
1340  }
1341 
1350  {
1351  $this->invitation_mode = $invitation_mode;
1352  }
1353 
1363  {
1364  $this->invitation_mode = $invitation_mode;
1365  $this->setInvitation($invitation);
1366  }
1367 
1374  public function setIntroduction($introduction = "")
1375  {
1376  $this->introduction = $introduction;
1377  }
1378 
1385  public function setOutro($outro = "")
1386  {
1387  $this->outro = $outro;
1388  }
1389 
1397  function getInvitation()
1398  {
1399  return ($this->invitation) ? $this->invitation : self::INVITATION_OFF;
1400  }
1401 
1409  function getInvitationMode()
1410  {
1411  include_once "./Services/Administration/classes/class.ilSetting.php";
1412  $surveySetting = new ilSetting("survey");
1413  $unlimited_invitation = $surveySetting->get("unlimited_invitation");
1414  if (!$unlimited_invitation && $this->invitation_mode == self::MODE_UNLIMITED)
1415  {
1417  }
1418  else
1419  {
1420  return ($this->invitation_mode) ? $this->invitation_mode : self::MODE_UNLIMITED;
1421  }
1422  }
1423 
1431  function getStatus()
1432  {
1433  return ($this->status) ? $this->status : self::STATUS_OFFLINE;
1434  }
1435 
1443  function isOnline()
1444  {
1445  return ($this->status == self::STATUS_ONLINE) ? true : false;
1446  }
1447 
1455  function isOffline()
1456  {
1457  return ($this->status == self::STATUS_OFFLINE) ? true : false;
1458  }
1459 
1468  function setStatus($status = self::STATUS_OFFLINE)
1469  {
1470  $result = "";
1471  if (($status == self::STATUS_ONLINE) && (count($this->questions) == 0))
1472  {
1473  $this->status = self::STATUS_OFFLINE;
1474  $result = $this->lng->txt("cannot_switch_to_online_no_questions");
1475  }
1476  else
1477  {
1478  $this->status = $status;
1479  }
1480  return $result;
1481  }
1482 
1490  function getStartDate()
1491  {
1492  return (strlen($this->start_date)) ? $this->start_date : NULL;
1493  }
1494 
1501  function canStartSurvey($anonymous_id = NULL, $a_no_rbac = false)
1502  {
1503  global $ilAccess;
1504 
1505  $result = TRUE;
1506  $messages = array();
1507  $edit_settings = false;
1508  // check start date
1509  if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches))
1510  {
1511  $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1512  $now = mktime();
1513  if ($now < $epoch_time)
1514  {
1515  array_push($messages,$this->lng->txt('start_date_not_reached').' ('.
1517  $result = FALSE;
1518  $edit_settings = true;
1519  }
1520  }
1521  // check end date
1522  if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches))
1523  {
1524  $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1525  $now = mktime();
1526  if ($now > $epoch_time)
1527  {
1528  array_push($messages,$this->lng->txt('end_date_reached').' ('.
1530  $result = FALSE;
1531  $edit_settings = true;
1532  }
1533  }
1534 
1535  // check online status
1536  if ($this->getStatus() == self::STATUS_OFFLINE)
1537  {
1538  array_push($messages, $this->lng->txt("survey_is_offline"));
1539  $result = FALSE;
1540  $edit_settings = true;
1541  }
1542  // check rbac permissions
1543  if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id))
1544  {
1545  array_push($messages, $this->lng->txt("cannot_participate_survey"));
1546  $result = FALSE;
1547  }
1548  /*
1549  // 2. check previous access
1550  if (!$result["error"])
1551  {
1552  global $ilUser;
1553  $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1554  if ($survey_started === 1)
1555  {
1556  array_push($messages, $this->lng->txt("already_completed_survey"));
1557  $result = FALSE;
1558  }
1559  }
1560  */
1561  return array(
1562  "result" => $result,
1563  "messages" => $messages,
1564  "edit_settings" => $edit_settings
1565  );
1566  }
1567 
1575  function setStartDate($start_date = "")
1576  {
1577  $this->start_date = $start_date;
1578  }
1579 
1588  function setStartDateAndTime($start_date = "", $start_time)
1589  {
1590  $y = ''; $m = ''; $d = ''; $h = ''; $i = ''; $s = '';
1591  if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches))
1592  {
1593  $y = $matches[1];
1594  $m = $matches[2];
1595  $d = $matches[3];
1596  }
1597  if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches))
1598  {
1599  $h = $matches[1];
1600  $i = $matches[2];
1601  $s = $matches[3];
1602  }
1603  $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1604  }
1605 
1613  function getEndDate()
1614  {
1615  return (strlen($this->end_date)) ? $this->end_date : NULL;
1616  }
1617 
1625  function setEndDate($end_date = "")
1626  {
1627  $this->end_date = $end_date;
1628  }
1629 
1638  function setEndDateAndTime($end_date = "", $end_time)
1639  {
1640  $y = ''; $m = ''; $d = ''; $h = ''; $i = ''; $s = '';
1641  if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches))
1642  {
1643  $y = $matches[1];
1644  $m = $matches[2];
1645  $d = $matches[3];
1646  }
1647  if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches))
1648  {
1649  $h = $matches[1];
1650  $i = $matches[2];
1651  $s = $matches[3];
1652  }
1653  $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1654  }
1655 
1664  {
1665  return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1666  }
1667 
1675  function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1676  {
1677  $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1678  }
1679 
1680  function setActivationVisibility($a_value)
1681  {
1682  $this->activation_visibility = (bool) $a_value;
1683  }
1684 
1686  {
1688  }
1689 
1691  {
1692  return (bool)$this->activation_limited;
1693  }
1694 
1695  function setActivationLimited($a_value)
1696  {
1697  $this->activation_limited = (bool)$a_value;
1698  }
1699 
1707  function getIntroduction()
1708  {
1709  return (strlen($this->introduction)) ? $this->introduction : NULL;
1710  }
1711 
1719  function getOutro()
1720  {
1721  return (strlen($this->outro)) ? $this->outro : NULL;
1722  }
1723 
1731  {
1732  global $ilDB;
1733  $existing_questions = array();
1734  $result = $ilDB->queryF("SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1735  "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1736  array('integer'),
1737  array($this->getSurveyId())
1738  );
1739  while ($data = $ilDB->fetchAssoc($result))
1740  {
1741  if($data["original_id"])
1742  {
1743  array_push($existing_questions, $data["original_id"]);
1744  }
1745  }
1746  return $existing_questions;
1747  }
1748 
1755  function &getQuestionpoolTitles($could_be_offline = FALSE, $showPath = FALSE)
1756  {
1757  include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
1758  return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = TRUE, $could_be_offline, $showPath);
1759  }
1760 
1767  function moveUpQuestion($question_id)
1768  {
1769  $move_questions = array($question_id);
1770  $pages =& $this->getSurveyPages();
1771  $pageindex = -1;
1772  foreach ($pages as $idx => $page)
1773  {
1774  if ($page[0]["question_id"] == $question_id)
1775  {
1776  $pageindex = $idx;
1777  }
1778  }
1779  if ($pageindex > 0)
1780  {
1781  $this->moveQuestions($move_questions, $pages[$pageindex-1][0]["question_id"], 0);
1782  }
1783  else
1784  {
1785  // move up a question in a questionblock
1786  $questions = $this->getSurveyQuestions();
1787  $questions = array_keys($questions);
1788  $index = array_search($question_id, $questions);
1789  if (($index !== FALSE) && ($index > 0))
1790  {
1791  $this->moveQuestions($move_questions, $questions[$index-1], 0);
1792  }
1793  }
1794  }
1795 
1801  public function moveDownQuestion($question_id)
1802  {
1803  $move_questions = array($question_id);
1804  $pages =& $this->getSurveyPages();
1805  $pageindex = -1;
1806  foreach ($pages as $idx => $page)
1807  {
1808  if (($page[0]["question_id"] == $question_id) && (strcmp($page[0]["questionblock_id"], "") == 0))
1809  {
1810  $pageindex = $idx;
1811  }
1812  }
1813  if (($pageindex < count($pages)-1) && ($pageindex >= 0))
1814  {
1815  $this->moveQuestions($move_questions, $pages[$pageindex+1][count($pages[$pageindex+1])-1]["question_id"], 1);
1816  }
1817  else
1818  {
1819  // move down a question in a questionblock
1820  $questions = $this->getSurveyQuestions();
1821  $questions = array_keys($questions);
1822  $index = array_search($question_id, $questions);
1823  if (($index !== FALSE) && ($index < count($questions)-1))
1824  {
1825  $this->moveQuestions($move_questions, $questions[$index+1], 1);
1826  }
1827  }
1828  }
1829 
1836  function moveUpQuestionblock($questionblock_id)
1837  {
1838  $pages =& $this->getSurveyPages();
1839  $move_questions = array();
1840  $pageindex = -1;
1841  foreach ($pages as $idx => $page)
1842  {
1843  if ($page[0]["questionblock_id"] == $questionblock_id)
1844  {
1845  foreach ($page as $pageidx => $question)
1846  {
1847  array_push($move_questions, $question["question_id"]);
1848  }
1849  $pageindex = $idx;
1850  }
1851  }
1852  if ($pageindex > 0)
1853  {
1854  $this->moveQuestions($move_questions, $pages[$pageindex-1][0]["question_id"], 0);
1855  }
1856  }
1857 
1864  function moveDownQuestionblock($questionblock_id)
1865  {
1866  $pages =& $this->getSurveyPages();
1867  $move_questions = array();
1868  $pageindex = -1;
1869  foreach ($pages as $idx => $page)
1870  {
1871  if ($page[0]["questionblock_id"] == $questionblock_id)
1872  {
1873  foreach ($page as $pageidx => $question)
1874  {
1875  array_push($move_questions, $question["question_id"]);
1876  }
1877  $pageindex = $idx;
1878  }
1879  }
1880  if ($pageindex < count($pages)-1)
1881  {
1882  $this->moveQuestions($move_questions, $pages[$pageindex+1][count($pages[$pageindex+1])-1]["question_id"], 1);
1883  }
1884  }
1885 
1894  function moveQuestions($move_questions, $target_index, $insert_mode)
1895  {
1896  $array_pos = array_search($target_index, $this->questions);
1897  if ($insert_mode == 0)
1898  {
1899  $part1 = array_slice($this->questions, 0, $array_pos);
1900  $part2 = array_slice($this->questions, $array_pos);
1901  }
1902  else if ($insert_mode == 1)
1903  {
1904  $part1 = array_slice($this->questions, 0, $array_pos + 1);
1905  $part2 = array_slice($this->questions, $array_pos + 1);
1906  }
1907  foreach ($move_questions as $question_id)
1908  {
1909  if (!(array_search($question_id, $part1) === FALSE))
1910  {
1911  unset($part1[array_search($question_id, $part1)]);
1912  }
1913  if (!(array_search($question_id, $part2) === FALSE))
1914  {
1915  unset($part2[array_search($question_id, $part2)]);
1916  }
1917  }
1918  $part1 = array_values($part1);
1919  $part2 = array_values($part2);
1920  $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1921  foreach ($move_questions as $question_id)
1922  {
1923  $constraints = $this->getConstraints($question_id);
1924  foreach ($constraints as $idx => $constraint)
1925  {
1926  foreach ($part2 as $next_question_id)
1927  {
1928  if ($constraint["question"] == $next_question_id)
1929  {
1930  // constraint concerning a question that follows -> delete constraint
1931  $this->deleteConstraint($constraint["id"]);
1932  }
1933  }
1934  }
1935  }
1936  $this->saveQuestionsToDb();
1937  }
1938 
1945  function removeQuestion($question_id)
1946  {
1947  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
1948  $question =& $this->_instanciateQuestion($question_id);
1949  $question->delete($question_id);
1950  $this->removeConstraintsConcerningQuestion($question_id);
1951  }
1952 
1960  {
1961  global $ilDB;
1962  $result = $ilDB->queryF("SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1963  array('integer','integer'),
1964  array($question_id, $this->getSurveyId())
1965  );
1966  if ($result->numRows() > 0)
1967  {
1968  $remove_constraints = array();
1969  while ($row = $ilDB->fetchAssoc($result))
1970  {
1971  array_push($remove_constraints, $row["constraint_fi"]);
1972  }
1973  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1974  array('integer','integer'),
1975  array($question_id, $this->getSurveyId())
1976  );
1977  foreach ($remove_constraints as $key => $constraint_id)
1978  {
1979  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_constraint WHERE constraint_id = %s",
1980  array('integer'),
1981  array($constraint_id)
1982  );
1983  }
1984  }
1985  }
1986 
1994  function removeQuestions($remove_questions, $remove_questionblocks)
1995  {
1996  global $ilDB;
1997 
1998  $block_sizes = array();
1999  foreach ($this->getSurveyQuestions() as $question_id => $data)
2000  {
2001  if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks))
2002  {
2003  unset($this->questions[array_search($question_id, $this->questions)]);
2004  $this->removeQuestion($question_id);
2005  }
2006  else if($data["questionblock_id"])
2007  {
2008  $block_sizes[$data["questionblock_id"]]++;
2009  }
2010  }
2011 
2012  // blocks with just 1 question need to be deleted
2013  foreach($block_sizes as $block_id => $size)
2014  {
2015  if($size < 2)
2016  {
2017  $remove_questionblocks[] = $block_id;
2018  }
2019  }
2020 
2021  foreach (array_unique($remove_questionblocks) as $questionblock_id)
2022  {
2023  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk WHERE questionblock_id = %s",
2024  array('integer'),
2025  array($questionblock_id)
2026  );
2027  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
2028  array('integer','integer'),
2029  array($questionblock_id, $this->getSurveyId())
2030  );
2031  }
2032 
2033  $this->questions = array_values($this->questions);
2034  $this->saveQuestionsToDb();
2035  }
2036 
2043  function unfoldQuestionblocks($questionblocks)
2044  {
2045  global $ilDB;
2046  foreach ($questionblocks as $index)
2047  {
2048  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk WHERE questionblock_id = %s",
2049  array('integer'),
2050  array($index)
2051  );
2052  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
2053  array('integer','integer'),
2054  array($index, $this->getSurveyId())
2055  );
2056  }
2057  }
2058 
2059  function removeQuestionFromBlock($question_id, $questionblock_id)
2060  {
2061  global $ilDB;
2062 
2063  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
2064  array('integer','integer','integer'),
2065  array($questionblock_id, $this->getSurveyId(), $question_id)
2066  );
2067  }
2068 
2069  function addQuestionToBlock($question_id, $questionblock_id)
2070  {
2071  global $ilDB;
2072 
2073 
2074  $next_id = $ilDB->nextId('svy_qblk_qst');
2075  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2076  "question_fi) VALUES (%s, %s, %s, %s)",
2077  array('integer','integer','integer','integer'),
2078  array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
2079  );
2080 
2081  $this->deleteConstraints($question_id); // #13713
2082  }
2083 
2090  function &getQuestionblockQuestions($questionblock_id)
2091  {
2092  global $ilDB;
2093  $titles = array();
2094  $result = $ilDB->queryF("SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM ".
2095  "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
2096  "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
2097  array('integer'),
2098  array($questionblock_id)
2099  );
2100  $survey_id = "";
2101  while ($row = $ilDB->fetchAssoc($result))
2102  {
2103  $titles[$row["question_fi"]] = $row["title"];
2104  $survey_id = $row["survey_fi"];
2105  }
2106  $result = $ilDB->queryF("SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
2107  array('integer'),
2108  array($survey_id)
2109  );
2110  $resultarray = array();
2111  $counter = 1;
2112  while ($row = $ilDB->fetchAssoc($result))
2113  {
2114  if (array_key_exists($row["question_fi"], $titles))
2115  {
2116  $resultarray[$counter++] = $titles[$row["question_fi"]];
2117  }
2118  }
2119  return $resultarray;
2120  }
2121 
2128  function &getQuestionblockQuestionIds($questionblock_id)
2129  {
2130  global $ilDB;
2131  $result = $ilDB->queryF("SELECT question_fi FROM svy_qblk_qst WHERE questionblock_fi = %s",
2132  array("integer"),
2133  array($questionblock_id)
2134  );
2135  $ids = array();
2136  if ($result->numRows())
2137  {
2138  while ($data = $ilDB->fetchAssoc($result))
2139  {
2140  array_push($ids, $data['question_fi']);
2141  }
2142  }
2143  return $ids;
2144  }
2145 
2153  function getQuestionblock($questionblock_id)
2154  {
2155  global $ilDB;
2156  $result = $ilDB->queryF("SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2157  array('integer'),
2158  array($questionblock_id)
2159  );
2160  return $ilDB->fetchAssoc($result);
2161  }
2162 
2170  function _getQuestionblock($questionblock_id)
2171  {
2172  global $ilDB;
2173  $result = $ilDB->queryF("SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2174  array('integer'),
2175  array($questionblock_id)
2176  );
2177  $row = $ilDB->fetchAssoc($result);
2178  return $row;
2179  }
2180 
2189  function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false)
2190  {
2191  global $ilDB;
2192  $next_id = $ilDB->nextId('svy_qblk');
2193  $ilDB->manipulateF("INSERT INTO svy_qblk (questionblock_id, title, show_questiontext,".
2194  " show_blocktitle, owner_fi, tstamp) " .
2195  "VALUES (%s, %s, %s, %s, %s, %s)",
2196  array('integer','text','integer','integer','integer','integer'),
2197  array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time())
2198  );
2199  return $next_id;
2200  }
2201 
2209  function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
2210  {
2211  global $ilDB;
2212 
2213  // if the selected questions are not in a continous selection, move all questions of the
2214  // questionblock at the position of the first selected question
2215  $this->moveQuestions($questions, $questions[0], 0);
2216 
2217  // now save the question block
2218  global $ilUser;
2219  $next_id = $ilDB->nextId('svy_qblk');
2220  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk (questionblock_id, title, show_questiontext,".
2221  " show_blocktitle, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
2222  array('integer','text','text','text','integer','integer'),
2223  array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time())
2224  );
2225  if ($affectedRows)
2226  {
2227  $questionblock_id = $next_id;
2228  foreach ($questions as $index)
2229  {
2230  $next_id = $ilDB->nextId('svy_qblk_qst');
2231  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2232  "question_fi) VALUES (%s, %s, %s, %s)",
2233  array('integer','integer','integer','integer'),
2234  array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2235  );
2236  $this->deleteConstraints($index);
2237  }
2238  }
2239  }
2240 
2248  function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
2249  {
2250  global $ilDB;
2251  $affectedRows = $ilDB->manipulateF("UPDATE svy_qblk SET title = %s, show_questiontext = %s,".
2252  " show_blocktitle = %s WHERE questionblock_id = %s",
2253  array('text','text','text','integer'),
2254  array($title, $show_questiontext, $show_blocktitle, $questionblock_id)
2255  );
2256  }
2257 
2264  function deleteConstraints($question_id)
2265  {
2266  global $ilDB;
2267  $result = $ilDB->queryF("SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2268  array('integer','integer'),
2269  array($question_id, $this->getSurveyId())
2270  );
2271  $constraints = array();
2272  while ($row = $ilDB->fetchAssoc($result))
2273  {
2274  array_push($constraints, $row["constraint_fi"]);
2275  }
2276  foreach ($constraints as $constraint_id)
2277  {
2278  $this->deleteConstraint($constraint_id);
2279  }
2280  }
2281 
2289  function deleteConstraint($constraint_id)
2290  {
2291  global $ilDB;
2292  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_constraint WHERE constraint_id = %s",
2293  array('integer'),
2294  array($constraint_id)
2295  );
2296  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2297  array('integer'),
2298  array($constraint_id)
2299  );
2300  }
2301 
2307  public function &getSurveyQuestions($with_answers = false)
2308  {
2309  global $ilDB;
2310  $obligatory_states =& $this->getObligatoryStates();
2311  // get questionblocks
2312  $all_questions = array();
2313  $result = $ilDB->queryF("SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, ".
2314  "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2315  "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2316  "ORDER BY svy_svy_qst.sequence",
2317  array('integer'),
2318  array($this->getSurveyId())
2319  );
2320  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2321  while ($row = $ilDB->fetchAssoc($result))
2322  {
2323  $add = true;
2324  if ($row["plugin"])
2325  {
2326  if (!$this->isPluginActive($row["type_tag"]))
2327  {
2328  $add = false;
2329  }
2330  }
2331  if ($add)
2332  {
2333  $question =& $this->_instanciateQuestion($row["question_id"]);
2334  $questionrow = $question->_getQuestionDataArray($row["question_id"]);
2335  foreach ($row as $key => $value)
2336  {
2337  $questionrow[$key] = $value;
2338  }
2339  $all_questions[$row["question_id"]] = $questionrow;
2340  $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2341  $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2342  if (array_key_exists($row["question_id"], $obligatory_states))
2343  {
2344  $all_questions[$row["question_id"]]["obligatory"] = $obligatory_states[$row["question_id"]];
2345  }
2346  }
2347  }
2348  // get all questionblocks
2349  $questionblocks = array();
2350  if (count($all_questions))
2351  {
2352  $result = $ilDB->queryF("SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2353  "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2354  "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2355  array('integer'),
2356  array($this->getSurveyId())
2357  );
2358  while ($row = $ilDB->fetchAssoc($result))
2359  {
2360  $questionblocks[$row['question_fi']] = $row;
2361  }
2362  }
2363 
2364  foreach ($all_questions as $question_id => $row)
2365  {
2366  $constraints = $this->getConstraints($question_id);
2367  if (isset($questionblocks[$question_id]))
2368  {
2369  $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2370  $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2371  $all_questions[$question_id]["constraints"] = $constraints;
2372  }
2373  else
2374  {
2375  $all_questions[$question_id]["questionblock_title"] = "";
2376  $all_questions[$question_id]["questionblock_id"] = "";
2377  $all_questions[$question_id]["constraints"] = $constraints;
2378  }
2379  if ($with_answers)
2380  {
2381  $answers = array();
2382  $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2383  "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id ".
2384  "ORDER BY sequence ASC",
2385  array('integer'),
2386  array($question_id)
2387  );
2388  if ($result->numRows() > 0)
2389  {
2390  while ($data = $ilDB->fetchAssoc($result))
2391  {
2392  array_push($answers, $data["title"]);
2393  }
2394  }
2395  $all_questions[$question_id]["answers"] = $answers;
2396  }
2397  }
2398  return $all_questions;
2399  }
2400 
2407  function setObligatoryStates($obligatory_questions)
2408  {
2409  global $ilDB;
2410  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2411  array('integer'),
2412  array($this->getSurveyId())
2413  );
2414  if ($result->numRows())
2415  {
2416  while ($row = $ilDB->fetchAssoc($result))
2417  {
2418  if (!array_key_exists($row["question_fi"], $obligatory_questions))
2419  {
2420  $obligatory_questions[$row["question_fi"]] = 0;
2421  }
2422  }
2423  }
2424 
2425  // set the obligatory states in the database
2426  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_oblig WHERE survey_fi = %s",
2427  array('integer'),
2428  array($this->getSurveyId())
2429  );
2430 
2431  // set the obligatory states in the database
2432  foreach ($obligatory_questions as $question_fi => $obligatory)
2433  {
2434  $next_id = $ilDB->nextId('svy_qst_oblig');
2435  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_oblig (question_obligatory_id, survey_fi, question_fi, " .
2436  "obligatory, tstamp) VALUES (%s, %s, %s, %s, %s)",
2437  array('integer','integer','integer','text','integer'),
2438  array($next_id, $this->getSurveyId(), $question_fi, (strlen($obligatory)) ? $obligatory : 0, time())
2439  );
2440 
2441  // #12420
2442  $ilDB->manipulate("UPDATE svy_question".
2443  " SET obligatory = ".$ilDB->quote($obligatory, "integer").
2444  " WHERE question_id = ".$ilDB->quote($question_fi, "integer"));
2445  }
2446  }
2447 
2455  {
2456  global $ilDB;
2457  $obligatory_states = array();
2458  $result = $ilDB->queryF("SELECT * FROM svy_qst_oblig WHERE survey_fi = %s",
2459  array('integer'),
2460  array($this->getSurveyId())
2461  );
2462  if ($result->numRows())
2463  {
2464  while ($row = $ilDB->fetchAssoc($result))
2465  {
2466  $obligatory_states[$row["question_fi"]] = $row["obligatory"];
2467  }
2468  }
2469  return $obligatory_states;
2470  }
2471 
2477  function &getSurveyPages()
2478  {
2479  global $ilDB;
2480  $obligatory_states =& $this->getObligatoryStates();
2481  // get questionblocks
2482  $all_questions = array();
2483  $result = $ilDB->queryF("SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2484  "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2485  "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id ".
2486  "ORDER BY svy_svy_qst.sequence",
2487  array('integer'),
2488  array($this->getSurveyId())
2489  );
2490  while ($row = $ilDB->fetchAssoc($result))
2491  {
2492  $all_questions[$row["question_id"]] = $row;
2493  }
2494  // get all questionblocks
2495  $questionblocks = array();
2496  if (count($all_questions))
2497  {
2498  $result = $ilDB->queryF("SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst ".
2499  "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s ".
2500  "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2501  array('integer'),
2502  array($this->getSurveyId())
2503  );
2504  while ($row = $ilDB->fetchAssoc($result))
2505  {
2506  $questionblocks[$row['question_fi']] = $row;
2507  }
2508  }
2509 
2510  $all_pages = array();
2511  $pageindex = -1;
2512  $currentblock = "";
2513  foreach ($all_questions as $question_id => $row)
2514  {
2515  if (array_key_exists($question_id, $obligatory_states))
2516  {
2517  $all_questions[$question_id]["obligatory"] = $obligatory_states[$question_id];
2518  }
2519  $constraints = array();
2520  if (isset($questionblocks[$question_id]))
2521  {
2522  if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id']))
2523  {
2524  $pageindex++;
2525  }
2526  $all_questions[$question_id]['page'] = $pageindex;
2527  $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2528  $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2529  $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2530  $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2531  $currentblock = $questionblocks[$question_id]['questionblock_id'];
2532  $constraints = $this->getConstraints($question_id);
2533  $all_questions[$question_id]["constraints"] = $constraints;
2534  }
2535  else
2536  {
2537  $pageindex++;
2538  $all_questions[$question_id]['page'] = $pageindex;
2539  $all_questions[$question_id]["questionblock_title"] = "";
2540  $all_questions[$question_id]["questionblock_id"] = "";
2541  $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2542  $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2543  $currentblock = "";
2544  $constraints = $this->getConstraints($question_id);
2545  $all_questions[$question_id]["constraints"] = $constraints;
2546  }
2547  if (!isset($all_pages[$pageindex]))
2548  {
2549  $all_pages[$pageindex] = array();
2550  }
2551  array_push($all_pages[$pageindex], $all_questions[$question_id]);
2552  }
2553  // calculate position percentage for every page
2554  $max = count($all_pages);
2555  $counter = 1;
2556  foreach ($all_pages as $index => $block)
2557  {
2558  foreach ($block as $blockindex => $question)
2559  {
2560  $all_pages[$index][$blockindex]["position"] = $counter / $max;
2561  }
2562  $counter++;
2563  }
2564  return $all_pages;
2565  }
2566 
2575  function getNextPage($active_page_question_id, $direction)
2576  {
2577  $foundpage = -1;
2578  $pages =& $this->getSurveyPages();
2579  if (strcmp($active_page_question_id, "") == 0)
2580  {
2581  return $pages[0];
2582  }
2583  foreach ($pages as $key => $question_array)
2584  {
2585  foreach ($question_array as $question)
2586  {
2587  if ($active_page_question_id == $question["question_id"])
2588  {
2589  $foundpage = $key;
2590  }
2591  }
2592  }
2593  if ($foundpage == -1)
2594  {
2595  // error: page not found
2596  }
2597  else
2598  {
2599  $foundpage += $direction;
2600  if ($foundpage < 0)
2601  {
2602  return 0;
2603  }
2604  if ($foundpage >= count($pages))
2605  {
2606  return 1;
2607  }
2608  return $pages[$foundpage];
2609  }
2610  }
2611 
2618  function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = FALSE, $permission = "read")
2619  {
2620  include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
2621  return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2622  }
2623 
2630  {
2631  global $ilDB;
2632 
2633  $result_array = array();
2634  $result = $ilDB->queryF("SELECT svy_constraint.*, svy_relation.*, svy_qst_constraint.question_fi ref_question_fi FROM svy_qst_constraint, svy_constraint, ".
2635  "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND ".
2636  "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2637  array('integer'),
2638  array($id)
2639  );
2640  $pc = array();
2641  if ($result->numRows())
2642  {
2643  $pc = $ilDB->fetchAssoc($result);
2644  }
2645  return $pc;
2646  }
2647 
2653  function getConstraints($question_id)
2654  {
2655  global $ilDB;
2656 
2657  $result_array = array();
2658  $result = $ilDB->queryF("SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation ".
2659  "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND ".
2660  "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s ".
2661  "AND svy_qst_constraint.survey_fi = %s",
2662  array('integer','integer'),
2663  array($question_id, $this->getSurveyId())
2664  );
2665  while ($row = $ilDB->fetchAssoc($result))
2666  {
2667  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2668  $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2669  SurveyQuestion::_includeClass($question_type);
2670  $question = new $question_type();
2671  $question->loadFromDb($row["question_fi"]);
2672  $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2673  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));
2674  }
2675  return $result_array;
2676  }
2677 
2684  {
2685  global $ilDB;
2686  $result_array = array();
2687  $result = $ilDB->queryF("SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* ".
2688  "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id ".
2689  "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2690  array('integer'),
2691  array($survey_id)
2692  );
2693  while ($row = $ilDB->fetchAssoc($result))
2694  {
2695  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']));
2696  }
2697  return $result_array;
2698  }
2699 
2700 
2706  function &getVariables($question_id)
2707  {
2708  global $ilDB;
2709 
2710  $result_array = array();
2711  $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN ".
2712  "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s ".
2713  "ORDER BY svy_variable.sequence",
2714  array('integer'),
2715  array($question_id)
2716  );
2717  while ($row = $ilDB->fetchObject($result))
2718  {
2719  $result_array[$row->sequence] = $row;
2720  }
2721  return $result_array;
2722  }
2723 
2732  function addConstraint($if_question_id, $relation, $value, $conjunction)
2733  {
2734  global $ilDB;
2735 
2736  $next_id = $ilDB->nextId('svy_constraint');
2737  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES ".
2738  "(%s, %s, %s, %s, %s)",
2739  array('integer','integer','integer','float', 'integer'),
2740  array($next_id, $if_question_id, $relation, $value, $conjunction)
2741  );
2742  if ($affectedRows)
2743  {
2744  return $next_id;
2745  }
2746  else
2747  {
2748  return null;
2749  }
2750  }
2751 
2752 
2759  public function addConstraintToQuestion($to_question_id, $constraint_id)
2760  {
2761  global $ilDB;
2762 
2763  $next_id = $ilDB->nextId('svy_qst_constraint');
2764  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, ".
2765  "constraint_fi) VALUES (%s, %s, %s, %s)",
2766  array('integer','integer','integer','integer'),
2767  array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2768  );
2769  }
2770 
2781  function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2782  {
2783  global $ilDB;
2784  $affectedRows = $ilDB->manipulateF("UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s ".
2785  "WHERE constraint_id = %s",
2786  array('integer','integer','float','integer','integer'),
2787  array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2788  );
2789  }
2790 
2791  public function updateConjunctionForQuestions($questions, $conjunction)
2792  {
2793  global $ilDB;
2794  foreach ($questions as $question_id)
2795  {
2796  $affectedRows = $ilDB->manipulateF("UPDATE svy_constraint SET conjunction = %s ".
2797  "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2798  array('integer','integer'),
2799  array($conjunction, $question_id)
2800  );
2801  }
2802  }
2803 
2809  function getAllRelations($short_as_key = false)
2810  {
2811  global $ilDB;
2812 
2813  // #7987
2814  $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2815  $custom_order = array_flip($custom_order);
2816 
2817  $result_array = array();
2818  $result = $ilDB->query("SELECT * FROM svy_relation");
2819  while ($row = $ilDB->fetchAssoc($result))
2820  {
2821  if ($short_as_key)
2822  {
2823  $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2824  }
2825  else
2826  {
2827  $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2828  }
2829  }
2830 
2831  $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2832  foreach($result_array as $idx => $item)
2833  {
2834  unset($result_array[$idx]["order"]);
2835  }
2836 
2837  return $result_array;
2838  }
2839 
2843  public function disinviteAllUsers()
2844  {
2845  global $ilDB;
2846  $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2847  array('integer'),
2848  array($this->getSurveyId())
2849  );
2850  while ($row = $ilDB->fetchAssoc($result))
2851  {
2852  $this->disinviteUser($row['user_fi']);
2853  }
2854  }
2855 
2861  public function disinviteUser($user_id)
2862  {
2863  global $ilDB;
2864 
2865  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_inv_usr WHERE survey_fi = %s AND user_fi = %s",
2866  array('integer','integer'),
2867  array($this->getSurveyId(), $user_id)
2868  );
2869  include_once './Services/User/classes/class.ilObjUser.php';
2870  ilObjUser::_dropDesktopItem($user_id, $this->getRefId(), "svy");
2871  }
2872 
2879  function inviteUser($user_id)
2880  {
2881  global $ilDB;
2882 
2883  $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE user_fi = %s AND survey_fi = %s",
2884  array('integer','integer'),
2885  array($user_id, $this->getSurveyId())
2886  );
2887  if ($result->numRows() < 1)
2888  {
2889  $next_id = $ilDB->nextId('svy_inv_usr');
2890  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_inv_usr (invited_user_id, survey_fi, user_fi, tstamp) " .
2891  "VALUES (%s, %s, %s, %s)",
2892  array('integer','integer','integer','integer'),
2893  array($next_id, $this->getSurveyId(), $user_id, time())
2894  );
2895  }
2896  if ($this->getInvitation() == self::INVITATION_ON)
2897  {
2898  include_once './Services/User/classes/class.ilObjUser.php';
2899  ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2900  }
2901  }
2902 
2909  function inviteGroup($group_id)
2910  {
2911  global $ilAccess;
2912  $invited = 0;
2913  include_once "./Modules/Group/classes/class.ilObjGroup.php";
2914  $group = new ilObjGroup($group_id);
2915  $members = $group->getGroupMemberIds();
2916  foreach ($members as $user_id)
2917  {
2918  if ($ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
2919  {
2920  $this->inviteUser($user_id);
2921  if ($this->getInvitation() == self::INVITATION_ON)
2922  {
2923  include_once './Services/User/classes/class.ilObjUser.php';
2924  ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2925  }
2926  }
2927  }
2928  return $invited;
2929  }
2930 
2937  function inviteRole($role_id)
2938  {
2939  global $rbacreview;
2940  global $ilAccess;
2941  $invited = 0;
2942  $members = $rbacreview->assignedUsers($role_id);
2943  foreach ($members as $user_id)
2944  {
2945  if ($ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
2946  {
2947  $this->inviteUser($user_id);
2948  if ($this->getInvitation() == self::INVITATION_ON)
2949  {
2950  include_once './Services/User/classes/class.ilObjUser.php';
2951  ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2952  }
2953  }
2954  }
2955  return $invited;
2956  }
2957 
2964  function &getInvitedUsers()
2965  {
2966  global $ilDB;
2967 
2968  $result_array = array();
2969  $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2970  array('integer'),
2971  array($this->getSurveyId())
2972  );
2973  while ($row = $ilDB->fetchAssoc($result))
2974  {
2975  array_push($result_array, $row["user_fi"]);
2976  }
2977  return $result_array;
2978  }
2979 
2987  function deleteWorkingData($question_id, $active_id)
2988  {
2989  global $ilDB;
2990 
2991  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2992  array('integer','integer'),
2993  array($question_id, $active_id)
2994  );
2995  }
2996 
3005  function loadWorkingData($question_id, $active_id)
3006  {
3007  global $ilDB;
3008  $result_array = array();
3009  $result = $ilDB->queryF("SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
3010  array('integer','integer'),
3011  array($question_id, $active_id)
3012  );
3013  if ($result->numRows() >= 1)
3014  {
3015  while ($row = $ilDB->fetchAssoc($result))
3016  {
3017  array_push($result_array, $row);
3018  }
3019  return $result_array;
3020  }
3021  else
3022  {
3023  return $result_array;
3024  }
3025  }
3026 
3033  function fillSurveyForUser($user_id = ANONYMOUS_USER_ID)
3034  {
3035  global $ilDB;
3036  // create an anonymous key
3037  $anonymous_id = $this->createNewAccessCode();
3038  $this->saveUserAccessCode($user_id, $anonymous_id);
3039  // create the survey_finished dataset and set the survey finished already
3040  $active_id = $ilDB->nextId('svy_finished');
3041  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp) ".
3042  "VALUES (%s, %s, %s, %s, %s, %s)",
3043  array('integer','integer','integer','text','text','integer'),
3044  array($active_id, $this->getSurveyId(), $user_id, $anonymous_id, 1, time())
3045  );
3046  // fill the questions randomly
3047  $pages =& $this->getSurveyPages();
3048  foreach ($pages as $key => $question_array)
3049  {
3050  foreach ($question_array as $question)
3051  {
3052  // instanciate question
3053  require_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3054  $question =& SurveyQuestion::_instanciateQuestion($question["question_id"]);
3055  $question->saveRandomData($active_id);
3056  }
3057  }
3058  }
3059 
3066  function startSurvey($user_id, $anonymous_id, $appraisee_id)
3067  {
3068  global $ilDB;
3069 
3070  if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) return;
3071 
3072  if (strcmp($user_id, "") == 0)
3073  {
3074  if ($user_id == ANONYMOUS_USER_ID)
3075  {
3076  $user_id = 0;
3077  }
3078  }
3079  $next_id = $ilDB->nextId('svy_finished');
3080  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) ".
3081  "VALUES (%s, %s, %s, %s, %s, %s, %s)",
3082  array('integer','integer','integer','text','text','integer','integer'),
3083  array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
3084  );
3085  return $next_id;
3086  }
3087 
3094  function finishSurvey($finished_id)
3095  {
3096  global $ilDB;
3097 
3098  $ilDB->manipulateF("UPDATE svy_finished SET state = %s, tstamp = %s".
3099  " WHERE survey_fi = %s AND finished_id = %s",
3100  array('text','integer','integer','integer'),
3101  array(1, time(), $this->getSurveyId(), $finished_id)
3102  );
3103 
3104  $this->checkTutorNotification();
3105  }
3106 
3114  function setPage($finished_id, $page_id)
3115  {
3116  global $ilDB;
3117 
3118  $affectedRows = $ilDB->manipulateF("UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
3119  array('integer','integer'),
3120  array(($page_id) ? $page_id : 0, $finished_id)
3121  );
3122  }
3123 
3124  function sendNotificationMail($user_id, $anonymize_id, $appr_id)
3125  {
3126  include_once "./Services/User/classes/class.ilObjUser.php";
3127  include_once "./Services/User/classes/class.ilUserUtil.php";
3128 
3129  // #12755
3130  $placeholders = array(
3131  "FIRST_NAME" => "firstname",
3132  "LAST_NAME" => "lastname",
3133  "LOGIN" => "login",
3134  // old style
3135  "firstname" => "firstname"
3136  );
3137 
3138  $recipients = preg_split('/,/', $this->mailaddresses);
3139  foreach ($recipients as $recipient)
3140  {
3141  // #11298
3142  include_once "./Services/Notification/classes/class.ilSystemNotification.php";
3143  $ntf = new ilSystemNotification();
3144  $ntf->setLangModules(array("survey"));
3145  $ntf->setRefId($this->getRefId());
3146  $ntf->setSubjectLangId('finished_mail_subject');
3147 
3148  $messagetext = $this->mailparticipantdata;
3149  if(trim($messagetext))
3150  {
3151  if (!$this->hasAnonymizedResults())
3152  {
3153  $data = ilObjUser::_getUserData(array($user_id));
3154  $data = $data[0];
3155  }
3156  foreach ($placeholders as $key => $mapping)
3157  {
3158  if ($this->hasAnonymizedResults()) // #16480
3159  {
3160  $messagetext = str_replace('[' . $key . ']', '', $messagetext);
3161  }
3162  else
3163  {
3164  $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
3165  }
3166  }
3167  $ntf->setIntroductionDirect($messagetext);
3168  }
3169  else
3170  {
3171  $ntf->setIntroductionLangId('survey_notification_finished_introduction');
3172  }
3173 
3174  // 360°? add appraisee data
3175  if($appr_id)
3176  {
3177  $ntf->addAdditionalInfo('survey_360_appraisee',
3179  }
3180 
3181  $active_id = $this->getActiveID($user_id, $anonymize_id, $appr_id);
3182  $ntf->addAdditionalInfo('results',
3183  $this->getParticipantTextResults($active_id), true);
3184 
3185  $ntf->setGotoLangId('survey_notification_tutor_link');
3186  $ntf->setReasonLangId('survey_notification_finished_reason');
3187 
3188  $ntf->sendMail(array($recipient), null, null);
3189  }
3190  }
3191 
3192  protected function getParticipantTextResults($active_id)
3193  {
3194  $textresult = "";
3195  $userResults =& $this->getUserSpecificResults(array($active_id));
3196  $questions =& $this->getSurveyQuestions(true);
3197  $questioncounter = 1;
3198  foreach ($questions as $question_id => $question_data)
3199  {
3200  $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
3201  $found = $userResults[$question_id][$active_id];
3202  $text = "";
3203  if (is_array($found))
3204  {
3205  $text = implode("\n", $found);
3206  }
3207  else
3208  {
3209  $text = $found;
3210  }
3211  if (strlen($text) == 0) $text = self::getSurveySkippedValue();
3212  $text = str_replace("<br />", "\n", $text);
3213  $textresult .= $text . "\n\n";
3214  }
3215  return $textresult;
3216  }
3217 
3219  {
3220  $counter = 0;
3221  $questions =& $this->getSurveyQuestions();
3222  $counter++;
3223  foreach ($questions as $data)
3224  {
3225  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3226  $question = SurveyQuestion::_instanciateQuestion($data["question_id"]);
3227 
3228  $eval = $this->getCumulatedResults($question);
3229  }
3230  }
3231 
3239  function isAllowedToTakeMultipleSurveys($userid = "")
3240  {
3241  // #7927: special users are deprecated
3242  return false;
3243 
3244  /*
3245  $result = FALSE;
3246  if ($this->getAnonymize())
3247  {
3248  if ($this->isAccessibleWithoutCode())
3249  {
3250  if (strlen($username) == 0)
3251  {
3252  global $ilUser;
3253  $userid = $ilUser->getId();
3254  }
3255  global $ilSetting;
3256  $surveysetting = new ilSetting("survey");
3257  $allowedUsers = strlen($surveysetting->get("multiple_survey_users")) ? explode(",",$surveysetting->get("multiple_survey_users")) : array();
3258  if (in_array($userid, $allowedUsers))
3259  {
3260  $result = TRUE;
3261  }
3262  }
3263  }
3264  return $result;
3265  */
3266  }
3267 
3275  function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
3276  {
3277  global $ilDB;
3278 
3279  // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
3280  if($anonymize_id)
3281  {
3282  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3283  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3284  array('integer','text','integer'),
3285  array($this->getSurveyId(), $anonymize_id, $appr_id)
3286  );
3287  }
3288  else
3289  {
3290  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3291  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3292  array('integer','integer','integer'),
3293  array($this->getSurveyId(), $user_id, $appr_id)
3294  );
3295  }
3296  if ($result->numRows() == 0)
3297  {
3298  return false;
3299  }
3300  else
3301  {
3302  $row = $ilDB->fetchAssoc($result);
3303 
3304  // yes, we are doing it this way
3305  $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
3306 
3307  return (int)$row["state"];
3308  }
3309 
3310  /*
3311  if ($this->getAnonymize())
3312  {
3313  if ((($user_id != ANONYMOUS_USER_ID) && sizeof($anonymize_id)) && (!($this->isAccessibleWithoutCode() && $this->isAllowedToTakeMultipleSurveys())))
3314  {
3315  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3316  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3317  array('integer','integer','integer'),
3318  array($this->getSurveyId(), $user_id, $appr_id)
3319  );
3320  }
3321  else
3322  {
3323  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3324  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3325  array('integer','text','integer'),
3326  array($this->getSurveyId(), $anonymize_id, $appr_id)
3327  );
3328  }
3329  }
3330  else
3331  {
3332  $result = $ilDB->queryF("SELECT * FROM svy_finished".
3333  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3334  array('integer','integer','integer'),
3335  array($this->getSurveyId(), $user_id, $appr_id)
3336  );
3337  }
3338  if ($result->numRows() == 0)
3339  {
3340  return false;
3341  }
3342  else
3343  {
3344  $row = $ilDB->fetchAssoc($result);
3345  $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
3346  return (int)$row["state"];
3347  }
3348  */
3349  }
3350 
3358  function getActiveID($user_id, $anonymize_id, $appr_id)
3359  {
3360  global $ilDB;
3361 
3362  // see self::isSurveyStarted()
3363 
3364  // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
3365  if($anonymize_id)
3366  {
3367  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3368  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3369  array('integer','text','integer'),
3370  array($this->getSurveyId(), $anonymize_id, $appr_id)
3371  );
3372  }
3373  else
3374  {
3375  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3376  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3377  array('integer','integer','integer'),
3378  array($this->getSurveyId(), $user_id, $appr_id)
3379  );
3380  }
3381  if ($result->numRows() == 0)
3382  {
3383  return false;
3384  }
3385  else
3386  {
3387  $row = $ilDB->fetchAssoc($result);
3388  return $row["finished_id"];
3389  }
3390 
3391  /*
3392  if ($this->getAnonymize())
3393  {
3394  if ((($user_id != ANONYMOUS_USER_ID) && (strlen($anonymize_id) == 0)) && (!($this->isAccessibleWithoutCode() && $this->isAllowedToTakeMultipleSurveys())))
3395  {
3396  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3397  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3398  array('integer','integer','integer'),
3399  array($this->getSurveyId(), $user_id, $appr_id)
3400  );
3401  }
3402  else
3403  {
3404  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3405  " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3406  array('integer','text','integer'),
3407  array($this->getSurveyId(), $anonymize_id, $appr_id)
3408  );
3409  }
3410  }
3411  else
3412  {
3413  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3414  " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3415  array('integer','integer','integer'),
3416  array($this->getSurveyId(), $user_id, $appr_id)
3417  );
3418  }
3419  if ($result->numRows() == 0)
3420  {
3421  return false;
3422  }
3423  else
3424  {
3425  $row = $ilDB->fetchAssoc($result);
3426  return $row["finished_id"];
3427  }
3428  */
3429  }
3430 
3438  function getLastActivePage($active_id)
3439  {
3440  global $ilDB;
3441  $result = $ilDB->queryF("SELECT lastpage FROM svy_finished WHERE finished_id = %s",
3442  array('integer'),
3443  array($active_id)
3444  );
3445  if ($result->numRows() == 0)
3446  {
3447  return "";
3448  }
3449  else
3450  {
3451  $row = $ilDB->fetchAssoc($result);
3452  return ($row["lastpage"]) ? $row["lastpage"] : '';
3453  }
3454  }
3455 
3464  function checkConstraint($constraint_data, $working_data)
3465  {
3466  if (count($working_data) == 0)
3467  {
3468  return 0;
3469  }
3470 
3471  if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0))
3472  {
3473  return 0;
3474  }
3475 
3476  $found = false;
3477  foreach ($working_data as $data)
3478  {
3479  switch ($constraint_data["short"])
3480  {
3481  case "<":
3482  if ($data["value"] < $constraint_data["value"])
3483  {
3484  $found = true;
3485  }
3486  break;
3487 
3488  case "<=":
3489  if ($data["value"] <= $constraint_data["value"])
3490  {
3491  $found = true;
3492  }
3493  break;
3494 
3495  case "=":
3496  if ($data["value"] == $constraint_data["value"])
3497  {
3498  $found = true;
3499  }
3500  break;
3501 
3502  case "<>":
3503  if ($data["value"] <> $constraint_data["value"])
3504  {
3505  $found = true;
3506  }
3507  break;
3508 
3509  case ">=":
3510  if ($data["value"] >= $constraint_data["value"])
3511  {
3512  $found = true;
3513  }
3514  break;
3515 
3516  case ">":
3517  if ($data["value"] > $constraint_data["value"])
3518  {
3519  $found = true;
3520  }
3521  break;
3522  }
3523  if ($found)
3524  {
3525  break;
3526  }
3527  }
3528 
3529  return (int)$found;
3530  }
3531 
3533  {
3534  global $ilDB;
3535 
3536  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3537  array('integer'),
3538  array($survey_id)
3539  );
3540  return ($result->numRows()) ? true : false;
3541  }
3542 
3550  {
3551  global $ilDB, $ilLog;
3552 
3553  $users = array();
3554  $result = $ilDB->queryF("SELECT * FROM svy_finished WHERE survey_fi = %s",
3555  array('integer'),
3556  array($this->getSurveyId())
3557  );
3558  if ($result->numRows())
3559  {
3560  while ($row = $ilDB->fetchAssoc($result))
3561  {
3562  array_push($users, $row["finished_id"]);
3563  }
3564  }
3565  return $users;
3566  }
3567 
3574  function &getUserSpecificResults($finished_ids)
3575  {
3576  global $ilDB;
3577 
3578  $evaluation = array();
3579  $questions =& $this->getSurveyQuestions();
3580  foreach ($questions as $question_id => $question_data)
3581  {
3582  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3583  $question_type = SurveyQuestion::_getQuestionType($question_id);
3584  SurveyQuestion::_includeClass($question_type);
3585  $question = new $question_type();
3586  $question->loadFromDb($question_id);
3587  $data =& $question->getUserAnswers($this->getSurveyId(), $finished_ids);
3588  $evaluation[$question_id] = $data;
3589  }
3590  return $evaluation;
3591  }
3592 
3600  function getUserDataFromActiveId($active_id)
3601  {
3602  global $ilDB;
3603 
3604  $surveySetting = new ilSetting("survey");
3605  $use_anonymous_id = array_key_exists("use_anonymous_id", $_GET) ? $_GET["use_anonymous_id"] : $surveySetting->get("use_anonymous_id");
3606  $result = $ilDB->queryF("SELECT * FROM svy_finished WHERE finished_id = %s",
3607  array('integer'),
3608  array($active_id)
3609  );
3610  $row = array();
3611  $foundrows = $result->numRows();
3612  if ($foundrows)
3613  {
3614  $row = $ilDB->fetchAssoc($result);
3615  }
3616  $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3617  $userdata = array(
3618  "fullname" => $name,
3619  "sortname" => $name,
3620  "firstname" => "",
3621  "lastname" => "",
3622  "login" => "",
3623  "gender" => "",
3624  "active_id" => "$active_id"
3625  );
3626  if ($foundrows)
3627  {
3628  if (($row["user_fi"] > 0) && ($row["user_fi"] != ANONYMOUS_USER_ID) &&
3629  !$this->hasAnonymizedResults() &&
3630  !$this->get360Mode()) // 360° uses ANONYMIZE_CODE_ALL which is wrong - see ilObjSurveyGUI::afterSave()
3631  {
3632  include_once './Services/User/classes/class.ilObjUser.php';
3633  if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0)
3634  {
3635  $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3636  }
3637  else
3638  {
3639  $user = new ilObjUser($row["user_fi"]);
3640  $userdata["fullname"] = $user->getFullname();
3641  $gender = $user->getGender();
3642  if (strlen($gender) == 1) $gender = $this->lng->txt("gender_$gender");
3643  $userdata["gender"] = $gender;
3644  $userdata["firstname"] = $user->getFirstname();
3645  $userdata["lastname"] = $user->getLastname();
3646  $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3647  $userdata["login"] = $user->getLogin();
3648  }
3649  }
3650  }
3651  return $userdata;
3652  }
3653 
3663  function &getEvaluationByUser($questions, $active_id)
3664  {
3665  global $ilDB;
3666 
3667  // collect all answers
3668  $answers = array();
3669  $result = $ilDB->queryF("SELECT * FROM svy_answer WHERE active_fi = %s",
3670  array('integer'),
3671  array($active_id)
3672  );
3673  while ($row = $ilDB->fetchAssoc($result))
3674  {
3675  if (!is_array($answers[$row["question_fi"]]))
3676  {
3677  $answers[$row["question_fi"]] = array();
3678  }
3679  array_push($answers[$row["question_fi"]], $row);
3680  }
3681  $userdata = $this->getUserDataFromActiveId($active_id);
3682  $resultset = array(
3683  "name" => $userdata["fullname"],
3684  "firstname" => $userdata["firstname"],
3685  "lastname" => $userdata["lastname"],
3686  "login" => $userdata["login"],
3687  "gender" => $userdata["gender"],
3688  "answers" => array()
3689  );
3690  foreach ($questions as $key => $question)
3691  {
3692  if (array_key_exists($key, $answers))
3693  {
3694  $resultset["answers"][$key] = $answers[$key];
3695  }
3696  else
3697  {
3698  $resultset["answers"][$key] = array();
3699  }
3700  sort($resultset["answers"][$key]);
3701  }
3702  return $resultset;
3703  }
3704 
3713  function getCumulatedResults(&$question, $finished_ids)
3714  {
3715  global $ilDB;
3716 
3717  if(!$finished_ids)
3718  {
3719  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3720  array('integer'),
3721  array($this->getSurveyId())
3722  );
3723  $nr_of_users = $result->numRows();
3724  }
3725  else
3726  {
3727  $nr_of_users = sizeof($finished_ids);
3728  }
3729 
3730  $result_array =& $question->getCumulatedResults($this->getSurveyId(), $nr_of_users, $finished_ids);
3731  return $result_array;
3732  }
3733 
3742  {
3743  global $ilDB;
3744 
3745  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3746  array('integer'),
3747  array($survey_id)
3748  );
3749  return $result->numRows();
3750  }
3751 
3752  function &getQuestions($question_ids)
3753  {
3754  global $ilDB;
3755 
3756  $result_array = array();
3757  $result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag FROM svy_question, svy_qtype WHERE ".
3758  "svy_question.questiontype_fi = svy_qtype.questiontype_id AND svy_question.tstamp > 0 AND ".
3759  $ilDB->in('svy_question.question_id', $question_ids, false, 'integer'));
3760  while ($row = $ilDB->fetchAssoc($result))
3761  {
3762  array_push($result_array, $row);
3763  }
3764  return $result_array;
3765  }
3766 
3772  function getQuestionsTable($arrFilter)
3773  {
3774  global $ilUser;
3775  global $ilDB;
3776  $where = "";
3777  if (is_array($arrFilter))
3778  {
3779  if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title']))
3780  {
3781  $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3782  }
3783  if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description']))
3784  {
3785  $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3786  }
3787  if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author']))
3788  {
3789  $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3790  }
3791  if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type']))
3792  {
3793  $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3794  }
3795  if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl']))
3796  {
3797  $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3798  }
3799  }
3800 
3801  $spls =& $this->getAvailableQuestionpools($use_obj_id = TRUE, $could_be_offline = FALSE, $showPath = FALSE);
3802  $forbidden = "";
3803  $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3804  $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3805  $existing = "";
3806  $existing_questions =& $this->getExistingQuestions();
3807  if (count($existing_questions))
3808  {
3809  $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3810  }
3811 
3812  include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
3814 
3815  $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id".
3816  " FROM svy_question, svy_qtype, object_reference".
3817  " WHERE svy_question.original_id IS NULL".$forbidden.$existing.
3818  " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0".
3819  " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3820 
3821  $rows = array();
3822  if ($query_result->numRows())
3823  {
3824  while ($row = $ilDB->fetchAssoc($query_result))
3825  {
3826  if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt']))
3827  {
3828  if(!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt']))
3829  {
3830  continue;
3831  }
3832  }
3833 
3834  $row['ttype'] = $trans[$row['type_tag']];
3835  if ($row["plugin"])
3836  {
3837  if ($this->isPluginActive($row["type_tag"]))
3838  {
3839  array_push($rows, $row);
3840  }
3841  }
3842  else
3843  {
3844  array_push($rows, $row);
3845  }
3846  }
3847  }
3848  return $rows;
3849  }
3850 
3856  function getQuestionblocksTable($arrFilter)
3857  {
3858  global $ilUser, $ilDB;
3859 
3860  $where = "";
3861  if (is_array($arrFilter))
3862  {
3863  if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title']))
3864  {
3865  $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3866  }
3867  }
3868 
3869  $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE ".
3870  "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi ".
3871  "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, ".
3872  "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3873  $rows = array();
3874  if ($query_result->numRows())
3875  {
3876  $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3877  $surveytitles = array();
3878  foreach ($survey_ref_ids as $survey_ref_id)
3879  {
3880  $survey_id = ilObject::_lookupObjId($survey_ref_id);
3881  $surveytitles[$survey_id] = ilObject::_lookupTitle($survey_id);
3882  }
3883  while ($row = $ilDB->fetchAssoc($query_result))
3884  {
3885  $questions_array =& $this->getQuestionblockQuestions($row["questionblock_id"]);
3886  $counter = 1;
3887  foreach ($questions_array as $key => $value)
3888  {
3889  $questions_array[$key] = "$counter. $value";
3890  $counter++;
3891  }
3892  if (strlen($surveytitles[$row["obj_fi"]])) // only questionpools which are not in trash
3893  {
3894  $rows[$row["questionblock_id"]] = array(
3895  "questionblock_id" => $row["questionblock_id"],
3896  "title" => $row["title"],
3897  "svy" => $surveytitles[$row["obj_fi"]],
3898  "contains" => join($questions_array, ", "),
3899  "owner" => $row["owner_fi"]
3900  );
3901  }
3902  }
3903  }
3904  return $rows;
3905  }
3906 
3913  function toXML()
3914  {
3915  include_once("./Services/Xml/classes/class.ilXmlWriter.php");
3916  $a_xml_writer = new ilXmlWriter;
3917  // set xml header
3918  $a_xml_writer->xmlHeader();
3919  $attrs = array(
3920  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3921  "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3922  );
3923  $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3924  $attrs = array(
3925  "id" => $this->getSurveyId(),
3926  "title" => $this->getTitle()
3927  );
3928  $a_xml_writer->xmlStartTag("survey", $attrs);
3929 
3930  $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
3931  $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
3932  $a_xml_writer->xmlStartTag("objectives");
3933  $attrs = array(
3934  "label" => "introduction"
3935  );
3936  $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), TRUE, TRUE, $attrs);
3937  $attrs = array(
3938  "label" => "outro"
3939  );
3940  $this->addMaterialTag($a_xml_writer, $this->getOutro(), TRUE, TRUE, $attrs);
3941  $a_xml_writer->xmlEndTag("objectives");
3942 
3943  if ($this->getAnonymize())
3944  {
3945  $attribs = array("enabled" => "1");
3946  }
3947  else
3948  {
3949  $attribs = array("enabled" => "0");
3950  }
3951  $a_xml_writer->xmlElement("anonymisation", $attribs);
3952  $a_xml_writer->xmlStartTag("restrictions");
3953  if ($this->getAnonymize() == 2)
3954  {
3955  $attribs = array("type" => "free");
3956  }
3957  else
3958  {
3959  $attribs = array("type" => "restricted");
3960  }
3961  $a_xml_writer->xmlElement("access", $attribs);
3962  if ($this->getStartDate())
3963  {
3964  $attrs = array("type" => "date");
3965  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3966  $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]));
3967  }
3968  if ($this->getEndDate())
3969  {
3970  $attrs = array("type" => "date");
3971  preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3972  $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]));
3973 
3974  }
3975  $a_xml_writer->xmlEndTag("restrictions");
3976 
3977  // constraints
3978  $pages =& $this->getSurveyPages();
3979  $hasconstraints = FALSE;
3980  foreach ($pages as $question_array)
3981  {
3982  foreach ($question_array as $question)
3983  {
3984  if (count($question["constraints"]))
3985  {
3986  $hasconstraints = TRUE;
3987  }
3988  }
3989  }
3990 
3991  if ($hasconstraints)
3992  {
3993  $a_xml_writer->xmlStartTag("constraints");
3994  foreach ($pages as $question_array)
3995  {
3996  foreach ($question_array as $question)
3997  {
3998  if (count($question["constraints"]))
3999  {
4000  // found constraints
4001  foreach ($question["constraints"] as $constraint)
4002  {
4003  $attribs = array(
4004  "sourceref" => $question["question_id"],
4005  "destref" => $constraint["question"],
4006  "relation" => $constraint["short"],
4007  "value" => $constraint["value"],
4008  "conjunction" => $constraint["conjunction"]
4009  );
4010  $a_xml_writer->xmlElement("constraint", $attribs);
4011  }
4012  }
4013  }
4014  }
4015  $a_xml_writer->xmlEndTag("constraints");
4016  }
4017 
4018  // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
4019  $a_xml_writer->xmlStartTag("metadata");
4020 
4021  $custom_properties = array();
4022  $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
4023  $custom_properties["status"] = $this->getStatus();
4024  $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
4025  $custom_properties["pool_usage"] = (int)$this->getPoolUsage();
4026 
4027  $custom_properties["own_results_view"] = (int)$this->hasViewOwnResults();
4028  $custom_properties["own_results_mail"] = (int)$this->hasMailOwnResults();
4029 
4030  $custom_properties["mode_360"] = (int)$this->get360Mode();
4031  $custom_properties["mode_360_self_eval"] = (int)$this->get360SelfEvaluation();
4032  $custom_properties["mode_360_self_rate"] = (int)$this->get360SelfRaters();
4033  $custom_properties["mode_360_self_appr"] = (int)$this->get360SelfAppraisee();
4034  $custom_properties["mode_360_results"] = $this->get360Results();
4035  $custom_properties["mode_360_skill_service"] = (int)$this->get360SkillService();
4036 
4037 
4038  // :TODO: skills?
4039 
4040  // reminder/tutor notification are (currently?) not exportable
4041 
4042  foreach($custom_properties as $label => $value)
4043  {
4044  $a_xml_writer->xmlStartTag("metadatafield");
4045  $a_xml_writer->xmlElement("fieldlabel", NULL, $label);
4046  $a_xml_writer->xmlElement("fieldentry", NULL, $value);
4047  $a_xml_writer->xmlEndTag("metadatafield");
4048  }
4049 
4050  $a_xml_writer->xmlStartTag("metadatafield");
4051  $a_xml_writer->xmlElement("fieldlabel", NULL, "SCORM");
4052  include_once "./Services/MetaData/classes/class.ilMD.php";
4053  $md = new ilMD($this->getId(),0, $this->getType());
4054  $writer = new ilXmlWriter();
4055  $md->toXml($writer);
4056  $metadata = $writer->xmlDumpMem();
4057  $a_xml_writer->xmlElement("fieldentry", NULL, $metadata);
4058  $a_xml_writer->xmlEndTag("metadatafield");
4059 
4060  $a_xml_writer->xmlEndTag("metadata");
4061  $a_xml_writer->xmlEndTag("survey");
4062 
4063  $attribs = array("id" => $this->getId());
4064  $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
4065  // add questionblock descriptions
4066  $obligatory_states =& $this->getObligatoryStates();
4067  foreach ($pages as $question_array)
4068  {
4069  if (count($question_array) > 1)
4070  {
4071  $attribs = array("id" => $question_array[0]["question_id"]);
4072  $attribs = array("showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
4073  "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"]);
4074  $a_xml_writer->xmlStartTag("questionblock", $attribs);
4075  if (strlen($question_array[0]["questionblock_title"]))
4076  {
4077  $a_xml_writer->xmlElement("questionblocktitle", NULL, $question_array[0]["questionblock_title"]);
4078  }
4079  }
4080  foreach ($question_array as $question)
4081  {
4082  if (strlen($question["heading"]))
4083  {
4084  $a_xml_writer->xmlElement("textblock", NULL, $question["heading"]);
4085  }
4086  $questionObject =& $this->_instanciateQuestion($question["question_id"]);
4087  if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
4088  }
4089  if (count($question_array) > 1)
4090  {
4091  $a_xml_writer->xmlEndTag("questionblock");
4092  }
4093  }
4094 
4095  $a_xml_writer->xmlEndTag("surveyquestions");
4096  $a_xml_writer->xmlEndTag("surveyobject");
4097  $xml = $a_xml_writer->xmlDumpMem(FALSE);
4098  return $xml;
4099  }
4100 
4108  function &_instanciateQuestion($question_id)
4109  {
4110  if ($question_id < 1) return FALSE;
4111  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
4112  $question_type = SurveyQuestion::_getQuestionType($question_id);
4113  if (strlen($question_type) == 0) return FALSE;
4114  SurveyQuestion::_includeClass($question_type);
4115  $question = new $question_type();
4116  $question->loadFromDb($question_id);
4117  return $question;
4118  }
4119 
4126  function locateImportFiles($a_dir)
4127  {
4128  if (!is_dir($a_dir) || is_int(strpos($a_dir, "..")))
4129  {
4130  return;
4131  }
4132  $importDirectory = "";
4133  $xmlFile = "";
4134 
4135  $current_dir = opendir($a_dir);
4136  $files = array();
4137  while($entryname = readdir($current_dir))
4138  {
4139  $files[] = $entryname;
4140  }
4141 
4142  foreach($files as $file)
4143  {
4144  if(is_dir($a_dir."/".$file) and ($file != "." and $file!=".."))
4145  {
4146  // found directory created by zip
4147  $importDirectory = $a_dir."/".$file;
4148  }
4149  }
4150  closedir($current_dir);
4151  if (strlen($importDirectory))
4152  {
4153  // find the xml file
4154  $current_dir = opendir($importDirectory);
4155  $files = array();
4156  while($entryname = readdir($current_dir))
4157  {
4158  $files[] = $entryname;
4159  }
4160  foreach($files as $file)
4161  {
4162  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)))
4163  {
4164  // found xml file
4165  $xmlFile = $importDirectory."/".$file;
4166  }
4167  }
4168  }
4169  return array("dir" => $importDirectory, "xml" => $xmlFile);
4170  }
4171 
4178  function importObject($file_info, $svy_qpl_id)
4179  {
4180  if ($svy_qpl_id < 1) $svy_qpl_id = -1;
4181  // check if file was uploaded
4182  $source = $file_info["tmp_name"];
4183  $error = "";
4184  if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK)
4185  {
4186  $error = $this->lng->txt("import_no_file_selected");
4187  }
4188  // check correct file type
4189  $isXml = FALSE;
4190  $isZip = FALSE;
4191  if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0))
4192  {
4193  $isXml = TRUE;
4194  }
4195  // too many different mime-types, so we use the suffix
4196  $suffix = pathinfo($file_info["name"]);
4197  if (strcmp(strtolower($suffix["extension"]), "zip") == 0)
4198  {
4199  $isZip = TRUE;
4200  }
4201  if (!$isXml && !$isZip)
4202  {
4203  $error = $this->lng->txt("import_wrong_file_type");
4204  global $ilLog;
4205  $ilLog->write("Survey: Import error. Filetype was \"" . $file_info["type"] ."\"");
4206  }
4207  if (strlen($error) == 0)
4208  {
4209  // import file as a survey
4210  $import_dir = $this->getImportDirectory();
4211  $import_subdir = "";
4212  $importfile = "";
4213  include_once "./Services/Utilities/classes/class.ilUtil.php";
4214  if ($isZip)
4215  {
4216  $importfile = $import_dir."/".$file_info["name"];
4217  ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
4218  ilUtil::unzip($importfile);
4219  $found = $this->locateImportFiles($import_dir);
4220  if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0)))
4221  {
4222  $error = $this->lng->txt("wrong_import_file_structure");
4223  return $error;
4224  }
4225  $importfile = $found["xml"];
4226  $import_subdir = $found["dir"];
4227  }
4228  else
4229  {
4230  $importfile = tempnam($import_dir, "survey_import");
4231  ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
4232  }
4233  $fh = fopen($importfile, "r");
4234  if (!$fh)
4235  {
4236  $error = $this->lng->txt("import_error_opening_file");
4237  return $error;
4238  }
4239  $xml = fread($fh, filesize($importfile));
4240  $result = fclose($fh);
4241  if (!$result)
4242  {
4243  $error = $this->lng->txt("import_error_closing_file");
4244  return $error;
4245  }
4246 
4247  unset($_SESSION["import_mob_xhtml"]);
4248  if (strpos($xml, "questestinterop"))
4249  {
4250  include_once "./Services/Survey/classes/class.SurveyImportParserPre38.php";
4251  $import = new SurveyImportParserPre38($svy_qpl_id, "", TRUE);
4252  $import->setSurveyObject($this);
4253  $import->setXMLContent($xml);
4254  $import->startParsing();
4255  }
4256  else
4257  {
4258  include_once "./Services/Survey/classes/class.SurveyImportParser.php";
4259  $import = new SurveyImportParser($svy_qpl_id, "", TRUE);
4260  $import->setSurveyObject($this);
4261  $import->setXMLContent($xml);
4262  $import->startParsing();
4263  }
4264 
4265  if (is_array($_SESSION["import_mob_xhtml"]))
4266  {
4267  include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
4268  include_once "./Services/RTE/classes/class.ilRTE.php";
4269  include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
4270  foreach ($_SESSION["import_mob_xhtml"] as $mob)
4271  {
4272  $importfile = $import_subdir . "/" . $mob["uri"];
4273  if (file_exists($importfile))
4274  {
4275  if (!$mob["type"])
4276  {
4277  $mob["type"] = "svy:html";
4278  }
4279 
4280  $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
4281 
4282  // survey mob
4283  if ($mob["type"] == "svy:html")
4284  {
4285  ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
4286  $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
4287  $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
4288  }
4289  // question mob
4290  else if($import->questions[$mob["id"]])
4291  {
4292  $new_qid = $import->questions[$mob["id"]];
4293  ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
4294  $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
4295  $qtext = $new_question->getQuestiontext();
4296  $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
4297  $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
4298  $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
4299  $new_question->setQuestiontext($qtext);
4300  $new_question->saveToDb();
4301 
4302  // also fix existing original in pool
4303  if($new_question->getOriginalId())
4304  {
4305  $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
4306  $pool_question->setQuestiontext($qtext);
4307  $pool_question->saveToDb();
4308  }
4309  }
4310  }
4311  else
4312  {
4313  global $ilLog;
4314  $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
4315  }
4316  }
4319  $this->saveToDb();
4320  }
4321 
4322  // delete import directory
4324  }
4325  return $error;
4326  }
4327 
4336  public function cloneObject($a_target_id,$a_copy_id = 0)
4337  {
4338  global $ilDB;
4339 
4340  $this->loadFromDb();
4341 
4342  // Copy settings
4343  $newObj = parent::cloneObject($a_target_id,$a_copy_id);
4344  $this->cloneMetaData($newObj);
4345  $newObj->updateMetaData();
4346 
4347  $newObj->setAuthor($this->getAuthor());
4348  $newObj->setIntroduction($this->getIntroduction());
4349  $newObj->setOutro($this->getOutro());
4350  $newObj->setEvaluationAccess($this->getEvaluationAccess());
4351  $newObj->setStartDate($this->getStartDate());
4352  $newObj->setEndDate($this->getEndDate());
4353  $newObj->setInvitation($this->getInvitation());
4354  $newObj->setInvitationMode($this->getInvitationMode());
4355  $newObj->setAnonymize($this->getAnonymize());
4356  $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
4357  $newObj->setTemplate($this->getTemplate());
4358  $newObj->setPoolUsage($this->getPoolUsage());
4359  $newObj->setViewOwnResults($this->hasViewOwnResults());
4360  $newObj->setMailOwnResults($this->hasMailOwnResults());
4361 
4362  // #12661
4363  if($this->get360Mode())
4364  {
4365  $newObj->set360Mode(true);
4366  $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
4367  $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
4368  $newObj->set360SelfRaters($this->get360SelfRaters());
4369  $newObj->set360Results($this->get360Results());
4370  $newObj->set360SkillService($this->get360SkillService());
4371  }
4372 
4373  // reminder/notification
4374  $newObj->setReminderStatus($this->getReminderStatus());
4375  $newObj->setReminderStart($this->getReminderStart());
4376  $newObj->setReminderEnd($this->getReminderEnd());
4377  $newObj->setReminderFrequency($this->getReminderFrequency());
4378  $newObj->setReminderTarget($this->getReminderTarget());
4379  // reminder_last_sent must not be copied!
4380  $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
4381  $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
4382  $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
4383 
4384  $question_pointer = array();
4385  // clone the questions
4386  $mapping = array();
4387  include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
4388 
4389  foreach ($this->questions as $key => $question_id)
4390  {
4391  $question = ilObjSurvey::_instanciateQuestion($question_id);
4392  if($question) // #10824
4393  {
4394  $question->id = -1;
4395  $original_id = SurveyQuestion::_getOriginalId($question_id, false);
4396  $question->saveToDb($original_id);
4397  $newObj->questions[$key] = $question->getId();
4398  $question_pointer[$question_id] = $question->getId();
4399  $mapping[$question_id] = $question->getId();
4400  }
4401  }
4402 
4403  //copy online status if object is not the root copy object
4404  $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
4405 
4406  if(!$cp_options->isRootNode($this->getRefId()))
4407  {
4408  $newObj->setStatus($this->isOnline()?self::STATUS_ONLINE: self::STATUS_OFFLINE);
4409  }
4410 
4411  $newObj->saveToDb();
4412  $newObj->cloneTextblocks($mapping);
4413 
4414  // #14929
4415  if($this->get360Mode() &&
4416  $this->get360SkillService())
4417  {
4418  include_once "./Modules/Survey/classes/class.ilSurveySkill.php";
4419  $src_skills = new ilSurveySkill($this);
4420  $tgt_skills = new ilSurveySkill($newObj);
4421 
4422  foreach($mapping as $src_qst_id => $tgt_qst_id)
4423  {
4424  $qst_skill = $src_skills->getSkillForQuestion($src_qst_id);
4425  if($qst_skill)
4426  {
4427  $tgt_skills->addQuestionSkillAssignment($tgt_qst_id, $qst_skill["base_skill_id"], $qst_skill["tref_id"]);
4428  }
4429  }
4430  }
4431 
4432  // clone the questionblocks
4433  $questionblocks = array();
4434  $questionblock_questions = array();
4435  $result = $ilDB->queryF("SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
4436  array('integer'),
4437  array($this->getSurveyId())
4438  );
4439  if ($result->numRows() > 0)
4440  {
4441  while ($row = $ilDB->fetchAssoc($result))
4442  {
4443  array_push($questionblock_questions, $row);
4444  $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
4445  }
4446  }
4447  // create new questionblocks
4448  foreach ($questionblocks as $key => $value)
4449  {
4450  $questionblock = ilObjSurvey::_getQuestionblock($key);
4451  $questionblock_id = ilObjSurvey::_addQuestionblock($questionblock["title"], $questionblock["owner_fi"], $questionblock["show_questiontext"], $questionblock["show_blocktitle"]);
4452  $questionblocks[$key] = $questionblock_id;
4453  }
4454  // create new questionblock questions
4455  foreach ($questionblock_questions as $key => $value)
4456  {
4457  if($questionblocks[$value["questionblock_fi"]] &&
4458  $question_pointer[$value["question_fi"]])
4459  {
4460  $next_id = $ilDB->nextId('svy_qblk_qst');
4461  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) ".
4462  "VALUES (%s, %s, %s, %s)",
4463  array('integer','integer','integer','integer'),
4464  array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
4465  );
4466  }
4467  }
4468 
4469  // clone the constraints
4470  $constraints = ilObjSurvey::_getConstraints($this->getSurveyId());
4471  $newConstraints = array();
4472  foreach ($constraints as $key => $constraint)
4473  {
4474  if ($question_pointer[$constraint["for_question"]] &&
4475  $question_pointer[$constraint["question"]])
4476  {
4477  if (!array_key_exists($constraint['id'], $newConstraints))
4478  {
4479  $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
4480  $newConstraints[$constraint['id']] = $constraint_id;
4481  }
4482  $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
4483  }
4484  }
4485 
4486  // clone the obligatory states
4487  $result = $ilDB->queryF("SELECT * FROM svy_qst_oblig WHERE survey_fi = %s",
4488  array('integer'),
4489  array($this->getSurveyId())
4490  );
4491  if ($result->numRows() > 0)
4492  {
4493  while ($row = $ilDB->fetchAssoc($result))
4494  {
4495  if($question_pointer[$row["question_fi"]])
4496  {
4497  $next_id = $ilDB->nextId('svy_qst_oblig');
4498  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_oblig (question_obligatory_id, survey_fi, question_fi, ".
4499  "obligatory, tstamp) VALUES (%s, %s, %s, %s, %s)",
4500  array('integer','integer','integer','text','integer'),
4501  array($next_id, $newObj->getSurveyId(), $question_pointer[$row["question_fi"]], $row["obligatory"], time())
4502  );
4503  }
4504  }
4505  }
4506  return $newObj;
4507  }
4508 
4509  function getTextblock($question_id)
4510  {
4511  global $ilDB;
4512  $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE question_fi = %s",
4513  array('integer'),
4514  array($question_id)
4515  );
4516  if ($result->numRows())
4517  {
4518  $row = $ilDB->fetchAssoc($result);
4519  return $row["heading"];
4520  }
4521  else
4522  {
4523  return "";
4524  }
4525  }
4526 
4532  function cloneTextblocks($mapping)
4533  {
4534  foreach ($mapping as $original_id => $new_id)
4535  {
4536  $textblock = $this->getTextblock($original_id);
4537  include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
4538  $this->saveHeading(ilUtil::stripSlashes($textblock, TRUE, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
4539  }
4540  }
4541 
4548  {
4549  include_once "./Services/Utilities/classes/class.ilUtil.php";
4550  $svy_data_dir = ilUtil::getDataDir()."/svy_data";
4551  ilUtil::makeDir($svy_data_dir);
4552  if(!is_writable($svy_data_dir))
4553  {
4554  $this->ilias->raiseError("Survey Data Directory (".$svy_data_dir
4555  .") not writeable.",$this->ilias->error_obj->FATAL);
4556  }
4557 
4558  // create learning module directory (data_dir/lm_data/lm_<id>)
4559  $svy_dir = $svy_data_dir."/svy_".$this->getId();
4560  ilUtil::makeDir($svy_dir);
4561  if(!@is_dir($svy_dir))
4562  {
4563  $this->ilias->raiseError("Creation of Survey Directory failed.",$this->ilias->error_obj->FATAL);
4564  }
4565  // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
4566  $export_dir = $svy_dir."/export";
4567  ilUtil::makeDir($export_dir);
4568  if(!@is_dir($export_dir))
4569  {
4570  $this->ilias->raiseError("Creation of Export Directory failed.",$this->ilias->error_obj->FATAL);
4571  }
4572  }
4573 
4578  {
4579  include_once "./Services/Utilities/classes/class.ilUtil.php";
4580  $export_dir = ilUtil::getDataDir()."/svy_data"."/svy_".$this->getId()."/export";
4581 
4582  return $export_dir;
4583  }
4584 
4588  function getExportFiles($dir)
4589  {
4590  // quit if import dir not available
4591  if (!@is_dir($dir) or
4592  !is_writeable($dir))
4593  {
4594  return array();
4595  }
4596 
4597  // open directory
4598  $dir = dir($dir);
4599 
4600  // initialize array
4601  $file = array();
4602 
4603  // get files and save the in the array
4604  while ($entry = $dir->read())
4605  {
4606  if ($entry != "." && $entry != ".." && ereg("^[0-9]{10}_{2}[0-9]+_{2}(svy_)*[0-9]+\.[a-z]{1,3}\$", $entry))
4607  {
4608  $file[] = $entry;
4609  }
4610  }
4611 
4612  // close import directory
4613  $dir->close();
4614  // sort files
4615  sort ($file);
4616  reset ($file);
4617 
4618  return $file;
4619  }
4620 
4627  {
4628  include_once "./Services/Utilities/classes/class.ilUtil.php";
4629  $svy_data_dir = ilUtil::getDataDir()."/svy_data";
4630  ilUtil::makeDir($svy_data_dir);
4631 
4632  if(!is_writable($svy_data_dir))
4633  {
4634  $this->ilias->raiseError("Survey Data Directory (".$svy_data_dir
4635  .") not writeable.",$this->ilias->error_obj->FATAL);
4636  }
4637 
4638  // create test directory (data_dir/svy_data/svy_<id>)
4639  $svy_dir = $svy_data_dir."/svy_".$this->getId();
4640  ilUtil::makeDir($svy_dir);
4641  if(!@is_dir($svy_dir))
4642  {
4643  $this->ilias->raiseError("Creation of Survey Directory failed.",$this->ilias->error_obj->FATAL);
4644  }
4645 
4646  // create import subdirectory (data_dir/svy_data/svy_<id>/import)
4647  $import_dir = $svy_dir."/import";
4648  ilUtil::makeDir($import_dir);
4649  if(!@is_dir($import_dir))
4650  {
4651  $this->ilias->raiseError("Creation of Import Directory failed.",$this->ilias->error_obj->FATAL);
4652  }
4653  }
4654 
4659  {
4660  include_once "./Services/Utilities/classes/class.ilUtil.php";
4661  $import_dir = ilUtil::getDataDir()."/svy_data".
4662  "/svy_".$this->getId()."/import";
4663  if (!is_dir($import_dir))
4664  {
4665  ilUtil::makeDirParents($import_dir);
4666  }
4667  if(@is_dir($import_dir))
4668  {
4669  return $import_dir;
4670  }
4671  else
4672  {
4673  return false;
4674  }
4675  }
4676 
4677  function saveHeading($heading = "", $insertbefore)
4678  {
4679  global $ilDB;
4680  if ($heading)
4681  {
4682  $affectedRows = $ilDB->manipulateF("UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4683  array('text','integer','integer'),
4684  array($heading, $this->getSurveyId(), $insertbefore)
4685  );
4686  }
4687  else
4688  {
4689  $affectedRows = $ilDB->manipulateF("UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4690  array('text','integer','integer'),
4691  array(NULL, $this->getSurveyId(), $insertbefore)
4692  );
4693  }
4694  }
4695 
4696  function isAnonymousKey($key)
4697  {
4698  global $ilDB;
4699 
4700  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
4701  array('text','integer'),
4702  array($key, $this->getSurveyId())
4703  );
4704  return ($result->numRows() == 1) ? true : false;
4705  }
4706 
4707  function getUserSurveyCode($user_id)
4708  {
4709  global $ilDB;
4710 
4711  if (($user_id == ANONYMOUS_USER_ID) || (($this->isAccessibleWithoutCode() && $this->isAllowedToTakeMultipleSurveys()))) return "";
4712  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_finished WHERE survey_fi = %s AND user_fi = %s",
4713  array('integer','integer'),
4714  array($this->getSurveyId(), $user_id)
4715  );
4716  if ($result->numRows() == 1)
4717  {
4718  $row = $ilDB->fetchAssoc($result);
4719  return $row["anonymous_id"];
4720  }
4721  else
4722  {
4723  return "";
4724  }
4725  }
4726 
4727  function bindSurveyCodeToUser($user_id, $code)
4728  {
4729  global $ilDB;
4730 
4731  if($user_id == ANONYMOUS_USER_ID)
4732  {
4733  return;
4734  }
4735 
4736  if($this->checkSurveyCode($code))
4737  {
4738  $ilDB->manipulate("UPDATE svy_anonymous".
4739  " SET user_key = ".$ilDB->quote(md5($user_id), "text").
4740  " WHERE survey_key = ".$ilDB->quote($code, "text"));
4741  }
4742  }
4743 
4745  {
4746  global $ilDB;
4747 
4748  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
4749  array('text','integer'),
4750  array($key, $this->getSurveyId())
4751  );
4752  return ($result->numRows() == 1) ? true : false;
4753  }
4754 
4755  function checkSurveyCode($code)
4756  {
4757  if ($this->isAnonymousKey($code))
4758  {
4759  if ($this->isSurveyStarted("", $code) == 1)
4760  {
4761  return false;
4762  }
4763  else
4764  {
4765  return true;
4766  }
4767  }
4768  else
4769  {
4770  return false;
4771  }
4772  }
4773 
4781  {
4782  global $ilDB;
4783 
4784  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND user_key IS NULL",
4785  array('integer'),
4786  array($this->getSurveyId())
4787  );
4788  return $result->numRows();
4789  }
4790 
4798  function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
4799  {
4800  global $ilDB, $ilUser, $lng;
4801 
4802  include_once "./Services/Link/classes/class.ilLink.php";
4803 
4804  $sql = "SELECT svy_anonymous.*, svy_finished.state".
4805  " FROM svy_anonymous".
4806  " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)".
4807  " WHERE svy_anonymous.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
4808  " AND svy_anonymous.user_key IS NULL";
4809 
4810  if($a_codes)
4811  {
4812  $sql .= " AND ".$ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
4813  }
4814  else if($a_ids)
4815  {
4816  $sql .= " AND ".$ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
4817  }
4818 
4819  $export = array();
4820 
4821  // #14905
4822  $titles = array();
4823  $titles[] = '"'.$lng->txt("survey_code").'"';
4824  $titles[] = '"'.$lng->txt("email").'"';
4825  $titles[] = '"'.$lng->txt("lastname").'"';
4826  $titles[] = '"'.$lng->txt("firstname").'"';
4827  $titles[] = '"'.$lng->txt("create_date").'"';
4828  $titles[] = '"'.$lng->txt("used").'"';
4829  $titles[] = '"'.$lng->txt("mail_sent_short").'"';
4830  $titles[] = '"'.$lng->txt("survey_code_url").'"';
4831  $export[] = implode(";", $titles);
4832 
4833  $result = $ilDB->query($sql);
4834  $default_lang = $ilUser->getPref("survey_code_language");
4835  while ($row = $ilDB->fetchAssoc($result))
4836  {
4837  $item = array();
4838  $item[] = $row["survey_key"];
4839 
4840  if($row["externaldata"])
4841  {
4842  $ext = unserialize($row["externaldata"]);
4843  $item[] = $ext["email"];
4844  $item[] = $ext["lastname"];
4845  $item[] = $ext["firstname"];
4846  }
4847  else
4848  {
4849  $item[] = "";
4850  $item[] = "";
4851  $item[] = "";
4852  }
4853 
4854  // No relative (today, tomorrow...) dates in export.
4855  $date = new ilDateTime($row['tstamp'],IL_CAL_UNIX);
4856  $item[] = $date->get(IL_CAL_DATETIME);
4857 
4858  $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4859  $item[] = ($row["sent"]) ? 1 : 0;
4860 
4861  $params = array("accesscode" => $row["survey_key"]);
4862  if ($default_lang)
4863  {
4864  $params["lang"] = $default_lang;
4865  }
4866  $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4867 
4868  $export[] = '"'.implode('";"', $item).'"';
4869  }
4870  return implode("\n", $export);
4871  }
4872 
4880  public function getSurveyCodesTableData(array $ids = null, $lang = null)
4881  {
4882  global $ilDB;
4883 
4884  include_once "./Services/Link/classes/class.ilLink.php";
4885 
4886  $codes = array();
4887 
4888  $sql = "SELECT svy_anonymous.*, svy_finished.state".
4889  " FROM svy_anonymous".
4890  " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)".
4891  " WHERE svy_anonymous.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer") /*.
4892  " AND svy_anonymous.user_key IS NULL" */; // #15860
4893 
4894  if($ids)
4895  {
4896  $sql .= " AND ".$ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4897  }
4898 
4899  $sql .= " ORDER BY tstamp, survey_key ASC";
4900  $result = $ilDB->query($sql);
4901  if ($result->numRows() > 0)
4902  {
4903  while ($row = $ilDB->fetchAssoc($result))
4904  {
4905  $href = "";
4906  $used = false;
4907  if ($this->isSurveyCodeUsed($row["survey_key"]))
4908  {
4909  $used = true;
4910  }
4911  else
4912  {
4913  $params = array("accesscode" => $row["survey_key"]);
4914  if ($lang)
4915  {
4916  $params["lang"] = $lang;
4917  }
4918  $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4919  }
4920 
4921 
4922  $item = array(
4923  'id' => $row["anonymous_id"],
4924  'code' => $row["survey_key"],
4925  'date' => $row["tstamp"],
4926  'used' => $used,
4927  'sent' => $row['sent'],
4928  'href' => $href,
4929  'email' => '',
4930  'last_name' => '',
4931  'first_name' => ''
4932  );
4933 
4934  if($row["externaldata"])
4935  {
4936  $ext = unserialize($row["externaldata"]);
4937  $item['email'] = $ext['email'];
4938  $item['last_name'] = $ext['lastname'];
4939  $item['first_name'] = $ext['firstname'];
4940  }
4941 
4942  array_push($codes, $item);
4943  }
4944  }
4945  return $codes;
4946  }
4947 
4948  function isSurveyCodeUsed($code)
4949  {
4950  global $ilDB;
4951  $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4952  array('integer','text'),
4953  array($this->getSurveyId(), $code)
4954  );
4955  return ($result->numRows() > 0) ? true : false;
4956  }
4957 
4958  function isSurveyCodeUnique($code)
4959  {
4960  global $ilDB;
4961  $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4962  array('integer','text'),
4963  array($this->getSurveyId(), $code)
4964  );
4965  return ($result->numRows() > 0) ? false : true;
4966  }
4967 
4968  function createSurveyCodes($nrOfCodes)
4969  {
4970  global $ilDB;
4971 
4972  $res = array();
4973 
4974  for ($i = 0; $i < $nrOfCodes; $i++)
4975  {
4976  $next_id = $ilDB->nextId('svy_anonymous');
4977  $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) ".
4978  "VALUES (%s, %s, %s, %s)",
4979  array('integer','text','integer','integer'),
4980  array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4981  );
4982  $res[] = $next_id;
4983  }
4984 
4985  return $res;
4986  }
4987 
4988  function importSurveyCode($a_anonymize_key, $a_created, $a_data)
4989  {
4990  global $ilDB;
4991 
4992  $next_id = $ilDB->nextId('svy_anonymous');
4993  $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) ".
4994  "VALUES (%s, %s, %s, %s, %s)",
4995  array('integer','text','integer','text','integer'),
4996  array($next_id, $a_anonymize_key, $this->getSurveyId(), serialize($a_data), $a_created)
4997  );
4998  }
4999 
5001  {
5002  global $ilDB;
5003 
5004  $ids = array();
5005  foreach ($data as $dataset)
5006  {
5007  $anonymize_key = $this->createNewAccessCode();
5008  $next_id = $ilDB->nextId('svy_anonymous');
5009  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) ".
5010  "VALUES (%s, %s, %s, %s, %s)",
5011  array('integer','text','integer','text','integer'),
5012  array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
5013  );
5014  $ids[] = $next_id;
5015  }
5016  return $ids;
5017  }
5018 
5019  function sendCodes($not_sent, $subject, $message, $lang)
5020  {
5021  /*
5022  * 0 = all
5023  * 1 = not sent
5024  * 2 = finished
5025  * 3 = not finished
5026  */
5027  $check_finished = ($not_sent > 1);
5028 
5029  include_once "./Services/Mail/classes/class.ilMail.php";
5030  include_once "./Services/Link/classes/class.ilLink.php";
5031  $user_id = $this->getOwner();
5032  $mail = new ilMail($user_id);
5033  $recipients = $this->getExternalCodeRecipients($check_finished);
5034  foreach ($recipients as $data)
5035  {
5036  if($data['email'] && $data['code'])
5037  {
5038  $do_send = false;
5039  switch ((int)$not_sent)
5040  {
5041  case 1:
5042  $do_send = !(bool)$data['sent'];
5043  break;
5044 
5045  case 2:
5046  $do_send = $data['finished'];
5047  break;
5048 
5049  case 3:
5050  $do_send = !$data['finished'];
5051  break;
5052 
5053  default:
5054  $do_send = true;
5055  break;
5056  }
5057  if ($do_send)
5058  {
5059  // build text
5060  $messagetext = $message;
5061  $url = ilLink::_getLink($this->getRefId(), "svy",
5062  array(
5063  "accesscode" => $data["code"],
5064  "lang" => $lang
5065  ));
5066  $messagetext = str_replace('[url]', "<" . $url . ">", $messagetext);
5067  foreach ($data as $key => $value)
5068  {
5069  $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
5070  }
5071 
5072  // send mail
5073  $mail->sendMail(
5074  $data['email'], // to
5075  "", // cc
5076  "", // bcc
5077  $subject, // subject
5078  $messagetext, // message
5079  array(), // attachments
5080  array('normal') // type
5081  );
5082  }
5083  }
5084  }
5085 
5086  global $ilDB;
5087  $ilDB->manipulateF("UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
5088  array('integer','integer'),
5089  array(1, $this->getSurveyId())
5090  );
5091  }
5092 
5093  function getExternalCodeRecipients($a_check_finished = false)
5094  {
5095  global $ilDB;
5096  $result = $ilDB->queryF("SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
5097  array('integer'),
5098  array($this->getSurveyId())
5099  );
5100  $res = array();
5101  while ($row = $ilDB->fetchAssoc($result))
5102  {
5103  if(!$row['externaldata'])
5104  {
5105  continue;
5106  }
5107 
5108  $externaldata = unserialize($row['externaldata']);
5109  if(!$externaldata['email'])
5110  {
5111  continue;
5112  }
5113 
5114  $externaldata['code'] = $row['code'];
5115  $externaldata['sent'] = $row['sent'];
5116 
5117  if($a_check_finished)
5118  {
5119  $externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
5120  }
5121 
5122  array_push($res, $externaldata);
5123  }
5124  return $res;
5125  }
5126 
5132  function deleteSurveyCode($survey_code)
5133  {
5134  global $ilDB;
5135 
5136  if (strlen($survey_code) > 0)
5137  {
5138  $affectedRows = $ilDB->manipulateF("DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
5139  array('integer', 'text'),
5140  array($this->getSurveyId(), $survey_code)
5141  );
5142  }
5143  }
5144 
5151  function getUserAccessCode($user_id)
5152  {
5153  global $ilDB;
5154  $access_code = "";
5155  $result = $ilDB->queryF("SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
5156  array('integer','text'),
5157  array($this->getSurveyId(), md5($user_id))
5158  );
5159  if ($result->numRows())
5160  {
5161  $row = $ilDB->fetchAssoc($result);
5162  $access_code = $row["survey_key"];
5163  }
5164  return $access_code;
5165  }
5166 
5173  function saveUserAccessCode($user_id, $access_code)
5174  {
5175  global $ilDB;
5176 
5177  // not really sure what to do about ANONYMOUS_USER_ID
5178 
5179  $next_id = $ilDB->nextId('svy_anonymous');
5180  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) ".
5181  "VALUES (%s, %s, %s, %s, %s)",
5182  array('integer','text', 'integer', 'text', 'integer'),
5183  array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
5184  );
5185  }
5186 
5193  {
5194  // create a 5 character code
5195  $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
5196  mt_srand();
5197  $code = "";
5198  for ($i = 1; $i <=5; $i++)
5199  {
5200  $index = mt_rand(0, strlen($codestring)-1);
5201  $code .= substr($codestring, $index, 1);
5202  }
5203  // verify it against the database
5204  while (!$this->isSurveyCodeUnique($code))
5205  {
5206  $code = $this->createNewAccessCode();
5207  }
5208  return $code;
5209  }
5210 
5211 
5222  function &processCSVRow($row, $quoteAll = FALSE, $separator = ";")
5223  {
5224  $resultarray = array();
5225  foreach ($row as $rowindex => $entry)
5226  {
5227  if(is_array($entry))
5228  {
5229  $entry = implode("/", $entry);
5230  }
5231  $surround = FALSE;
5232  if ($quoteAll)
5233  {
5234  $surround = TRUE;
5235  }
5236  if (strpos($entry, "\"") !== FALSE)
5237  {
5238  $entry = str_replace("\"", "\"\"", $entry);
5239  $surround = TRUE;
5240  }
5241  if (strpos($entry, $separator) !== FALSE)
5242  {
5243  $surround = TRUE;
5244  }
5245  // replace all CR LF with LF (for Excel for Windows compatibility
5246  $entry = str_replace(chr(13).chr(10), chr(10), $entry);
5247  if ($surround)
5248  {
5249  $resultarray[$rowindex] = utf8_decode("\"" . $entry . "\"");
5250  }
5251  else
5252  {
5253  $resultarray[$rowindex] = utf8_decode($entry);
5254  }
5255  }
5256  return $resultarray;
5257  }
5258 
5259  function _getLastAccess($finished_id)
5260  {
5261  global $ilDB;
5262 
5263  $result = $ilDB->queryF("SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
5264  array('integer'),
5265  array($finished_id)
5266  );
5267  if ($result->numRows())
5268  {
5269  $row = $ilDB->fetchAssoc($result);
5270  return $row["tstamp"];
5271  }
5272  else
5273  {
5274  $result = $ilDB->queryF("SELECT tstamp FROM svy_finished WHERE finished_id = %s",
5275  array('integer'),
5276  array($finished_id)
5277  );
5278  if ($result->numRows())
5279  {
5280  $row = $ilDB->fetchAssoc($result);
5281  return $row["tstamp"];
5282  }
5283  }
5284  return "";
5285  }
5286 
5293  function prepareTextareaOutput($txt_output)
5294  {
5295  include_once "./Services/Utilities/classes/class.ilUtil.php";
5296  return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
5297  }
5298 
5306  function isHTML($a_text)
5307  {
5308  if (preg_match("/<[^>]*?>/", $a_text))
5309  {
5310  return TRUE;
5311  }
5312  else
5313  {
5314  return FALSE;
5315  }
5316  }
5317 
5326  function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE, $attribs = NULL)
5327  {
5328  include_once "./Services/RTE/classes/class.ilRTE.php";
5329  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
5330 
5331  $a_xml_writer->xmlStartTag("material", $attribs);
5332  $attrs = array(
5333  "type" => "text/plain"
5334  );
5335  if ($this->isHTML($a_material))
5336  {
5337  $attrs["type"] = "text/xhtml";
5338  }
5339  $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
5340  $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
5341 
5342  if ($add_mobs)
5343  {
5344  $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
5345  foreach ($mobs as $mob)
5346  {
5347  $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
5348  if (strpos($mattext, $mob_id) !== FALSE)
5349  {
5350  $mob_obj =& new ilObjMediaObject($mob);
5351  $imgattrs = array(
5352  "label" => $mob_id,
5353  "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
5354  "type" => "svy:html",
5355  "id" => $this->getId()
5356  );
5357  $a_xml_writer->xmlElement("matimage", $imgattrs, NULL);
5358  }
5359  }
5360  }
5361  if ($close_material_tag) $a_xml_writer->xmlEndTag("material");
5362  }
5363 
5373  {
5374  if ($this->getAnonymize() != self::ANONYMIZE_OFF)
5375  {
5376  if ($this->surveyCodeSecurity == FALSE)
5377  {
5378  return TRUE;
5379  }
5380  }
5381  return FALSE;
5382  }
5383 
5391  function processPrintoutput2FO($print_output)
5392  {
5393  global $ilLog;
5394 
5395  if (extension_loaded("tidy"))
5396  {
5397  $config = array(
5398  "indent" => false,
5399  "output-xml" => true,
5400  "numeric-entities" => true
5401  );
5402  $tidy = new tidy();
5403  $tidy->parseString($print_output, $config, 'utf8');
5404  $tidy->cleanRepair();
5405  $print_output = tidy_get_output($tidy);
5406  $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
5407  }
5408  else
5409  {
5410  $print_output = str_replace("&nbsp;", "&#160;", $print_output);
5411  $print_output = str_replace("&otimes;", "X", $print_output);
5412 
5413  // #17680 - metric questions use &#160; in print view
5414  $print_output = str_replace("&gt;", ">", $print_output);
5415  $print_output = str_replace("&lt;", "<", $print_output);
5416  $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
5417  $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
5418  $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
5419  }
5420  $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
5421 
5422  // additional font support
5423  $xsl = str_replace(
5424  'font-family="Helvetica, unifont"',
5425  'font-family="'.$GLOBALS['ilSetting']->get('rpc_pdf_font','Helvetica, unifont').'"',
5426  $xsl
5427  );
5428 
5429  $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
5430  $xh = xslt_create();
5431  $params = array();
5432  $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", NULL, $args, $params);
5433  xslt_error($xh);
5434  xslt_free($xh);
5435  $ilLog->write($output);
5436  return $output;
5437  }
5438 
5445  function deliverPDFfromFO($fo)
5446  {
5447  global $ilLog;
5448 
5449  include_once "./Services/Utilities/classes/class.ilUtil.php";
5450  $fo_file = ilUtil::ilTempnam() . ".fo";
5451  $fp = fopen($fo_file, "w"); fwrite($fp, $fo); fclose($fp);
5452 
5453  include_once './Services/WebServices/RPC/classes/class.ilRpcClientFactory.php';
5454  try
5455  {
5456  $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
5457  ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
5458  return true;
5459  }
5460  catch(XML_RPC2_FaultException $e)
5461  {
5462  $ilLog->write(__METHOD__.': '.$e->getMessage());
5463  return false;
5464  }
5465  catch(Exception $e)
5466  {
5467  $ilLog->write(__METHOD__.': '.$e->getMessage());
5468  return false;
5469  }
5470 
5471  /*
5472  include_once "./Services/Transformation/classes/class.ilFO2PDF.php";
5473  $fo2pdf = new ilFO2PDF();
5474  $fo2pdf->setFOString($fo);
5475  $result = $fo2pdf->send();
5476  ilUtil::deliverData($result, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
5477  */
5478  }
5479 
5486  function isPluginActive($a_pname)
5487  {
5488  global $ilPluginAdmin;
5489  if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname))
5490  {
5491  return TRUE;
5492  }
5493  else
5494  {
5495  return FALSE;
5496  }
5497  }
5498 
5504  public function setSurveyId($survey_id)
5505  {
5506  $this->survey_id = $survey_id;
5507  }
5508 
5515  public function &getUserData($ids)
5516  {
5517  global $ilDB;
5518 
5519  if (!is_array($ids) || count($ids) ==0) return array();
5520 
5521  $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
5522  $result_array = array();
5523  while ($row = $ilDB->fetchAssoc($result))
5524  {
5525  $result_array[$row["usr_id"]]= $row;
5526  }
5527  return $result_array;
5528  }
5529 
5530  function &getGroupData($ids)
5531  {
5532  if (!is_array($ids) || count($ids) ==0) return array();
5533  $result = array();
5534  foreach ($ids as $ref_id)
5535  {
5536  $obj_id = ilObject::_lookupObjId($ref_id);
5537  $result[$ref_id] = array("ref_id" => $ref_id, "title" => ilObject::_lookupTitle($obj_id), "description" => ilObject::_lookupDescription($obj_id));
5538  }
5539  return $result;
5540  }
5541 
5542  function &getRoleData($ids)
5543  {
5544  if (!is_array($ids) || count($ids) ==0) return array();
5545  $result = array();
5546  foreach ($ids as $obj_id)
5547  {
5548  $result[$obj_id] = array("obj_id" => $obj_id, "title" => ilObject::_lookupTitle($obj_id), "description" => ilObject::_lookupDescription($obj_id));
5549  }
5550  return $result;
5551  }
5552 
5554  {
5555  return $this->mailnotification;
5556  }
5557 
5558  function setMailNotification($a_notification)
5559  {
5560  $this->mailnotification = ($a_notification) ? true : false;
5561  }
5562 
5563  function getMailAddresses()
5564  {
5565  return $this->mailaddresses;
5566  }
5567 
5568  function setMailAddresses($a_addresses)
5569  {
5570  $this->mailaddresses = $a_addresses;
5571  }
5572 
5574  {
5576  }
5577 
5578  function setMailParticipantData($a_data)
5579  {
5580  $this->mailparticipantdata = $a_data;
5581  }
5582 
5583  public function getSurveyTimes()
5584  {
5585  global $ilDB;
5586 
5587  $result = $ilDB->queryF("SELECT * FROM svy_times, svy_finished WHERE svy_finished.survey_fi = %s",
5588  array('integer'),
5589  array($this->getId())
5590  );
5591  $times = array();;
5592  while ($row = $ilDB->fetchAssoc($result))
5593  {
5594  if (strlen($row['left_page']) && strlen($row['entered_page']))
5595  $times[$row['finished_fi']] += ($row['left_page']-$row['entered_page']);
5596  }
5597  return $times;
5598  }
5599 
5600  function setStartTime($finished_id, $first_question)
5601  {
5602  global $ilDB;
5603  $time = time();
5604  $_SESSION['svy_entered_page'] = $time;
5605  $affectedRows = $ilDB->manipulateF("INSERT INTO svy_times (finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s)",
5606  array('integer', 'integer', 'integer', 'integer'),
5607  array($finished_id, $time, NULL, $first_question)
5608  );
5609  }
5610 
5611  function setEndTime($finished_id)
5612  {
5613  global $ilDB;
5614  $time = time();
5615  $affectedRows = $ilDB->manipulateF("UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
5616  array('integer', 'integer', 'integer'),
5617  array($time, $finished_id, $_SESSION['svy_entered_page'])
5618  );
5619  unset($_SESSION['svy_entered_page']);
5620  }
5621 
5622  function getWorkingtimeForParticipant($finished_id)
5623  {
5624  global $ilDB;
5625 
5626  $result = $ilDB->queryF("SELECT * FROM svy_times WHERE finished_fi = %s",
5627  array('integer'),
5628  array($finished_id)
5629  );
5630  $total = 0;
5631  while ($row = $ilDB->fetchAssoc($result))
5632  {
5633  if ($row['left_page'] > 0 && $row['entered_page'] > 0)
5634  $total += $row['left_page'] - $row['entered_page'];
5635  }
5636  return $total;
5637  }
5638 
5640  {
5641  $this->template_id = (int)$template_id;
5642  }
5643 
5644  function getTemplate()
5645  {
5646  return $this->template_id;
5647  }
5648 
5649  function updateOrder(array $a_order)
5650  {
5651  if(sizeof($this->questions) == sizeof($a_order))
5652  {
5653  $this->questions = array_flip($a_order);
5654  $this->saveQuestionsToDB();
5655  }
5656  }
5657 
5658  function getPoolUsage()
5659  {
5660  return $this->pool_usage;
5661  }
5662 
5663  function setPoolUsage($a_value)
5664  {
5665  $this->pool_usage = (bool)$a_value;
5666  }
5667 
5673  function isPoolActive()
5674  {
5675  $use_pool = (bool)$this->getPoolUsage();
5676  $template_settings = $this->getTemplate();
5677  if($template_settings)
5678  {
5679  include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
5680  $template_settings = new ilSettingsTemplate($template_settings);
5681  $template_settings = $template_settings->getSettings();
5682  $template_settings = $template_settings["use_pool"];
5683  if($template_settings && $template_settings["hide"])
5684  {
5685  $use_pool = (bool)$template_settings["value"];
5686  }
5687  }
5688  return $use_pool;
5689  }
5690 
5697  {
5698  if(!$template_id)
5699  {
5700  return;
5701  }
5702 
5703  include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
5704  $template = new ilSettingsTemplate($template_id);
5705  $template_settings = $template->getSettings();
5706  if($template_settings)
5707  {
5708  if($template_settings["show_question_titles"] !== NULL)
5709  {
5710  if($template_settings["show_question_titles"]["value"])
5711  {
5712  $this->setShowQuestionTitles(true);
5713  }
5714  else
5715  {
5716  $this->setShowQuestionTitles(false);
5717  }
5718  }
5719 
5720  if($template_settings["use_pool"] !== NULL)
5721  {
5722  if($template_settings["use_pool"]["value"])
5723  {
5724  $this->setPoolUsage(true);
5725  }
5726  else
5727  {
5728  $this->setPoolUsage(false);
5729  }
5730  }
5731 
5732  if($template_settings["anonymization_options"]["value"])
5733  {
5734  $anon_map = array('personalized' => self::ANONYMIZE_OFF,
5735  'anonymize_with_code' => self::ANONYMIZE_ON,
5736  'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
5737  $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
5738  }
5739 
5740  /* other settings: not needed here
5741  * - enabled_end_date
5742  * - enabled_start_date
5743  * - rte_switch
5744  */
5745  }
5746 
5747  $this->setTemplate($template_id);
5748  $this->saveToDb();
5749  }
5750 
5751  public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
5752  {
5753  global $ilDB;
5754 
5755  $a_email = trim($a_email);
5756 
5757  // :TODO:
5758  if($a_email && !ilUtil::is_email($a_email))
5759  {
5760  return;
5761  }
5762 
5763  $data = array("email" => $a_email,
5764  "lastname" => trim($a_last_name),
5765  "firstname" => trim($a_first_name));
5766 
5767  $fields = array(
5768  "externaldata" => array("text", serialize($data)),
5769  "sent" => array("integer", $a_sent)
5770  );
5771 
5772  $ilDB->update("svy_anonymous", $fields,
5773  array("anonymous_id" => array("integer", $a_id)));
5774  }
5775 
5776 
5777  //
5778  // 360°
5779  //
5780 
5781  public function set360Mode($a_value)
5782  {
5783  $this->mode_360 = (bool)$a_value;
5784  }
5785 
5786  public function get360Mode()
5787  {
5788  return (bool)$this->mode_360;
5789  }
5790 
5791  public function set360SelfEvaluation($a_value)
5792  {
5793  $this->mode_360_self_eval = (bool)$a_value;
5794  }
5795 
5796  public function get360SelfEvaluation()
5797  {
5798  return (bool)$this->mode_360_self_eval;
5799  }
5800 
5801  public function set360SelfAppraisee($a_value)
5802  {
5803  $this->mode_360_self_appr = (bool)$a_value;
5804  }
5805 
5806  public function get360SelfAppraisee()
5807  {
5808  return (bool)$this->mode_360_self_appr;
5809  }
5810 
5811  public function set360SelfRaters($a_value)
5812  {
5813  $this->mode_360_self_rate = (bool)$a_value;
5814  }
5815 
5816  public function get360SelfRaters()
5817  {
5818  return (bool)$this->mode_360_self_rate;
5819  }
5820 
5821  public function set360Results($a_value)
5822  {
5823  $this->mode_360_results = (int)$a_value;
5824  }
5825 
5826  public function get360Results()
5827  {
5828  return (int)$this->mode_360_results;
5829  }
5830 
5831  public function addAppraisee($a_user_id)
5832  {
5833  global $ilDB;
5834 
5835  if(!$this->isAppraisee($a_user_id) &&
5836  $a_user_id != ANONYMOUS_USER_ID)
5837  {
5838  $fields = array(
5839  "obj_id" => array("integer", $this->getSurveyId()),
5840  "user_id" => array("integer", $a_user_id)
5841  );
5842  $ilDB->insert("svy_360_appr", $fields);
5843  }
5844  }
5845 
5846  public function isAppraisee($a_user_id)
5847  {
5848  global $ilDB;
5849 
5850  $set = $ilDB->query("SELECT user_id".
5851  " FROM svy_360_appr".
5852  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5853  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5854  return (bool)$ilDB->numRows($set);
5855  }
5856 
5857  public function isAppraiseeClosed($a_user_id)
5858  {
5859  global $ilDB;
5860 
5861  $set = $ilDB->query("SELECT has_closed".
5862  " FROM svy_360_appr".
5863  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5864  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5865  $row = $ilDB->fetchAssoc($set);
5866  return $row["has_closed"];
5867  }
5868 
5869  public function deleteAppraisee($a_user_id)
5870  {
5871  global $ilDB;
5872 
5873  $ilDB->manipulate("DELETE FROM svy_360_appr".
5874  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5875  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5876 
5877  $set = $ilDB->query("SELECT user_id".
5878  " FROM svy_360_rater".
5879  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5880  " AND appr_id = ".$ilDB->quote($a_user_id, "integer"));
5881  while($row = $ilDB->fetchAssoc($set))
5882  {
5883  $this->deleteRater($a_user_id, $row["user_id"]);
5884  }
5885  // appraisee will not be part of raters table
5886  if($this->get360SelfEvaluation())
5887  {
5888  $this->deleteRater($a_user_id, $a_user_id);
5889  }
5890  }
5891 
5892  public function getAppraiseesData()
5893  {
5894  global $ilDB;
5895 
5896  $res = array();
5897 
5898  $set = $ilDB->query("SELECT * FROM svy_360_appr".
5899  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer"));
5900  while($row = $ilDB->fetchAssoc($set))
5901  {
5902  $name = ilObjUser::_lookupName($row["user_id"]);
5903  $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5904  $res[$row["user_id"]] = $name;
5905 
5906  $finished = 0;
5907  $raters = $this->getRatersData($row["user_id"]);
5908  foreach($raters as $rater)
5909  {
5910  if($rater["finished"])
5911  {
5912  $finished++;
5913  }
5914  }
5915  $res[$row["user_id"]]["finished"] = $finished."/".sizeof($raters);
5916  $res[$row["user_id"]]["closed"] = $row["has_closed"];
5917  }
5918 
5919  return $res;
5920  }
5921 
5922  public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5923  {
5924  global $ilDB;
5925 
5926  if($this->isAppraisee($a_appraisee_id) &&
5927  !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id))
5928  {
5929  $fields = array(
5930  "obj_id" => array("integer", $this->getSurveyId()),
5931  "appr_id" => array("integer", $a_appraisee_id),
5932  "user_id" => array("integer", $a_user_id),
5933  "anonymous_id" => array("integer", $a_anonymous_id)
5934  );
5935  $ilDB->insert("svy_360_rater", $fields);
5936  }
5937  }
5938 
5939  public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5940  {
5941  global $ilDB;
5942 
5943  // user is rater if already appraisee and active self-evaluation
5944  if($this->isAppraisee($a_user_id) &&
5945  $this->get360SelfEvaluation() &&
5946  (!$a_appraisee_id || $a_appraisee_id == $a_user_id))
5947  {
5948  return true;
5949  }
5950 
5951  // :TODO: should we get rid of code as well?
5952 
5953  $sql = "SELECT user_id".
5954  " FROM svy_360_rater".
5955  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5956  " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5957  " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer");
5958  if($a_appraisee_id)
5959  {
5960  $sql .= " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer");
5961  }
5962  $set = $ilDB->query($sql);
5963  return (bool)$ilDB->numRows($set);
5964  }
5965 
5966  public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5967  {
5968  global $ilDB;
5969 
5970  $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5971  if($finished_id)
5972  {
5973  $this->removeSelectedSurveyResults(array($finished_id));
5974  }
5975 
5976  $ilDB->manipulate("DELETE FROM svy_360_rater".
5977  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5978  " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer").
5979  " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5980  " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer"));
5981  }
5982 
5983  public function getRatersData($a_appraisee_id)
5984  {
5985  global $ilDB;
5986 
5987  $res = $anonymous_ids = array();
5988 
5989  $set = $ilDB->query("SELECT * FROM svy_360_rater".
5990  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5991  " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer"));
5992  while($row = $ilDB->fetchAssoc($set))
5993  {
5994  if($row["anonymous_id"])
5995  {
5996  $res["a".$row["anonymous_id"]] = array(
5997  "lastname" => "unknown code ".$row["anonymous_id"],
5998  "sent" => $row["mail_sent"],
5999  "finished" => null
6000  );
6001  $anonymous_ids[] = $row["anonymous_id"];
6002  }
6003  else
6004  {
6005  $name = ilObjUser::_lookupName($row["user_id"]);
6006  $name["user_id"] = "u".$name["user_id"];
6007  $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
6008  $name["sent"] = $row["mail_sent"];
6009  $name["finished"] = (bool)$this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
6010  $res["u".$row["user_id"]] = $name;
6011  }
6012  }
6013 
6014  if(sizeof($anonymous_ids))
6015  {
6016  $data = $this->getSurveyCodesTableData($anonymous_ids);
6017  foreach($data as $item)
6018  {
6019  if(isset($res["a".$item["id"]]))
6020  {
6021  $res["a".$item["id"]] = array(
6022  "user_id" => "a".$item["id"],
6023  "lastname" => $item["last_name"],
6024  "firstname" => $item["first_name"],
6025  "login" => "",
6026  "email" => $item["email"],
6027  "code" => $item["code"],
6028  "href" => $item["href"],
6029  "sent" => $res["a".$item["id"]]["sent"],
6030  "finished" => (bool)$this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
6031  );
6032  }
6033  }
6034  }
6035 
6036  return $res;
6037  }
6038 
6039  public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
6040  {
6041  global $ilDB;
6042 
6043  $res = array();
6044 
6045  $sql = "SELECT appr_id FROM svy_360_rater".
6046  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer");
6047 
6048  if($a_user_id)
6049  {
6050  $sql .= " AND user_id = ".$ilDB->quote($a_user_id, "integer");
6051  }
6052  else
6053  {
6054  $sql .= " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer");
6055  }
6056 
6057  $set = $ilDB->query($sql);
6058  while($row = $ilDB->fetchAssoc($set))
6059  {
6060  $res[] = $row["appr_id"];
6061  }
6062 
6063  // user may evaluate himself if already appraisee
6064  if($this->get360SelfEvaluation() &&
6065  $this->isAppraisee($a_user_id) &&
6066  !in_array($a_user_id, $res))
6067  {
6068  $res[] = $a_user_id;
6069  }
6070 
6071  return $res;
6072  }
6073 
6074  public function getAnonymousIdByCode($a_code)
6075  {
6076  global $ilDB;
6077 
6078  $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous".
6079  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6080  " AND survey_key = ".$ilDB->quote($a_code, "text"));
6081  $res = $ilDB->fetchAssoc($set);
6082  return $res["anonymous_id"];
6083  }
6084 
6085  function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
6086  {
6087  global $ilDB;
6088 
6089  $sql = "SELECT * FROM svy_finished".
6090  " WHERE survey_fi =".$ilDB->quote($this->getSurveyId(), "integer").
6091  " AND appr_id = ".$ilDB->quote($appr_id, "integer");
6092  if ($user_id)
6093  {
6094  $sql .= " AND user_fi = ".$ilDB->quote($user_id, "integer");
6095  }
6096  else
6097  {
6098  $sql .= " AND anonymous_id = ".$ilDB->quote($anonymous_code, "text");
6099  }
6100  $result = $ilDB->query($sql);
6101  if ($result->numRows() == 0)
6102  {
6103  return false;
6104  }
6105  else
6106  {
6107  $row = $ilDB->fetchAssoc($result);
6108  return (int)$row["state"];
6109  }
6110  }
6111 
6112  function getUserSurveyExecutionStatus($a_code = null)
6113  {
6114  global $ilUser, $ilDB;
6115 
6116  $user_id = $ilUser->getId();
6117 
6118  // code is obligatory?
6119  if(!$this->isAccessibleWithoutCode())
6120  {
6121  if(!$a_code)
6122  {
6123  // registered raters do not need code
6124  if($this->get360Mode() &&
6125  $user_id != ANONYMOUS_USER_ID &&
6126  $this->isRater(0, $user_id))
6127  {
6128  // auto-generate code
6129  $a_code = $this->createNewAccessCode();
6130  $this->saveUserAccessCode($user_id, $a_code);
6131  }
6132  else
6133  {
6134  return null;
6135  }
6136  }
6137  }
6138  else if($user_id == ANONYMOUS_USER_ID ||
6139  $this->getAnonymize() == self::ANONYMIZE_FREEACCESS)
6140  {
6141  if(!$a_code)
6142  {
6143  // auto-generate code
6144  $a_code = $this->createNewAccessCode();
6145  $this->saveUserAccessCode($user_id, $a_code);
6146  }
6147  }
6148  else
6149  {
6150  $a_code = null;
6151  }
6152 
6153  $res = array();
6154 
6155  $sql = "SELECT * FROM svy_finished".
6156  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
6157  // if proper user id is given, use it or current code
6158  if($user_id != ANONYMOUS_USER_ID)
6159  {
6160  $sql .= " AND (user_fi = ".$ilDB->quote($user_id, "integer").
6161  " OR anonymous_id = ".$ilDB->quote($a_code, "text").")";
6162  }
6163  // use anonymous code to find finished id(s)
6164  else
6165  {
6166  $sql .= " AND anonymous_id = ".$ilDB->quote($a_code, "text");
6167  }
6168  $set = $ilDB->query($sql);
6169  while($row = $ilDB->fetchAssoc($set))
6170  {
6171  $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
6172  "user_id" => $row["user_fi"],
6173  "code" => $row["anonymous_id"],
6174  "finished" => (bool)$row["state"]);
6175  }
6176 
6177  return array("code"=>$a_code, "runs"=>$res);
6178  }
6179 
6180  function findCodeForUser($a_user_id)
6181  {
6182  global $ilDB;
6183 
6184  if($a_user_id != ANONYMOUS_USER_ID)
6185  {
6186  $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf".
6187  " WHERE sf.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6188  " AND sf.user_fi = ".$ilDB->quote($a_user_id, "integer"));
6189  $a_code = $ilDB->fetchAssoc($set);
6190  return $a_code["anonymous_id"];
6191  }
6192  }
6193 
6194  function isUnusedCode($a_code, $a_user_id)
6195  {
6196  global $ilDB;
6197 
6198  $set = $ilDB->query("SELECT user_fi FROM svy_finished".
6199  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6200  " AND anonymous_id = ".$ilDB->quote($a_code, "text"));
6201  $user_id = $ilDB->fetchAssoc($set);
6202  $user_id = $user_id["user_fi"];
6203 
6204  if($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID))
6205  {
6206  return false;
6207  }
6208  return true;
6209  }
6210 
6211  function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
6212  {
6213  global $ilDB;
6214 
6215  $res = array();
6216 
6217  $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished".
6218  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6219  " AND appr_id = ".$ilDB->quote($a_appr_id, "integer"));
6220  while($row = $ilDB->fetchAssoc($set))
6221  {
6222  if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id)
6223  {
6224  continue;
6225  }
6226  $res[] = $row["finished_id"];
6227  }
6228 
6229  return $res;
6230  }
6231 
6239  function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
6240  {
6241  global $ilDB;
6242 
6243  $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished".
6244  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6245  " AND appr_id = ".$ilDB->quote($a_appr_id, "integer").
6246  " AND user_fi = ".$ilDB->quote($a_rat_id, "integer"));
6247  $row = $ilDB->fetchAssoc($set);
6248  return $row["finished_id"];
6249  }
6250 
6251 
6252  // 360° using competence/skill service
6253 
6259  function set360SkillService($a_val)
6260  {
6261  $this->mode_360_skill_service = $a_val;
6262  }
6263 
6270  {
6272  }
6273 
6274  function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
6275  {
6276  global $ilDB;
6277 
6278  if(!$a_tstamp)
6279  {
6280  $a_tstamp = time();
6281  }
6282 
6283  $ilDB->manipulate("UPDATE svy_360_rater".
6284  " SET mail_sent = ".$ilDB->quote($a_tstamp, "integer").
6285  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
6286  " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer").
6287  " AND user_id = ".$ilDB->quote($a_user_id, "integer").
6288  " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer"));
6289  }
6290 
6291  function closeAppraisee($a_user_id)
6292  {
6293  global $ilDB;
6294 
6295  // close the appraisee
6296  $ilDB->manipulate("UPDATE svy_360_appr".
6297  " SET has_closed = ".$ilDB->quote(time(), "integer").
6298  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
6299  " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
6300 
6301  // write competences
6302  include_once("./Services/Skill/classes/class.ilSkillManagementSettings.php");
6303  $skmg_set = new ilSkillManagementSettings();
6304  if ($this->get360SkillService() && $skmg_set->isActivated())
6305  {
6306  include_once("./Modules/Survey/classes/class.ilSurveySkill.php");
6307  $sskill = new ilSurveySkill($this);
6308  $sskill->writeAppraiseeSkills($a_user_id);
6309  }
6310  }
6311 
6313  {
6314  global $ilDB;
6315 
6316  $ilDB->manipulate("UPDATE svy_360_appr".
6317  " SET has_closed = ".$ilDB->quote(null, "integer").
6318  " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer"));
6319  }
6320 
6321  public static function validateExternalRaterCode($a_ref_id, $a_code)
6322  {
6323  if(!isset($_SESSION["360_extrtr"][$a_ref_id]))
6324  {
6325  $svy = new self($a_ref_id);
6326  $svy->loadFromDB();
6327 
6328  if($svy->canStartSurvey(null, true) &&
6329  $svy->get360Mode() &&
6330  $svy->isAnonymousKey($a_code))
6331  {
6332  $anonymous_id = $svy->getAnonymousIdByCode($a_code);
6333  if($anonymous_id)
6334  {
6335  if(sizeof($svy->getAppraiseesToRate(null, $anonymous_id)))
6336  {
6337  $_SESSION["360_extrtr"][$a_ref_id] = true;
6338  return true;
6339  }
6340  }
6341  }
6342 
6343  $_SESSION["360_extrtr"][$a_ref_id] = false;
6344  return false;
6345  }
6346 
6347  return $_SESSION["360_extrtr"][$a_ref_id];
6348  }
6349 
6350 
6351  //
6352  // reminder/notification
6353  //
6354 
6355  public function getReminderStatus()
6356  {
6357  return (bool)$this->reminder_status;
6358  }
6359 
6360  public function setReminderStatus($a_value)
6361  {
6362  $this->reminder_status = (bool)$a_value;
6363  }
6364 
6365  public function getReminderStart()
6366  {
6367  return $this->reminder_start;
6368  }
6369 
6370  public function setReminderStart(ilDate $a_value = null)
6371  {
6372  $this->reminder_start = $a_value;
6373  }
6374 
6375  public function getReminderEnd()
6376  {
6377  return $this->reminder_end;
6378  }
6379 
6380  public function setReminderEnd(ilDate $a_value = null)
6381  {
6382  $this->reminder_end = $a_value;
6383  }
6384 
6385  public function getReminderFrequency()
6386  {
6388  }
6389 
6390  public function setReminderFrequency($a_value)
6391  {
6392  $this->reminder_frequency = (int)$a_value;
6393  }
6394 
6395  public function getReminderTarget()
6396  {
6397  return $this->reminder_target;
6398  }
6399 
6400  public function setReminderTarget($a_value)
6401  {
6402  $this->reminder_target = (int)$a_value;
6403  }
6404 
6405  public function getReminderLastSent()
6406  {
6408  }
6409 
6410  public function setReminderLastSent($a_value)
6411  {
6412  $this->reminder_last_sent = $a_value;
6413  }
6414 
6415  public function getTutorNotificationStatus()
6416  {
6417  return (bool)$this->tutor_ntf_status;
6418  }
6419 
6420  public function setTutorNotificationStatus($a_value)
6421  {
6422  $this->tutor_ntf_status = (bool)$a_value;
6423  }
6424 
6426  {
6428  }
6429 
6430  public function setTutorNotificationRecipients(array $a_value)
6431  {
6432  $this->tutor_ntf_recipients = $a_value;
6433  }
6434 
6435  public function getTutorNotificationTarget()
6436  {
6437  return $this->tutor_ntf_target;
6438  }
6439 
6440  public function setTutorNotificationTarget($a_value)
6441  {
6442  $this->tutor_ntf_target = (int)$a_value;
6443  }
6444 
6445  protected function checkTutorNotification()
6446  {
6447  global $ilDB;
6448 
6449  if($this->getTutorNotificationStatus())
6450  {
6451  $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
6452  if($user_ids)
6453  {
6454  $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished".
6455  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6456  " AND state = ".$ilDB->quote(1, "integer").
6457  " AND ".$ilDB->in("user_fi", $user_ids, "", "integer"));
6458  $row = $ilDB->fetchAssoc($set);
6459  if($row["numall"] == sizeof($user_ids))
6460  {
6461  $this->sendTutorNotification();
6462  }
6463  }
6464  }
6465  }
6466 
6467  protected function getNotificationTargetUserIds($a_use_invited)
6468  {
6469  global $tree;
6470 
6471  if((bool)$a_use_invited)
6472  {
6473  $user_ids = $this->getInvitedUsers();
6474  }
6475  else
6476  {
6477  $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
6478  if($parent_grp_ref_id)
6479  {
6480  include_once "Modules/Group/classes/class.ilGroupParticipants.php";
6481  $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
6482  $user_ids = $part->getMembers();
6483  }
6484  else
6485  {
6486  $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
6487  if($parent_crs_ref_id)
6488  {
6489  include_once "Modules/Course/classes/class.ilCourseParticipants.php";
6490  $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
6491  $user_ids = $part->getMembers();
6492  }
6493  }
6494  }
6495  return $user_ids;
6496  }
6497 
6498  protected function sendTutorNotification()
6499  {
6500  include_once "./Services/Mail/classes/class.ilMail.php";
6501  include_once "./Services/User/classes/class.ilObjUser.php";
6502  include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6503  include_once "./Services/User/classes/class.ilUserUtil.php";
6504  include_once "./Services/Link/classes/class.ilLink.php";
6505  $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6506 
6507  foreach($this->getTutorNotificationRecipients() as $user_id)
6508  {
6509  // use language of recipient to compose message
6510  $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6511  $ulng->loadLanguageModule('survey');
6512 
6513  $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
6514  $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id))."\n\n";
6515 
6516  $message .= $ulng->txt('survey_notification_tutor_body').":\n\n";
6517  $message .= $ulng->txt('obj_svy').": ". $this->getTitle()."\n";
6518  $message .= "\n".$ulng->txt('survey_notification_tutor_link').": ".$link;
6519 
6520  $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6521  $mail_obj->appendInstallationSignature(true);
6522  $mail_obj->sendMail(ilObjUser::_lookupLogin($user_id),
6523  "", "", $subject, $message, array(), array("system"));
6524  }
6525  }
6526 
6527  public function checkReminder()
6528  {
6529  global $ilDB, $ilAccess;
6530 
6531  $now = time();
6532  $today = date("Y-m-d");
6533 
6534  // object settings / participation period
6535  if($this->isOffline() ||
6536  !$this->getReminderStatus() ||
6537  ($this->getStartDate() && $now < $this->getStartDate()) ||
6538  ($this->getEndDate() && $now > $this->getEndDate()))
6539  {
6540  return false;
6541  }
6542 
6543  // reminder period
6544  $start = $this->getReminderStart();
6545  if($start)
6546  {
6547  $start = $start->get(IL_CAL_DATE);
6548  }
6549  $end = $this->getReminderEnd();
6550  if($end)
6551  {
6552  $end = $end->get(IL_CAL_DATE);
6553  }
6554  if($today < $start ||
6555  ($end && $today > $end))
6556  {
6557  return false;
6558  }
6559 
6560  // object access period
6561  include_once "Services/Object/classes/class.ilObjectActivation.php";
6562  $item_data = ilObjectActivation::getItem($this->getRefId());
6563  if($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
6564  ($now < $item_data["timing_start"] ||
6565  $now > $item_data["timing_end"]))
6566  {
6567  return false;
6568  }
6569 
6570  // check frequency
6571  $cut = new ilDate($today, IL_CAL_DATE);
6572  $cut->increment(IL_CAL_DAY, $this->getReminderFrequency()*-1);
6573  if(!$this->getReminderLastSent() ||
6574  $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10))
6575  {
6576  $missing_ids = array();
6577 
6578  // #16871
6579  $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
6580  if($user_ids)
6581  {
6582  // gather participants who already finished
6583  $finished_ids = array();
6584  $set = $ilDB->query("SELECT user_fi FROM svy_finished".
6585  " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6586  " AND state = ".$ilDB->quote(1, "text").
6587  " AND ".$ilDB->in("user_fi", $user_ids, "", "integer"));
6588  while($row = $ilDB->fetchAssoc($set))
6589  {
6590  $finished_ids[] = $row["user_fi"];
6591  }
6592 
6593  // some users missing out?
6594  $missing_ids = array_diff($user_ids, $finished_ids);
6595  if($missing_ids)
6596  {
6597  foreach($missing_ids as $idx => $user_id)
6598  {
6599  // should be able to participate
6600  if(!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
6601  {
6602  unset($missing_ids[$idx]);
6603  }
6604  }
6605  }
6606  if($missing_ids)
6607  {
6608  $this->sentReminder($missing_ids);
6609  }
6610  }
6611 
6612  $this->setReminderLastSent($today);
6613  $this->saveToDb();
6614 
6615  return sizeof($missing_ids);
6616  }
6617 
6618  return false;
6619  }
6620 
6621  protected function sentReminder(array $a_recipient_ids)
6622  {
6623  include_once "./Services/Mail/classes/class.ilMail.php";
6624  include_once "./Services/User/classes/class.ilObjUser.php";
6625  include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6626  include_once "./Services/User/classes/class.ilUserUtil.php";
6627  include_once "./Services/Link/classes/class.ilLink.php";
6628  $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6629 
6630  foreach($a_recipient_ids as $user_id)
6631  {
6632  // use language of recipient to compose message
6633  $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6634  $ulng->loadLanguageModule('survey');
6635 
6636  $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
6637  $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id))."\n\n";
6638 
6639  $message .= $ulng->txt('survey_reminder_body').":\n\n";
6640  $message .= $ulng->txt('obj_svy').": ". $this->getTitle()."\n";
6641  $message .= "\n".$ulng->txt('survey_reminder_link').": ".$link;
6642 
6643  $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6644  $mail_obj->appendInstallationSignature(true);
6645  $mail_obj->sendMail(ilObjUser::_lookupLogin($user_id),
6646  "", "", $subject, $message, array(), array("system"));
6647  }
6648  }
6649 
6650  function setActivationStartDate($starting_time = NULL)
6651  {
6652  $this->activation_starting_time = $starting_time;
6653  }
6654 
6655  function setActivationEndDate($ending_time = NULL)
6656  {
6657  $this->activation_ending_time = $ending_time;
6658  }
6659 
6661  {
6662  return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : NULL;
6663  }
6664 
6666  {
6667  return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : NULL;
6668  }
6669 
6670  function setViewOwnResults($a_value)
6671  {
6672  $this->view_own_results = (bool)$a_value;
6673  }
6674 
6676  {
6677  return $this->view_own_results;
6678  }
6679 
6680  function setMailOwnResults($a_value)
6681  {
6682  $this->mail_own_results = (bool)$a_value;
6683  }
6684 
6686  {
6687  return $this->mail_own_results;
6688  }
6689 
6690  public static function getSurveySkippedValue()
6691  {
6692  global $lng;
6693 
6694  // #13541
6695 
6696  include_once "./Services/Administration/classes/class.ilSetting.php";
6697  $surveySetting = new ilSetting("survey");
6698  if(!$surveySetting->get("skipped_is_custom", false))
6699  {
6700  return $lng->txt("skipped");
6701  }
6702  else
6703  {
6704  return $surveySetting->get("skipped_custom_value", "");
6705  }
6706  }
6707 
6708 } // END class.ilObjSurvey
6709 
6710 ?>