ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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
4include_once "./Services/Object/classes/class.ilObject.php";
5
15class ilObjSurvey extends ilObject
16{
20 protected $user;
21
25 protected $access;
26
30 protected $plugin_admin;
31
32 const STATUS_OFFLINE = 0;
33 const STATUS_ONLINE = 1;
34
38
39 const INVITATION_OFF = 0;
40 const INVITATION_ON = 1;
41
42 const MODE_UNLIMITED = 0;
44
45 const ANONYMIZE_OFF = 0; // personalized, no codes
46 const ANONYMIZE_ON = 1; // anonymized, codes
47 const ANONYMIZE_FREEACCESS = 2; // anonymized, no codes
48 const ANONYMIZE_CODE_ALL = 3; // personalized, codes
49
52
53 // constants to define the print view values.
54 const PRINT_HIDE_LABELS = 1; // Show only the titles in "print" and "PDF Export"
55 const PRINT_SHOW_LABELS = 3; // Show titles and labels in "print" and "PDF Export"
56
63 public $survey_id;
64
71 public $author;
72
79
85 public $outro;
86
92 public $status;
93
100
107
113 public $end_date;
114
121
128
135
141
147
154
160
164 protected $log;
165
169
170 // 360°
171 protected $mode_360; // [bool]
172 protected $mode_360_self_eval; // [bool]
173 protected $mode_360_self_appr; // [bool]
174 protected $mode_360_self_rate; // [bool]
175 protected $mode_360_results; // [int]
176 protected $mode_360_skill_service; // [bool]
177
181
182 // reminder/notification
183 protected $reminder_status; // [bool]
184 protected $reminder_start; // [ilDate]
185 protected $reminder_end; // [ilDate]
186 protected $reminder_frequency; // [int]
187 protected $reminder_target; // [int]
188 protected $reminder_last_sent; // [bool]
189 protected $reminder_tmpl; // [int]
190 protected $tutor_ntf_status; // [bool]
191 protected $tutor_ntf_recipients; // [array]
192 protected $tutor_ntf_target; // [int]
193
194 protected $view_own_results; // [bool]
195 protected $mail_own_results; // [bool]
196 protected $mail_confirmation; // [bool]
197
198 protected $anon_user_list; // [bool]
199
205
206
213 public function __construct($a_id = 0, $a_call_by_reference = true)
214 {
215 global $DIC;
216
217 $this->user = $DIC->user();
218 $this->lng = $DIC->language();
219 $this->db = $DIC->database();
220 $this->access = $DIC->access();
221 $this->log = $DIC["ilLog"];
222 $this->plugin_admin = $DIC["ilPluginAdmin"];
223 $this->tree = $DIC->repositoryTree();
224 $ilUser = $DIC->user();
225 $lng = $DIC->language();
226
227 $this->type = "svy";
228 $this->survey_id = -1;
229 $this->introduction = "";
230 $this->outro = $lng->txt("survey_finished");
231 $this->author = $ilUser->getFullname();
232 $this->status = self::STATUS_OFFLINE;
233 $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
234 $this->questions = array();
235 $this->invitation = self::INVITATION_OFF;
236 $this->invitation_mode = self::MODE_PREDEFINED_USERS;
237 $this->anonymize = self::ANONYMIZE_OFF;
238 $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
239 $this->surveyCodeSecurity = true;
240 $this->template_id = null;
241 $this->pool_usage = true;
242 $this->log = ilLoggerFactory::getLogger("svy");
243
244 parent::__construct($a_id, $a_call_by_reference);
245 }
246
250 public function create($a_upload = false)
251 {
252 parent::create();
253 if (!$a_upload) {
254 $this->createMetaData();
255 }
256 }
257
263 public function createMetaData()
264 {
265 parent::createMetaData();
266 $this->saveAuthorToMetadata();
267 }
268
275 public function update()
276 {
277 $this->updateMetaData();
278
279 if (!parent::update()) {
280 return false;
281 }
282
283 // put here object specific stuff
284
285 return true;
286 }
287
288 public function createReference()
289 {
290 $result = parent::createReference();
291 $this->saveToDb();
292 return $result;
293 }
294
299 public function read()
300 {
301 parent::read();
302 $this->loadFromDb();
303 }
304
311 public function addQuestion($question_id)
312 {
313 array_push($this->questions, $question_id);
314 }
315
322 public function delete()
323 {
324 if ($this->countReferences() == 1) {
325 $this->deleteMetaData();
326
327 // Delete all survey questions, constraints and materials
328 foreach ($this->questions as $question_id) {
329 $this->removeQuestion($question_id);
330 }
331 $this->deleteSurveyRecord();
332
334 }
335
336 $remove = parent::delete();
337
338 // always call parent delete function first!!
339 if (!$remove) {
340 return false;
341 }
342 return true;
343 }
344
350 public function deleteSurveyRecord()
351 {
353
354 $affectedRows = $ilDB->manipulateF(
355 "DELETE FROM svy_svy WHERE survey_id = %s",
356 array('integer'),
357 array($this->getSurveyId())
358 );
359
360 $result = $ilDB->queryF(
361 "SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
362 array('integer'),
363 array($this->getSurveyId())
364 );
365 $questionblocks = array();
366 while ($row = $ilDB->fetchAssoc($result)) {
367 array_push($questionblocks, $row["questionblock_fi"]);
368 }
369 if (count($questionblocks)) {
370 $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
371 }
372 $affectedRows = $ilDB->manipulateF(
373 "DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
374 array('integer'),
375 array($this->getSurveyId())
376 );
377 $this->deleteAllUserData();
378
379 $affectedRows = $ilDB->manipulateF(
380 "DELETE FROM svy_anonymous WHERE survey_fi = %s",
381 array('integer'),
382 array($this->getSurveyId())
383 );
384
385 // delete export files
386 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
387 $directory = $svy_data_dir . "/svy_" . $this->getId();
388 if (is_dir($directory)) {
389 ilUtil::delDir($directory);
390 }
391
392 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
393 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
394 // remaining usages are not in text anymore -> delete them
395 // and media objects (note: delete method of ilObjMediaObject
396 // checks whether object is used in another context; if yes,
397 // the object is not deleted!)
398 foreach ($mobs as $mob) {
399 ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
400 $mob_obj = new ilObjMediaObject($mob);
401 $mob_obj->delete();
402 }
403 }
404
410 public function deleteAllUserData()
411 {
413
414 $result = $ilDB->queryF(
415 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
416 array('integer'),
417 array($this->getSurveyId())
418 );
419 $active_array = array();
420 while ($row = $ilDB->fetchAssoc($result)) {
421 array_push($active_array, $row["finished_id"]);
422 }
423
424 $affectedRows = $ilDB->manipulateF(
425 "DELETE FROM svy_finished WHERE survey_fi = %s",
426 array('integer'),
427 array($this->getSurveyId())
428 );
429
430 foreach ($active_array as $active_fi) {
431 $affectedRows = $ilDB->manipulateF(
432 "DELETE FROM svy_answer WHERE active_fi = %s",
433 array('integer'),
434 array($active_fi)
435 );
436 $affectedRows = $ilDB->manipulateF(
437 "DELETE FROM svy_times WHERE finished_fi = %s",
438 array('integer'),
439 array($active_fi)
440 );
441 }
442
443 include_once "Services/Object/classes/class.ilObjectLP.php";
444 $lp_obj = ilObjectLP::getInstance($this->getId());
445 $lp_obj->resetLPDataForCompleteObject();
446 }
447
453 public function removeSelectedSurveyResults($finished_ids)
454 {
456
457 $user_ids[] = array();
458
459 foreach ($finished_ids as $finished_id) {
460 $result = $ilDB->queryF(
461 "SELECT finished_id FROM svy_finished WHERE finished_id = %s",
462 array('integer'),
463 array($finished_id)
464 );
465 $row = $ilDB->fetchAssoc($result);
466
467 if ($row["user_fi"]) {
468 $user_ids[] = $row["user_fi"];
469 }
470
471 $affectedRows = $ilDB->manipulateF(
472 "DELETE FROM svy_answer WHERE active_fi = %s",
473 array('integer'),
474 array($row["finished_id"])
475 );
476
477 $affectedRows = $ilDB->manipulateF(
478 "DELETE FROM svy_finished WHERE finished_id = %s",
479 array('integer'),
480 array($finished_id)
481 );
482
483 $affectedRows = $ilDB->manipulateF(
484 "DELETE FROM svy_times WHERE finished_fi = %s",
485 array('integer'),
486 array($row["finished_id"])
487 );
488 }
489
490 if (sizeof($user_ids)) {
491 include_once "Services/Object/classes/class.ilObjectLP.php";
492 $lp_obj = ilObjectLP::getInstance($this->getId());
493 $lp_obj->resetLPDataForUserIds($user_ids);
494 }
495 }
496
497 public function &getSurveyParticipants($finished_ids = null, $force_non_anonymous = false)
498 {
500
501 $sql = "SELECT * FROM svy_finished" .
502 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
503 if ($finished_ids) {
504 $sql .= " AND " . $ilDB->in("finished_id", $finished_ids, "", "integer");
505 }
506
507 $result = $ilDB->query($sql);
508 $participants = array();
509 if ($result->numRows() > 0) {
510 while ($row = $ilDB->fetchAssoc($result)) {
511 $userdata = $this->getUserDataFromActiveId($row["finished_id"], $force_non_anonymous);
512 $userdata["finished"] = (bool) $row["state"];
513 $userdata["finished_tstamp"] = $row["tstamp"];
514 $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
515 }
516 }
517 return $participants;
518 }
519
526 public function isComplete()
527 {
528 if (($this->getTitle()) and (count($this->questions))) {
529 return 1;
530 } else {
531 return 0;
532 }
533 }
534
540 public function saveCompletionStatus()
541 {
543
544 $complete = 0;
545 if ($this->isComplete()) {
546 $complete = 1;
547 }
548 if ($this->getSurveyId() > 0) {
549 $affectedRows = $ilDB->manipulateF(
550 "UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
551 array('text','integer','integer'),
552 array($this->isComplete(), time(), $this->getSurveyId())
553 );
554 }
555 }
556
564 public function duplicateQuestionForSurvey($question_id, $a_force = false)
565 {
567
568 $questiontype = $this->getQuestionType($question_id);
569 $question_gui = $this->getQuestionGUI($questiontype, $question_id);
570
571 // check if question is a pool question at all, if not do nothing
572 if ($this->getId() == $question_gui->object->getObjId() && !$a_force) {
573 return $question_id;
574 }
575
576 $duplicate_id = $question_gui->object->duplicate(true, "", "", "", $this->getId());
577 return $duplicate_id;
578 }
579
585 public function insertQuestion($question_id)
586 {
588
589 $this->log->debug("insert question, id:" . $question_id);
590
591 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
592 if (!SurveyQuestion::_isComplete($question_id)) {
593 $this->log->debug("question is not complete");
594 return false;
595 } else {
596 // get maximum sequence index in test
597 // @todo: refactor this
598 $result = $ilDB->queryF(
599 "SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
600 array('integer'),
601 array($this->getSurveyId())
602 );
603 $sequence = $result->numRows();
604 $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
605 $this->log->debug("duplicate, id: " . $question_id . ", duplicate id: " . $duplicate_id);
606
607 // check if question is not already in the survey, see #22018
608 if ($this->isQuestionInSurvey($duplicate_id)) {
609 return false;
610 }
611
612 $next_id = $ilDB->nextId('svy_svy_qst');
613 $affectedRows = $ilDB->manipulateF(
614 "INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
615 array('integer', 'integer', 'integer', 'integer', 'integer'),
616 array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
617 );
618
619 $this->log->debug("added entry to svy_svy_qst, id: " . $next_id . ", question id: " . $duplicate_id . ", sequence: " . $sequence);
620
621 $this->loadQuestionsFromDb();
622 return true;
623 }
624 }
625
632 public function isQuestionInSurvey($a_question_fi)
633 {
634 global $DIC;
635 //return false;
636 $ilDB = $DIC->database();
637
638 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
639 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
640 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
641 if ($rec = $ilDB->fetchAssoc($set)) {
642 return true;
643 }
644 return false;
645 }
646
647
648
654 public function insertQuestionblock($questionblock_id)
655 {
657 $result = $ilDB->queryF(
658 "SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle," .
659 " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst" .
660 " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi" .
661 " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi" .
662 " AND svy_qblk.questionblock_id = %s" .
663 " ORDER BY svy_svy_qst.sequence",
664 array('integer'),
665 array($questionblock_id)
666 );
667 $questions = array();
668 $show_questiontext = 0;
669 $show_blocktitle = 0;
670 while ($row = $ilDB->fetchAssoc($result)) {
671 $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
672 array_push($questions, $duplicate_id);
673 $title = $row["title"];
674 $show_questiontext = $row["show_questiontext"];
675 $show_blocktitle = $row["show_blocktitle"];
676 }
677 $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
678 }
679
680 public function saveUserSettings($usr_id, $key, $title, $value)
681 {
683
684 $next_id = $ilDB->nextId('svy_settings');
685 $affectedRows = $ilDB->insert("svy_settings", array(
686 "settings_id" => array("integer", $next_id),
687 "usr_id" => array("integer", $usr_id),
688 "keyword" => array("text", $key),
689 "title" => array("text", $title),
690 "value" => array("clob", $value)
691 ));
692 }
693
694 public function deleteUserSettings($id)
695 {
697
698 $affectedRows = $ilDB->manipulateF(
699 "DELETE FROM svy_settings WHERE settings_id = %s",
700 array('integer'),
701 array($id)
702 );
703 return $affectedRows;
704 }
705
706 public function getUserSettings($usr_id, $key)
707 {
709
710 $result = $ilDB->queryF(
711 "SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
712 array('integer', 'text'),
713 array($usr_id, $key)
714 );
715 $found = array();
716 if ($result->numRows()) {
717 while ($row = $ilDB->fetchAssoc($result)) {
718 $found[$row['settings_id']] = $row;
719 }
720 }
721 return $found;
722 }
723
729 public function saveToDb()
730 {
732
733 // date handling
734 $rmd_start = $this->getReminderStart();
735 if (is_object($rmd_start)) {
736 $rmd_start = $rmd_start->get(IL_CAL_DATE);
737 }
738 $rmd_end = $this->getReminderEnd();
739 if (is_object($rmd_end)) {
740 $rmd_end = $rmd_end->get(IL_CAL_DATE);
741 }
742
743 include_once("./Services/RTE/classes/class.ilRTE.php");
744 if ($this->getSurveyId() < 1) {
745 $next_id = $ilDB->nextId('svy_svy');
746 $affectedRows = $ilDB->insert("svy_svy", array(
747 "survey_id" => array("integer", $next_id),
748 "obj_fi" => array("integer", $this->getId()),
749 "author" => array("text", $this->getAuthor()),
750 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
751 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
752 "status" => array("text", $this->getStatus()),
753 "startdate" => array("text", $this->getStartDate()),
754 "enddate" => array("text", $this->getEndDate()),
755 "evaluation_access" => array("text", $this->getEvaluationAccess()),
756 "invitation" => array("text", $this->getInvitation()),
757 "invitation_mode" => array("text", $this->getInvitationMode()),
758 "complete" => array("text", $this->isComplete()),
759 "created" => array("integer", time()),
760 "anonymize" => array("text", $this->getAnonymize()),
761 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
762 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
763 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
764 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
765 "tstamp" => array("integer", time()),
766 "template_id" => array("integer", $this->getTemplate()),
767 "pool_usage" => array("integer", $this->getPoolUsage()),
768 // 360°
769 "mode_360" => array("integer", $this->get360Mode()),
770 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
771 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
772 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
773 "mode_360_results" => array("integer", $this->get360Results()),
774 "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
775 // reminder/notification
776 "reminder_status" => array("integer", (int) $this->getReminderStatus()),
777 "reminder_start" => array("datetime", $rmd_start),
778 "reminder_end" => array("datetime", $rmd_end),
779 "reminder_frequency" => array("integer", (int) $this->getReminderFrequency()),
780 "reminder_target" => array("integer", (int) $this->getReminderTarget()),
781 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
782 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
783 "tutor_ntf_status" => array("integer", (int) $this->getTutorNotificationStatus()),
784 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
785 "tutor_ntf_target" => array("integer", (int) $this->getTutorNotificationTarget()),
786 "own_results_view" => array("integer", $this->hasViewOwnResults()),
787 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
788 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
789 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
790 ));
791 $this->setSurveyId($next_id);
792 } else {
793 $affectedRows = $ilDB->update("svy_svy", array(
794 "author" => array("text", $this->getAuthor()),
795 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
796 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
797 "status" => array("text", $this->getStatus()),
798 "startdate" => array("text", $this->getStartDate()),
799 "enddate" => array("text", $this->getEndDate()),
800 "evaluation_access" => array("text", $this->getEvaluationAccess()),
801 "invitation" => array("text", $this->getInvitation()),
802 "invitation_mode" => array("text", $this->getInvitationMode()),
803 "complete" => array("text", $this->isComplete()),
804 "anonymize" => array("text", $this->getAnonymize()),
805 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
806 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
807 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
808 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
809 "tstamp" => array("integer", time()),
810 "template_id" => array("integer", $this->getTemplate()),
811 "pool_usage" => array("integer", $this->getPoolUsage()),
812 // 360°
813 "mode_360" => array("integer", $this->get360Mode()),
814 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
815 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
816 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
817 "mode_360_results" => array("integer", $this->get360Results()),
818 "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
819 // reminder/notification
820 "reminder_status" => array("integer", $this->getReminderStatus()),
821 "reminder_start" => array("datetime", $rmd_start),
822 "reminder_end" => array("datetime", $rmd_end),
823 "reminder_frequency" => array("integer", $this->getReminderFrequency()),
824 "reminder_target" => array("integer", $this->getReminderTarget()),
825 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
826 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
827 "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
828 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
829 "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget()),
830 "own_results_view" => array("integer", $this->hasViewOwnResults()),
831 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
832 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
833 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
834 ), array(
835 "survey_id" => array("integer", $this->getSurveyId())
836 ));
837 }
838 if ($affectedRows) {
839 // save questions to db
840 $this->saveQuestionsToDb();
841 }
842
843 // moved activation to ilObjectActivation
844 if ($this->ref_id) {
845 include_once "./Services/Object/classes/class.ilObjectActivation.php";
846 ilObjectActivation::getItem($this->ref_id);
847
848 $item = new ilObjectActivation;
849 if (!$this->isActivationLimited()) {
851 } else {
852 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
853 $item->setTimingStart($this->getActivationStartDate());
854 $item->setTimingEnd($this->getActivationEndDate());
855 $item->toggleVisible($this->getActivationVisibility());
856 }
857
858 $item->update($this->ref_id);
859 }
860 }
861
868 public function saveQuestionsToDb()
869 {
871
872 $this->log->debug("save questions");
873
874 // gather old questions state
875 $old_questions = array();
876 $result = $ilDB->queryF(
877 "SELECT survey_question_id,question_fi,sequence" .
878 " FROM svy_svy_qst WHERE survey_fi = %s",
879 array('integer'),
880 array($this->getSurveyId())
881 );
882 while ($row = $ilDB->fetchAssoc($result)) {
883 $old_questions[$row["question_fi"]] = $row; // problem, as soon as duplicates exist, they will be hidden here
884 }
885
886 // #15231 - diff with current questions state
887 $insert = $update = $delete = array();
888 foreach ($this->questions as $seq => $fi) {
889 if (!array_key_exists($fi, $old_questions)) { // really new fi IDs
890 $insert[] = $fi; // this should be ok, should not create duplicates here
891 } elseif ($old_questions[$fi]["sequence"] != $seq) { // we are updating one of the duplicates (if any)
892 $update[$fi] = $old_questions[$fi]["survey_question_id"];
893 }
894 // keep track of still relevant questions
895 unset($old_questions[$fi]); // deleting old question, if they are not in current array
896 }
897
898 // delete obsolete question relations
899 if (sizeof($old_questions)) {
900 $del_ids = array();
901 foreach ($old_questions as $fi => $old) {
902 $del_ids[] = $old["survey_question_id"];
903 }
904 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
905 " WHERE " . $ilDB->in("survey_question_id", $del_ids, "", "integer"));
906 $this->log->debug("delete: " . $q);
907 }
908 unset($old_questions);
909
910 // create/update question relations
911 foreach ($this->questions as $seq => $fi) {
912 if (in_array($fi, $insert)) {
913 // check if question is not already in the survey, see #22018
914 if (!$this->isQuestionInSurvey($fi)) {
915 $next_id = $ilDB->nextId('svy_svy_qst');
916 $ilDB->manipulateF(
917 "INSERT INTO svy_svy_qst" .
918 " (survey_question_id, survey_fi, question_fi, heading, sequence, tstamp)" .
919 " VALUES (%s, %s, %s, %s, %s, %s)",
920 array('integer', 'integer', 'integer', 'text', 'integer', 'integer'),
921 array($next_id, $this->getSurveyId(), $fi, null, $seq, time())
922 );
923 $this->log->debug("insert svy_svy_qst, id:" . $next_id . ", fi: " . $fi . ", seq:" . $seq);
924 }
925 } elseif (array_key_exists($fi, $update)) {
926 $ilDB->manipulate("UPDATE svy_svy_qst" .
927 " SET sequence = " . $ilDB->quote($seq, "integer") .
928 ", tstamp = " . $ilDB->quote(time(), "integer") .
929 " WHERE survey_question_id = " . $ilDB->quote($update[$fi], "integer"));
930 $this->log->debug("update svy_svy_qst, id:" . $update[$fi] . ", fi: " . $fi . ", seq:" . $seq);
931 }
932 }
933 }
934
942 public function getAnonymousId($id)
943 {
945 $result = $ilDB->queryF(
946 "SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
947 array('text'),
948 array($id)
949 );
950 if ($result->numRows()) {
951 $row = $ilDB->fetchAssoc($result);
952 return $row["anonymous_id"];
953 } else {
954 return "";
955 }
956 }
957
964 public function getQuestionGUI($questiontype, $question_id)
965 {
966 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestionGUI.php";
967 return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
968 }
969
977 public function getQuestionType($question_id)
978 {
980 if ($question_id < 1) {
981 return -1;
982 }
983 $result = $ilDB->queryF(
984 "SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
985 "svy_question.questiontype_fi = svy_qtype.questiontype_id",
986 array('integer'),
987 array($question_id)
988 );
989 if ($result->numRows() == 1) {
990 $data = $ilDB->fetchAssoc($result);
991 return $data["type_tag"];
992 } else {
993 return "";
994 }
995 }
996
1003 public function getSurveyId()
1004 {
1005 return $this->survey_id;
1006 }
1007
1011 public function setAnonymize($a_anonymize)
1012 {
1013 switch ($a_anonymize) {
1015 case self::ANONYMIZE_ON:
1018 $this->anonymize = $a_anonymize;
1019 break;
1020 default:
1021 $this->anonymize = self::ANONYMIZE_OFF;
1022 break;
1023 }
1024 }
1025
1031 public function getAnonymize()
1032 {
1033 return ($this->anonymize) ? $this->anonymize : 0;
1034 }
1035
1041 public function isAccessibleWithoutCode()
1042 {
1043 return ($this->getAnonymize() == self::ANONYMIZE_OFF ||
1044 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1045 }
1046
1052 public function hasAnonymizedResults()
1053 {
1054 return ($this->getAnonymize() == self::ANONYMIZE_ON ||
1055 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1056 }
1057
1063 public function loadFromDb()
1064 {
1065 $ilDB = $this->db;
1066 $result = $ilDB->queryF(
1067 "SELECT * FROM svy_svy WHERE obj_fi = %s",
1068 array('integer'),
1069 array($this->getId())
1070 );
1071 if ($result->numRows() == 1) {
1072 $data = $ilDB->fetchAssoc($result);
1073 $this->setSurveyId($data["survey_id"]);
1074 $this->setAuthor($data["author"]);
1075 include_once("./Services/RTE/classes/class.ilRTE.php");
1076 $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1077 if (strcmp($data["outro"], "survey_finished") == 0) {
1078 $this->setOutro($this->lng->txt("survey_finished"));
1079 } else {
1081 }
1082 $this->setInvitation($data["invitation"]);
1083 $this->setInvitationMode($data["invitation_mode"]);
1084 $this->setShowQuestionTitles($data["show_question_titles"]);
1085 $this->setStartDate($data["startdate"]);
1086 $this->setEndDate($data["enddate"]);
1087 $this->setAnonymize($data["anonymize"]);
1088 $this->setEvaluationAccess($data["evaluation_access"]);
1089 $this->loadQuestionsFromDb();
1090 $this->setStatus($data["status"]);
1091 $this->setMailNotification($data['mailnotification']);
1092 $this->setMailAddresses($data['mailaddresses']);
1093 $this->setMailParticipantData($data['mailparticipantdata']);
1094 $this->setTemplate($data['template_id']);
1095 $this->setPoolUsage($data['pool_usage']);
1096 // 360°
1097 $this->set360Mode($data['mode_360']);
1098 $this->set360SelfEvaluation($data['mode_360_self_eval']);
1099 $this->set360SelfRaters($data['mode_360_self_rate']);
1100 $this->set360SelfAppraisee($data['mode_360_self_appr']);
1101 $this->set360Results($data['mode_360_results']);
1102 $this->set360SkillService($data['mode_360_skill_service']);
1103 // reminder/notification
1104 $this->setReminderStatus($data["reminder_status"]);
1105 $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1106 $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1107 $this->setReminderFrequency($data["reminder_frequency"]);
1108 $this->setReminderTarget($data["reminder_target"]);
1109 $this->setReminderLastSent($data["reminder_last_sent"]);
1110 $this->setReminderTemplate($data["reminder_tmpl"]);
1111 $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1112 $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1113 $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1114
1115 $this->setViewOwnResults($data["own_results_view"]);
1116 $this->setMailOwnResults($data["own_results_mail"]);
1117 $this->setMailConfirmation($data["confirmation_mail"]);
1118
1119 $this->setAnonymousUserList($data["anon_user_list"]);
1120 }
1121
1122 // moved activation to ilObjectActivation
1123 if ($this->ref_id) {
1124 include_once "./Services/Object/classes/class.ilObjectActivation.php";
1125 $activation = ilObjectActivation::getItem($this->ref_id);
1126 switch ($activation["timing_type"]) {
1128 $this->setActivationLimited(true);
1129 $this->setActivationStartDate($activation["timing_start"]);
1130 $this->setActivationEndDate($activation["timing_end"]);
1131 $this->setActivationVisibility($activation["visible"]);
1132 break;
1133
1134 default:
1135 $this->setActivationLimited(false);
1136 break;
1137 }
1138 }
1139 }
1140
1147 public function loadQuestionsFromDb()
1148 {
1149 $ilDB = $this->db;
1150 $this->questions = array();
1151 $result = $ilDB->queryF(
1152 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1153 array('integer'),
1154 array($this->getSurveyId())
1155 );
1156 while ($data = $ilDB->fetchAssoc($result)) {
1157 $this->questions[$data["sequence"]] = $data["question_fi"];
1158 }
1159 }
1160
1164 public function fixSequenceStructure()
1165 {
1166 global $DIC;
1167
1168 $ilDB = $DIC->database();
1169 //return;
1170 // we keep all survey question ids with their lowest sequence
1171 $result = $ilDB->queryF(
1172 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1173 array('integer'),
1174 array($this->getSurveyId())
1175 );
1176
1177 // step 1: find duplicates -> $to_delete_ids
1178 $fis = array();
1179 $to_delete_ids = array();
1180 while ($data = $ilDB->fetchAssoc($result)) {
1181 if (in_array($data["question_fi"], $fis)) { // found a duplicate
1182 $to_delete_ids[] = $data["survey_question_id"];
1183 } else {
1184 $fis[] = $data["question_fi"];
1185 }
1186 }
1187
1188 // step 2: we delete the duplicates
1189 if (count($to_delete_ids) > 0) {
1190 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
1191 " WHERE " . $ilDB->in("survey_question_id", $to_delete_ids, false, "integer") .
1192 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1193 $this->log->debug("delete: " . $q);
1194
1195 $ilDB->manipulate($q = "DELETE FROM svy_qblk_qst " .
1196 " WHERE " . $ilDB->in("question_fi", $fis, true, "integer") .
1197 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1198 $this->log->debug("delete: " . $q);
1199 }
1200
1201 // step 3: we fix the sequence
1202 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
1203 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") . " ORDER BY sequence");
1204 $seq = 0;
1205 while ($rec = $ilDB->fetchAssoc($set)) {
1206 $ilDB->manipulate(
1207 $q = "UPDATE svy_svy_qst SET " .
1208 " sequence = " . $ilDB->quote($seq++, "integer") .
1209 " WHERE survey_question_id = " . $ilDB->quote($rec["survey_question_id"], "integer")
1210 );
1211 $this->log->debug("update: " . $q);
1212 }
1213 }
1214
1215
1223 public function setAuthor($author = "")
1224 {
1225 $this->author = $author;
1226 }
1227
1237 public function saveAuthorToMetadata($a_author = "")
1238 {
1239 $md = new ilMD($this->getId(), 0, $this->getType());
1240 $md_life =&$md->getLifecycle();
1241 if (!$md_life) {
1242 if (strlen($a_author) == 0) {
1244 $a_author = $ilUser->getFullname();
1245 }
1246
1247 $md_life =&$md->addLifecycle();
1248 $md_life->save();
1249 $con =&$md_life->addContribute();
1250 $con->setRole("Author");
1251 $con->save();
1252 $ent =&$con->addEntity();
1253 $ent->setEntity($a_author);
1254 $ent->save();
1255 }
1256 }
1257
1265 public function getAuthor()
1266 {
1267 $author = array();
1268 include_once "./Services/MetaData/classes/class.ilMD.php";
1269 $md = new ilMD($this->getId(), 0, $this->getType());
1270 $md_life =&$md->getLifecycle();
1271 if ($md_life) {
1272 $ids =&$md_life->getContributeIds();
1273 foreach ($ids as $id) {
1274 $md_cont =&$md_life->getContribute($id);
1275 if (strcmp($md_cont->getRole(), "Author") == 0) {
1276 $entids =&$md_cont->getEntityIds();
1277 foreach ($entids as $entid) {
1278 $md_ent =&$md_cont->getEntity($entid);
1279 array_push($author, $md_ent->getEntity());
1280 }
1281 }
1282 }
1283 }
1284 return join($author, ",");
1285 }
1286
1293 public function getShowQuestionTitles()
1294 {
1295 return ($this->display_question_titles) ? 1 : 0;
1296 }
1297
1304 public function setShowQuestionTitles($a_show)
1305 {
1306 $this->display_question_titles = ($a_show) ? 1 : 0;
1307 }
1308
1315 public function showQuestionTitles()
1316 {
1317 $this->display_question_titles = 1;
1318 }
1319
1326 public function hideQuestionTitles()
1327 {
1328 $this->display_question_titles = 0;
1329 }
1330
1338 public function setInvitation($invitation = 0)
1339 {
1340 $ilDB = $this->db;
1341 $ilAccess = $this->access;
1342
1343 $this->invitation = $invitation;
1345 $this->disinviteAllUsers();
1346 } elseif ($invitation == self::INVITATION_ON) {
1347 if ($this->getInvitationMode() == self::MODE_UNLIMITED) {
1348 $result = $ilDB->query("SELECT usr_id FROM usr_data");
1349 while ($row = $ilDB->fetchAssoc($result)) {
1350 if ($ilAccess->checkAccessOfUser($row["usr_id"], "read", "", $this->getRefId(), "svy", $this->getId())) {
1351 $this->inviteUser($row['usr_id']);
1352 }
1353 }
1354 }
1355 }
1356 }
1357
1366 {
1367 $this->invitation_mode = $invitation_mode;
1368 }
1369
1379 {
1380 $this->invitation_mode = $invitation_mode;
1381 $this->setInvitation($invitation);
1382 }
1383
1390 public function setIntroduction($introduction = "")
1391 {
1392 $this->introduction = $introduction;
1393 }
1394
1401 public function setOutro($outro = "")
1402 {
1403 $this->outro = $outro;
1404 }
1405
1413 public function getInvitation()
1414 {
1415 return ($this->invitation) ? $this->invitation : self::INVITATION_OFF;
1416 }
1417
1425 public function getInvitationMode()
1426 {
1427 include_once "./Services/Administration/classes/class.ilSetting.php";
1428 $surveySetting = new ilSetting("survey");
1429 $unlimited_invitation = $surveySetting->get("unlimited_invitation");
1430 if (!$unlimited_invitation && $this->invitation_mode == self::MODE_UNLIMITED) {
1432 } else {
1433 return ($this->invitation_mode) ? $this->invitation_mode : self::MODE_UNLIMITED;
1434 }
1435 }
1436
1444 public function getStatus()
1445 {
1446 return ($this->status) ? $this->status : self::STATUS_OFFLINE;
1447 }
1448
1456 public function isOnline()
1457 {
1458 return ($this->status == self::STATUS_ONLINE) ? true : false;
1459 }
1460
1468 public function isOffline()
1469 {
1470 return ($this->status == self::STATUS_OFFLINE) ? true : false;
1471 }
1472
1481 public function setStatus($status = self::STATUS_OFFLINE)
1482 {
1483 $result = "";
1484 if (($status == self::STATUS_ONLINE) && (count($this->questions) == 0)) {
1485 $this->status = self::STATUS_OFFLINE;
1486 $result = $this->lng->txt("cannot_switch_to_online_no_questions");
1487 } else {
1488 $this->status = $status;
1489 }
1490 return $result;
1491 }
1492
1500 public function getStartDate()
1501 {
1502 return (strlen($this->start_date)) ? $this->start_date : null;
1503 }
1504
1511 public function canStartSurvey($anonymous_id = null, $a_no_rbac = false)
1512 {
1513 $ilAccess = $this->access;
1514
1515 $result = true;
1516 $messages = array();
1517 $edit_settings = false;
1518 // check start date
1519 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches)) {
1520 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1521 $now = time();
1522 if ($now < $epoch_time) {
1523 array_push($messages, $this->lng->txt('start_date_not_reached') . ' (' .
1525 $result = false;
1526 $edit_settings = true;
1527 }
1528 }
1529 // check end date
1530 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches)) {
1531 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1532 $now = time();
1533 if ($now > $epoch_time) {
1534 array_push($messages, $this->lng->txt('end_date_reached') . ' (' .
1536 $result = false;
1537 $edit_settings = true;
1538 }
1539 }
1540
1541 // check online status
1542 if ($this->getStatus() == self::STATUS_OFFLINE) {
1543 array_push($messages, $this->lng->txt("survey_is_offline"));
1544 $result = false;
1545 $edit_settings = true;
1546 }
1547 // check rbac permissions
1548 if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id)) {
1549 array_push($messages, $this->lng->txt("cannot_participate_survey"));
1550 $result = false;
1551 }
1552 /*
1553 // 2. check previous access
1554 if (!$result["error"])
1555 {
1556 $ilUser = $this->user;
1557 $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1558 if ($survey_started === 1)
1559 {
1560 array_push($messages, $this->lng->txt("already_completed_survey"));
1561 $result = FALSE;
1562 }
1563 }
1564 */
1565 return array(
1566 "result" => $result,
1567 "messages" => $messages,
1568 "edit_settings" => $edit_settings
1569 );
1570 }
1571
1579 public function setStartDate($start_date = "")
1580 {
1581 $this->start_date = $start_date;
1582 }
1583
1592 public function setStartDateAndTime($start_date = "", $start_time)
1593 {
1594 $y = '';
1595 $m = '';
1596 $d = '';
1597 $h = '';
1598 $i = '';
1599 $s = '';
1600 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches)) {
1601 $y = $matches[1];
1602 $m = $matches[2];
1603 $d = $matches[3];
1604 }
1605 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches)) {
1606 $h = $matches[1];
1607 $i = $matches[2];
1608 $s = $matches[3];
1609 }
1610 $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1611 }
1612
1620 public function getEndDate()
1621 {
1622 return (strlen($this->end_date)) ? $this->end_date : null;
1623 }
1624
1632 public function setEndDate($end_date = "")
1633 {
1634 $this->end_date = $end_date;
1635 }
1636
1645 public function setEndDateAndTime($end_date = "", $end_time)
1646 {
1647 $y = '';
1648 $m = '';
1649 $d = '';
1650 $h = '';
1651 $i = '';
1652 $s = '';
1653 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches)) {
1654 $y = $matches[1];
1655 $m = $matches[2];
1656 $d = $matches[3];
1657 }
1658 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches)) {
1659 $h = $matches[1];
1660 $i = $matches[2];
1661 $s = $matches[3];
1662 }
1663 $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1664 }
1665
1673 public function getEvaluationAccess()
1674 {
1675 return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1676 }
1677
1685 public function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1686 {
1687 $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1688 }
1689
1690 public function setActivationVisibility($a_value)
1691 {
1692 $this->activation_visibility = (bool) $a_value;
1693 }
1694
1695 public function getActivationVisibility()
1696 {
1698 }
1699
1700 public function isActivationLimited()
1701 {
1702 return (bool) $this->activation_limited;
1703 }
1704
1705 public function setActivationLimited($a_value)
1706 {
1707 $this->activation_limited = (bool) $a_value;
1708 }
1709
1717 public function getIntroduction()
1718 {
1719 return (strlen($this->introduction)) ? $this->introduction : null;
1720 }
1721
1729 public function getOutro()
1730 {
1731 return (strlen($this->outro)) ? $this->outro : null;
1732 }
1733
1740 public function &getExistingQuestions()
1741 {
1742 $ilDB = $this->db;
1743 $existing_questions = array();
1744 $result = $ilDB->queryF(
1745 "SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1746 "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1747 array('integer'),
1748 array($this->getSurveyId())
1749 );
1750 while ($data = $ilDB->fetchAssoc($result)) {
1751 if ($data["original_id"]) {
1752 array_push($existing_questions, $data["original_id"]);
1753 }
1754 }
1755 return $existing_questions;
1756 }
1757
1764 public function &getQuestionpoolTitles($could_be_offline = false, $showPath = false)
1765 {
1766 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
1767 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = true, $could_be_offline, $showPath);
1768 }
1769
1778 public function moveQuestions($move_questions, $target_index, $insert_mode)
1779 {
1780 $array_pos = array_search($target_index, $this->questions);
1781 if ($insert_mode == 0) {
1782 $part1 = array_slice($this->questions, 0, $array_pos);
1783 $part2 = array_slice($this->questions, $array_pos);
1784 } elseif ($insert_mode == 1) {
1785 $part1 = array_slice($this->questions, 0, $array_pos + 1);
1786 $part2 = array_slice($this->questions, $array_pos + 1);
1787 }
1788 foreach ($move_questions as $question_id) {
1789 if (!(array_search($question_id, $part1) === false)) {
1790 unset($part1[array_search($question_id, $part1)]);
1791 }
1792 if (!(array_search($question_id, $part2) === false)) {
1793 unset($part2[array_search($question_id, $part2)]);
1794 }
1795 }
1796 $part1 = array_values($part1);
1797 $part2 = array_values($part2);
1798 $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1799 foreach ($move_questions as $question_id) {
1800 $constraints = $this->getConstraints($question_id);
1801 foreach ($constraints as $idx => $constraint) {
1802 foreach ($part2 as $next_question_id) {
1803 if ($constraint["question"] == $next_question_id) {
1804 // constraint concerning a question that follows -> delete constraint
1805 $this->deleteConstraint($constraint["id"]);
1806 }
1807 }
1808 }
1809 }
1810 $this->saveQuestionsToDb();
1811 }
1812
1819 public function removeQuestion($question_id)
1820 {
1821 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
1822 $question = self::_instanciateQuestion($question_id);
1823 #20610 if no question found, do nothing.
1824 if ($question) {
1825 $question->delete($question_id);
1826 $this->removeConstraintsConcerningQuestion($question_id);
1827 }
1828 }
1829
1836 public function removeConstraintsConcerningQuestion($question_id)
1837 {
1838 $ilDB = $this->db;
1839 $result = $ilDB->queryF(
1840 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1841 array('integer','integer'),
1842 array($question_id, $this->getSurveyId())
1843 );
1844 if ($result->numRows() > 0) {
1845 $remove_constraints = array();
1846 while ($row = $ilDB->fetchAssoc($result)) {
1847 array_push($remove_constraints, $row["constraint_fi"]);
1848 }
1849 $affectedRows = $ilDB->manipulateF(
1850 "DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1851 array('integer','integer'),
1852 array($question_id, $this->getSurveyId())
1853 );
1854 foreach ($remove_constraints as $key => $constraint_id) {
1855 $affectedRows = $ilDB->manipulateF(
1856 "DELETE FROM svy_constraint WHERE constraint_id = %s",
1857 array('integer'),
1858 array($constraint_id)
1859 );
1860 }
1861 }
1862 }
1863
1871 public function removeQuestions($remove_questions, $remove_questionblocks)
1872 {
1873 $ilDB = $this->db;
1874
1875 $block_sizes = array();
1876 foreach ($this->getSurveyQuestions() as $question_id => $data) {
1877 if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks)) {
1878 unset($this->questions[array_search($question_id, $this->questions)]);
1879 $this->removeQuestion($question_id);
1880 } elseif ($data["questionblock_id"]) {
1881 $block_sizes[$data["questionblock_id"]]++;
1882 }
1883 }
1884
1885 // blocks with just 1 question need to be deleted
1886 foreach ($block_sizes as $block_id => $size) {
1887 if ($size < 2) {
1888 $remove_questionblocks[] = $block_id;
1889 }
1890 }
1891
1892 foreach (array_unique($remove_questionblocks) as $questionblock_id) {
1893 $affectedRows = $ilDB->manipulateF(
1894 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1895 array('integer'),
1896 array($questionblock_id)
1897 );
1898 $affectedRows = $ilDB->manipulateF(
1899 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1900 array('integer','integer'),
1901 array($questionblock_id, $this->getSurveyId())
1902 );
1903 }
1904
1905 $this->questions = array_values($this->questions);
1906 $this->saveQuestionsToDb();
1907 }
1908
1915 public function unfoldQuestionblocks($questionblocks)
1916 {
1917 $ilDB = $this->db;
1918 foreach ($questionblocks as $index) {
1919 $affectedRows = $ilDB->manipulateF(
1920 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1921 array('integer'),
1922 array($index)
1923 );
1924 $affectedRows = $ilDB->manipulateF(
1925 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1926 array('integer','integer'),
1927 array($index, $this->getSurveyId())
1928 );
1929 }
1930 }
1931
1932 public function removeQuestionFromBlock($question_id, $questionblock_id)
1933 {
1934 $ilDB = $this->db;
1935
1936 $affectedRows = $ilDB->manipulateF(
1937 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
1938 array('integer','integer','integer'),
1939 array($questionblock_id, $this->getSurveyId(), $question_id)
1940 );
1941 }
1942
1943 public function addQuestionToBlock($question_id, $questionblock_id)
1944 {
1945 $ilDB = $this->db;
1946
1947 // see #22018
1948 if (!$this->isQuestionInAnyBlock($question_id)) {
1949 $next_id = $ilDB->nextId('svy_qblk_qst');
1950 $affectedRows = $ilDB->manipulateF(
1951 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
1952 "question_fi) VALUES (%s, %s, %s, %s)",
1953 array('integer', 'integer', 'integer', 'integer'),
1954 array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
1955 );
1956
1957 $this->deleteConstraints($question_id); // #13713
1958 }
1959 }
1960
1967 public function isQuestionInAnyBlock($a_question_fi)
1968 {
1969 global $DIC;
1970
1971 $ilDB = $DIC->database();
1972
1973 $set = $ilDB->query("SELECT * FROM svy_qblk_qst " .
1974 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
1975 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
1976 if ($rec = $ilDB->fetchAssoc($set)) {
1977 return true;
1978 }
1979 return false;
1980 }
1981
1982
1989 public function &getQuestionblockQuestions($questionblock_id)
1990 {
1991 $ilDB = $this->db;
1992 $titles = array();
1993 $result = $ilDB->queryF(
1994 "SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM " .
1995 "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
1996 "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
1997 array('integer'),
1998 array($questionblock_id)
1999 );
2000 $survey_id = "";
2001 while ($row = $ilDB->fetchAssoc($result)) {
2002 $titles[$row["question_fi"]] = $row["title"];
2003 $survey_id = $row["survey_fi"];
2004 }
2005 $result = $ilDB->queryF(
2006 "SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
2007 array('integer'),
2008 array($survey_id)
2009 );
2010 $resultarray = array();
2011 $counter = 1;
2012 while ($row = $ilDB->fetchAssoc($result)) {
2013 if (array_key_exists($row["question_fi"], $titles)) {
2014 $resultarray[$counter++] = $titles[$row["question_fi"]];
2015 }
2016 }
2017 return $resultarray;
2018 }
2019
2026 public function &getQuestionblockQuestionIds($questionblock_id)
2027 {
2028 $ilDB = $this->db;
2029
2030 // we need a correct order here, see #22011
2031 $result = $ilDB->queryF(
2032 "SELECT a.question_fi FROM svy_qblk_qst a JOIN svy_svy_qst b ON (a.question_fi = b.question_fi) " .
2033 " WHERE a.questionblock_fi = %s ORDER BY b.sequence",
2034 array("integer"),
2035 array($questionblock_id)
2036 );
2037 $ids = array();
2038 if ($result->numRows()) {
2039 while ($data = $ilDB->fetchAssoc($result)) {
2040 if (!in_array($data['question_fi'], $ids)) { // no duplicates, see #22018
2041 array_push($ids, $data['question_fi']);
2042 }
2043 }
2044 }
2045
2046 return $ids;
2047 }
2048
2056 public static function _getQuestionblock($questionblock_id)
2057 {
2058 global $DIC;
2059
2060 $ilDB = $DIC->database();
2061 $result = $ilDB->queryF(
2062 "SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2063 array('integer'),
2064 array($questionblock_id)
2065 );
2066 $row = $ilDB->fetchAssoc($result);
2067 return $row;
2068 }
2069
2078 public static function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false)
2079 {
2080 global $DIC;
2081
2082 $ilDB = $DIC->database();
2083 $next_id = $ilDB->nextId('svy_qblk');
2084 $ilDB->manipulateF(
2085 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
2086 " show_blocktitle, owner_fi, tstamp) " .
2087 "VALUES (%s, %s, %s, %s, %s, %s)",
2088 array('integer','text','integer','integer','integer','integer'),
2089 array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time())
2090 );
2091 return $next_id;
2092 }
2093
2101 public function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
2102 {
2103 $ilDB = $this->db;
2104
2105 // if the selected questions are not in a continous selection, move all questions of the
2106 // questionblock at the position of the first selected question
2107 $this->moveQuestions($questions, $questions[0], 0);
2108
2109 // now save the question block
2111 $next_id = $ilDB->nextId('svy_qblk');
2112 $affectedRows = $ilDB->manipulateF(
2113 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
2114 " show_blocktitle, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
2115 array('integer','text','text','text','integer','integer'),
2116 array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time())
2117 );
2118 if ($affectedRows) {
2119 $questionblock_id = $next_id;
2120 foreach ($questions as $index) {
2121 if (!$this->isQuestionInAnyBlock($index)) {
2122 $next_id = $ilDB->nextId('svy_qblk_qst'); // #22018
2123 $affectedRows = $ilDB->manipulateF(
2124 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2125 "question_fi) VALUES (%s, %s, %s, %s)",
2126 array('integer', 'integer', 'integer', 'integer'),
2127 array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2128 );
2129 $this->deleteConstraints($index);
2130 }
2131 }
2132 }
2133 }
2134
2142 public function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
2143 {
2144 $ilDB = $this->db;
2145 $affectedRows = $ilDB->manipulateF(
2146 "UPDATE svy_qblk SET title = %s, show_questiontext = %s," .
2147 " show_blocktitle = %s WHERE questionblock_id = %s",
2148 array('text','text','text','integer'),
2149 array($title, $show_questiontext, $show_blocktitle, $questionblock_id)
2150 );
2151 }
2152
2159 public function deleteConstraints($question_id)
2160 {
2161 $ilDB = $this->db;
2162 $result = $ilDB->queryF(
2163 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2164 array('integer','integer'),
2165 array($question_id, $this->getSurveyId())
2166 );
2167 $constraints = array();
2168 while ($row = $ilDB->fetchAssoc($result)) {
2169 array_push($constraints, $row["constraint_fi"]);
2170 }
2171 foreach ($constraints as $constraint_id) {
2172 $this->deleteConstraint($constraint_id);
2173 }
2174 }
2175
2183 public function deleteConstraint($constraint_id)
2184 {
2185 $ilDB = $this->db;
2186 $affectedRows = $ilDB->manipulateF(
2187 "DELETE FROM svy_constraint WHERE constraint_id = %s",
2188 array('integer'),
2189 array($constraint_id)
2190 );
2191 $affectedRows = $ilDB->manipulateF(
2192 "DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2193 array('integer'),
2194 array($constraint_id)
2195 );
2196 }
2197
2203 public function &getSurveyQuestions($with_answers = false)
2204 {
2205 $ilDB = $this->db;
2206 // get questionblocks
2207 $all_questions = array();
2208 $result = $ilDB->queryF(
2209 "SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, " .
2210 "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2211 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2212 "ORDER BY svy_svy_qst.sequence",
2213 array('integer'),
2214 array($this->getSurveyId())
2215 );
2216 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2217 while ($row = $ilDB->fetchAssoc($result)) {
2218 $add = true;
2219 if ($row["plugin"]) {
2220 if (!$this->isPluginActive($row["type_tag"])) {
2221 $add = false;
2222 }
2223 }
2224 if ($add) {
2225 $question = self::_instanciateQuestion($row["question_id"]);
2226 $questionrow = $question->getQuestionDataArray($row["question_id"]);
2227 foreach ($row as $key => $value) {
2228 $questionrow[$key] = $value;
2229 }
2230 $all_questions[$row["question_id"]] = $questionrow;
2231 $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2232 $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2233 }
2234 }
2235 // get all questionblocks
2236 $questionblocks = array();
2237 if (count($all_questions)) {
2238 $result = $ilDB->queryF(
2239 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2240 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2241 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2242 array('integer'),
2243 array($this->getSurveyId())
2244 );
2245 while ($row = $ilDB->fetchAssoc($result)) {
2246 $questionblocks[$row['question_fi']] = $row;
2247 }
2248 }
2249
2250 foreach ($all_questions as $question_id => $row) {
2251 $constraints = $this->getConstraints($question_id);
2252 if (isset($questionblocks[$question_id])) {
2253 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2254 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2255 $all_questions[$question_id]["constraints"] = $constraints;
2256 } else {
2257 $all_questions[$question_id]["questionblock_title"] = "";
2258 $all_questions[$question_id]["questionblock_id"] = "";
2259 $all_questions[$question_id]["constraints"] = $constraints;
2260 }
2261 if ($with_answers) {
2262 $answers = array();
2263 $result = $ilDB->queryF(
2264 "SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2265 "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id " .
2266 "ORDER BY sequence ASC",
2267 array('integer'),
2268 array($question_id)
2269 );
2270 if ($result->numRows() > 0) {
2271 while ($data = $ilDB->fetchAssoc($result)) {
2272 array_push($answers, $data["title"]);
2273 }
2274 }
2275 $all_questions[$question_id]["answers"] = $answers;
2276 }
2277 }
2278 return $all_questions;
2279 }
2280
2287 public function setObligatoryStates($obligatory_questions)
2288 {
2289 $ilDB = $this->db;
2290 $result = $ilDB->queryF(
2291 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2292 array('integer'),
2293 array($this->getSurveyId())
2294 );
2295 if ($result->numRows()) {
2296 while ($row = $ilDB->fetchAssoc($result)) {
2297 if (!array_key_exists($row["question_fi"], $obligatory_questions)) {
2298 $obligatory_questions[$row["question_fi"]] = 0;
2299 }
2300 }
2301 }
2302
2303 // set the obligatory states in the database
2304 foreach ($obligatory_questions as $question_fi => $obligatory) {
2305 // #12420
2306 $ilDB->manipulate("UPDATE svy_question" .
2307 " SET obligatory = " . $ilDB->quote($obligatory, "integer") .
2308 " WHERE question_id = " . $ilDB->quote($question_fi, "integer"));
2309 }
2310 }
2311
2317 public function &getSurveyPages()
2318 {
2319 $ilDB = $this->db;
2320 // get questionblocks
2321 $all_questions = array();
2322 $result = $ilDB->queryF(
2323 "SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2324 "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2325 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2326 "ORDER BY svy_svy_qst.sequence",
2327 array('integer'),
2328 array($this->getSurveyId())
2329 );
2330 while ($row = $ilDB->fetchAssoc($result)) {
2331 $all_questions[$row["question_id"]] = $row;
2332 }
2333 // get all questionblocks
2334 $questionblocks = array();
2335 if (count($all_questions)) {
2336 $result = $ilDB->queryF(
2337 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst " .
2338 "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2339 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2340 array('integer'),
2341 array($this->getSurveyId())
2342 );
2343 while ($row = $ilDB->fetchAssoc($result)) {
2344 $questionblocks[$row['question_fi']] = $row;
2345 }
2346 }
2347
2348 $all_pages = array();
2349 $pageindex = -1;
2350 $currentblock = "";
2351 foreach ($all_questions as $question_id => $row) {
2352 $constraints = array();
2353 if (isset($questionblocks[$question_id])) {
2354 if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id'])) {
2355 $pageindex++;
2356 }
2357 $all_questions[$question_id]['page'] = $pageindex;
2358 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2359 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2360 $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2361 $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2362 $currentblock = $questionblocks[$question_id]['questionblock_id'];
2363 $constraints = $this->getConstraints($question_id);
2364 $all_questions[$question_id]["constraints"] = $constraints;
2365 } else {
2366 $pageindex++;
2367 $all_questions[$question_id]['page'] = $pageindex;
2368 $all_questions[$question_id]["questionblock_title"] = "";
2369 $all_questions[$question_id]["questionblock_id"] = "";
2370 $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2371 $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2372 $currentblock = "";
2373 $constraints = $this->getConstraints($question_id);
2374 $all_questions[$question_id]["constraints"] = $constraints;
2375 }
2376 if (!isset($all_pages[$pageindex])) {
2377 $all_pages[$pageindex] = array();
2378 }
2379 array_push($all_pages[$pageindex], $all_questions[$question_id]);
2380 }
2381 // calculate position percentage for every page
2382 $max = count($all_pages);
2383 $counter = 1;
2384 foreach ($all_pages as $index => $block) {
2385 foreach ($block as $blockindex => $question) {
2386 $all_pages[$index][$blockindex]["position"] = $counter / $max;
2387 }
2388 $counter++;
2389 }
2390
2391 return $all_pages;
2392 }
2393
2402 public function getNextPage($active_page_question_id, $direction)
2403 {
2404 $foundpage = -1;
2405 $pages =&$this->getSurveyPages();
2406 if (strcmp($active_page_question_id, "") == 0) {
2407 return $pages[0];
2408 }
2409 foreach ($pages as $key => $question_array) {
2410 foreach ($question_array as $question) {
2411 if ($active_page_question_id == $question["question_id"]) {
2412 $foundpage = $key;
2413 }
2414 }
2415 }
2416 if ($foundpage == -1) {
2417 // error: page not found
2418 } else {
2419 $foundpage += $direction;
2420 if ($foundpage < 0) {
2421 return 0;
2422 }
2423 if ($foundpage >= count($pages)) {
2424 return 1;
2425 }
2426 return $pages[$foundpage];
2427 }
2428 }
2429
2436 public function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = false, $permission = "read")
2437 {
2438 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
2439 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2440 }
2441
2447 public function getPrecondition($id)
2448 {
2449 $ilDB = $this->db;
2450
2451 $result_array = array();
2452 $result = $ilDB->queryF(
2453 "SELECT svy_constraint.*, svy_relation.*, svy_qst_constraint.question_fi ref_question_fi FROM svy_qst_constraint, svy_constraint, " .
2454 "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2455 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2456 array('integer'),
2457 array($id)
2458 );
2459 $pc = array();
2460 if ($result->numRows()) {
2461 $pc = $ilDB->fetchAssoc($result);
2462 }
2463 return $pc;
2464 }
2465
2471 public function getConstraints($question_id)
2472 {
2473 $ilDB = $this->db;
2474
2475 $result_array = array();
2476 $result = $ilDB->queryF(
2477 "SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation " .
2478 "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2479 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s " .
2480 "AND svy_qst_constraint.survey_fi = %s",
2481 array('integer','integer'),
2482 array($question_id, $this->getSurveyId())
2483 );
2484 while ($row = $ilDB->fetchAssoc($result)) {
2485 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2486 $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2487 SurveyQuestion::_includeClass($question_type);
2488 $question = new $question_type();
2489 $question->loadFromDb($row["question_fi"]);
2490 $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2491 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));
2492 }
2493 return $result_array;
2494 }
2495
2501 public static function _getConstraints($survey_id)
2502 {
2503 global $DIC;
2504
2505 $ilDB = $DIC->database();
2506 $result_array = array();
2507 $result = $ilDB->queryF(
2508 "SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* " .
2509 "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id " .
2510 "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2511 array('integer'),
2512 array($survey_id)
2513 );
2514 while ($row = $ilDB->fetchAssoc($result)) {
2515 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']));
2516 }
2517 return $result_array;
2518 }
2519
2520
2526 public function &getVariables($question_id)
2527 {
2528 $ilDB = $this->db;
2529
2530 $result_array = array();
2531 $result = $ilDB->queryF(
2532 "SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN " .
2533 "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s " .
2534 "ORDER BY svy_variable.sequence",
2535 array('integer'),
2536 array($question_id)
2537 );
2538 while ($row = $ilDB->fetchObject($result)) {
2539 $result_array[$row->sequence] = $row;
2540 }
2541 return $result_array;
2542 }
2543
2552 public function addConstraint($if_question_id, $relation, $value, $conjunction)
2553 {
2554 $ilDB = $this->db;
2555
2556 $next_id = $ilDB->nextId('svy_constraint');
2557 $affectedRows = $ilDB->manipulateF(
2558 "INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES " .
2559 "(%s, %s, %s, %s, %s)",
2560 array('integer','integer','integer','float', 'integer'),
2561 array($next_id, $if_question_id, $relation, $value, $conjunction)
2562 );
2563 if ($affectedRows) {
2564 return $next_id;
2565 } else {
2566 return null;
2567 }
2568 }
2569
2570
2577 public function addConstraintToQuestion($to_question_id, $constraint_id)
2578 {
2579 $ilDB = $this->db;
2580
2581 $next_id = $ilDB->nextId('svy_qst_constraint');
2582 $affectedRows = $ilDB->manipulateF(
2583 "INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, " .
2584 "constraint_fi) VALUES (%s, %s, %s, %s)",
2585 array('integer','integer','integer','integer'),
2586 array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2587 );
2588 }
2589
2600 public function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2601 {
2602 $ilDB = $this->db;
2603 $affectedRows = $ilDB->manipulateF(
2604 "UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s " .
2605 "WHERE constraint_id = %s",
2606 array('integer','integer','float','integer','integer'),
2607 array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2608 );
2609 }
2610
2611 public function updateConjunctionForQuestions($questions, $conjunction)
2612 {
2613 $ilDB = $this->db;
2614 foreach ($questions as $question_id) {
2615 $affectedRows = $ilDB->manipulateF(
2616 "UPDATE svy_constraint SET conjunction = %s " .
2617 "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2618 array('integer','integer'),
2619 array($conjunction, $question_id)
2620 );
2621 }
2622 }
2623
2629 public function getAllRelations($short_as_key = false)
2630 {
2631 $ilDB = $this->db;
2632
2633 // #7987
2634 $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2635 $custom_order = array_flip($custom_order);
2636
2637 $result_array = array();
2638 $result = $ilDB->query("SELECT * FROM svy_relation");
2639 while ($row = $ilDB->fetchAssoc($result)) {
2640 if ($short_as_key) {
2641 $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2642 } else {
2643 $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2644 }
2645 }
2646
2647 $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2648 foreach ($result_array as $idx => $item) {
2649 unset($result_array[$idx]["order"]);
2650 }
2651
2652 return $result_array;
2653 }
2654
2658 public function disinviteAllUsers()
2659 {
2660 $ilDB = $this->db;
2661 $result = $ilDB->queryF(
2662 "SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2663 array('integer'),
2664 array($this->getSurveyId())
2665 );
2666 while ($row = $ilDB->fetchAssoc($result)) {
2667 $this->disinviteUser($row['user_fi']);
2668 }
2669 }
2670
2676 public function disinviteUser($user_id)
2677 {
2678 $ilDB = $this->db;
2679
2680 $affectedRows = $ilDB->manipulateF(
2681 "DELETE FROM svy_inv_usr WHERE survey_fi = %s AND user_fi = %s",
2682 array('integer','integer'),
2683 array($this->getSurveyId(), $user_id)
2684 );
2685 include_once './Services/User/classes/class.ilObjUser.php';
2686 ilObjUser::_dropDesktopItem($user_id, $this->getRefId(), "svy");
2687 }
2688
2695 public function inviteUser($user_id)
2696 {
2697 $ilDB = $this->db;
2698
2699 $result = $ilDB->queryF(
2700 "SELECT user_fi FROM svy_inv_usr WHERE user_fi = %s AND survey_fi = %s",
2701 array('integer','integer'),
2702 array($user_id, $this->getSurveyId())
2703 );
2704 if ($result->numRows() < 1) {
2705 $next_id = $ilDB->nextId('svy_inv_usr');
2706 $affectedRows = $ilDB->manipulateF(
2707 "INSERT INTO svy_inv_usr (invited_user_id, survey_fi, user_fi, tstamp) " .
2708 "VALUES (%s, %s, %s, %s)",
2709 array('integer','integer','integer','integer'),
2710 array($next_id, $this->getSurveyId(), $user_id, time())
2711 );
2712 }
2713 if ($this->getInvitation() == self::INVITATION_ON) {
2714 include_once './Services/User/classes/class.ilObjUser.php';
2715 ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2716 }
2717 }
2718
2725 public function &getInvitedUsers()
2726 {
2727 $ilDB = $this->db;
2728
2729 $result_array = array();
2730 $result = $ilDB->queryF(
2731 "SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2732 array('integer'),
2733 array($this->getSurveyId())
2734 );
2735 while ($row = $ilDB->fetchAssoc($result)) {
2736 array_push($result_array, $row["user_fi"]);
2737 }
2738 return $result_array;
2739 }
2740
2748 public function deleteWorkingData($question_id, $active_id)
2749 {
2750 $ilDB = $this->db;
2751
2752 $affectedRows = $ilDB->manipulateF(
2753 "DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2754 array('integer','integer'),
2755 array($question_id, $active_id)
2756 );
2757 }
2758
2767 public function loadWorkingData($question_id, $active_id)
2768 {
2769 $ilDB = $this->db;
2770 $result_array = array();
2771 $result = $ilDB->queryF(
2772 "SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2773 array('integer','integer'),
2774 array($question_id, $active_id)
2775 );
2776 if ($result->numRows() >= 1) {
2777 while ($row = $ilDB->fetchAssoc($result)) {
2778 array_push($result_array, $row);
2779 }
2780 return $result_array;
2781 } else {
2782 return $result_array;
2783 }
2784 }
2785
2792 public function startSurvey($user_id, $anonymous_id, $appraisee_id)
2793 {
2794 $ilDB = $this->db;
2795
2796 if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) {
2797 return;
2798 }
2799
2800 if (strcmp($user_id, "") == 0) {
2801 if ($user_id == ANONYMOUS_USER_ID) {
2802 $user_id = 0;
2803 }
2804 }
2805 $next_id = $ilDB->nextId('svy_finished');
2806 $affectedRows = $ilDB->manipulateF(
2807 "INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) " .
2808 "VALUES (%s, %s, %s, %s, %s, %s, %s)",
2809 array('integer','integer','integer','text','text','integer','integer'),
2810 array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
2811 );
2812 return $next_id;
2813 }
2814
2821 public function finishSurvey($finished_id)
2822 {
2823 $ilDB = $this->db;
2824
2825 $ilDB->manipulateF(
2826 "UPDATE svy_finished SET state = %s, tstamp = %s" .
2827 " WHERE survey_fi = %s AND finished_id = %s",
2828 array('text','integer','integer','integer'),
2829 array(1, time(), $this->getSurveyId(), $finished_id)
2830 );
2831
2832 $this->checkTutorNotification();
2833 }
2834
2842 public function setPage($finished_id, $page_id)
2843 {
2844 $ilDB = $this->db;
2845
2846 $affectedRows = $ilDB->manipulateF(
2847 "UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
2848 array('integer','integer'),
2849 array(($page_id) ? $page_id : 0, $finished_id)
2850 );
2851 }
2852
2853 public function sendNotificationMail($user_id, $anonymize_id, $appr_id)
2854 {
2855 include_once "./Services/User/classes/class.ilObjUser.php";
2856 include_once "./Services/User/classes/class.ilUserUtil.php";
2857
2858 // #12755
2859 $placeholders = array(
2860 "FIRST_NAME" => "firstname",
2861 "LAST_NAME" => "lastname",
2862 "LOGIN" => "login",
2863 // old style
2864 "firstname" => "firstname"
2865 );
2866
2867 $recipients = preg_split('/,/', $this->mailaddresses);
2868 foreach ($recipients as $recipient) {
2869 // #11298
2870 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
2871 $ntf = new ilSystemNotification();
2872 $ntf->setLangModules(array("survey"));
2873 $ntf->setRefId($this->getRefId());
2874 $ntf->setSubjectLangId('finished_mail_subject');
2875
2876 $messagetext = $this->mailparticipantdata;
2877 if (trim($messagetext)) {
2878 if (!$this->hasAnonymizedResults()) {
2879 $data = ilObjUser::_getUserData(array($user_id));
2880 $data = $data[0];
2881 }
2882 foreach ($placeholders as $key => $mapping) {
2883 if ($this->hasAnonymizedResults()) { // #16480
2884 $messagetext = str_replace('[' . $key . ']', '', $messagetext);
2885 } else {
2886 $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
2887 }
2888 }
2889 $ntf->setIntroductionDirect($messagetext);
2890 } else {
2891 $ntf->setIntroductionLangId('survey_notification_finished_introduction');
2892 }
2893
2894 // 360°? add appraisee data
2895 if ($appr_id) {
2896 $ntf->addAdditionalInfo(
2897 'survey_360_appraisee',
2899 );
2900 }
2901
2902 $active_id = $this->getActiveID($user_id, $anonymize_id, $appr_id);
2903 $ntf->addAdditionalInfo(
2904 'results',
2905 $this->getParticipantTextResults($active_id),
2906 true
2907 );
2908
2909 $ntf->setGotoLangId('survey_notification_tutor_link');
2910 $ntf->setReasonLangId('survey_notification_finished_reason');
2911
2912 $ntf->sendMail(array($recipient), null, null);
2913 }
2914 }
2915
2916 protected function getParticipantTextResults($active_id)
2917 {
2918 $textresult = "";
2919 $userResults =&$this->getUserSpecificResults(array($active_id));
2920 $questions =&$this->getSurveyQuestions(true);
2921 $questioncounter = 1;
2922 foreach ($questions as $question_id => $question_data) {
2923 $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
2924 $found = $userResults[$question_id][$active_id];
2925 $text = "";
2926 if (is_array($found)) {
2927 $text = implode("\n", $found);
2928 } else {
2929 $text = $found;
2930 }
2931 if (strlen($text) == 0) {
2933 }
2934 $text = str_replace("<br />", "\n", $text);
2935 $textresult .= $text . "\n\n";
2936 }
2937 return $textresult;
2938 }
2939
2947 public function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
2948 {
2949 $ilDB = $this->db;
2950
2951 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2952 if ($anonymize_id) {
2953 $result = $ilDB->queryF(
2954 "SELECT * FROM svy_finished" .
2955 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2956 array('integer','text','integer'),
2957 array($this->getSurveyId(), $anonymize_id, $appr_id)
2958 );
2959 } else {
2960 $result = $ilDB->queryF(
2961 "SELECT * FROM svy_finished" .
2962 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2963 array('integer','integer','integer'),
2964 array($this->getSurveyId(), $user_id, $appr_id)
2965 );
2966 }
2967 if ($result->numRows() == 0) {
2968 return false;
2969 } else {
2970 $row = $ilDB->fetchAssoc($result);
2971 // yes, we are doing it this way
2972 $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
2973
2974 return (int) $row["state"];
2975 }
2976 }
2977
2985 public function getActiveID($user_id, $anonymize_id, $appr_id)
2986 {
2987 $ilDB = $this->db;
2988
2989 // see self::isSurveyStarted()
2990
2991 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2992 if ($anonymize_id) {
2993 $result = $ilDB->queryF(
2994 "SELECT finished_id FROM svy_finished" .
2995 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2996 array('integer','text','integer'),
2997 array($this->getSurveyId(), $anonymize_id, $appr_id)
2998 );
2999 } else {
3000 $result = $ilDB->queryF(
3001 "SELECT finished_id FROM svy_finished" .
3002 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3003 array('integer','integer','integer'),
3004 array($this->getSurveyId(), $user_id, $appr_id)
3005 );
3006 }
3007 if ($result->numRows() == 0) {
3008 return false;
3009 } else {
3010 $row = $ilDB->fetchAssoc($result);
3011 return $row["finished_id"];
3012 }
3013 }
3014
3022 public function getLastActivePage($active_id)
3023 {
3024 $ilDB = $this->db;
3025 $result = $ilDB->queryF(
3026 "SELECT lastpage FROM svy_finished WHERE finished_id = %s",
3027 array('integer'),
3028 array($active_id)
3029 );
3030 if ($result->numRows() == 0) {
3031 return "";
3032 } else {
3033 $row = $ilDB->fetchAssoc($result);
3034 return ($row["lastpage"]) ? $row["lastpage"] : '';
3035 }
3036 }
3037
3046 public function checkConstraint($constraint_data, $working_data)
3047 {
3048 if (count($working_data) == 0) {
3049 return 0;
3050 }
3051
3052 if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0)) {
3053 return 0;
3054 }
3055
3056 $found = false;
3057 foreach ($working_data as $data) {
3058 switch ($constraint_data["short"]) {
3059 case "<":
3060 if ($data["value"] < $constraint_data["value"]) {
3061 $found = true;
3062 }
3063 break;
3064
3065 case "<=":
3066 if ($data["value"] <= $constraint_data["value"]) {
3067 $found = true;
3068 }
3069 break;
3070
3071 case "=":
3072 if ($data["value"] == $constraint_data["value"]) {
3073 $found = true;
3074 }
3075 break;
3076
3077 case "<>":
3078 if ($data["value"] <> $constraint_data["value"]) {
3079 $found = true;
3080 }
3081 break;
3082
3083 case ">=":
3084 if ($data["value"] >= $constraint_data["value"]) {
3085 $found = true;
3086 }
3087 break;
3088
3089 case ">":
3090 if ($data["value"] > $constraint_data["value"]) {
3091 $found = true;
3092 }
3093 break;
3094 }
3095 if ($found) {
3096 break;
3097 }
3098 }
3099
3100 return (int) $found;
3101 }
3102
3103 public static function _hasDatasets($survey_id)
3104 {
3105 global $DIC;
3106
3107 $ilDB = $DIC->database();
3108
3109 $result = $ilDB->queryF(
3110 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3111 array('integer'),
3112 array($survey_id)
3113 );
3114 return ($result->numRows()) ? true : false;
3115 }
3116
3123 public function &getSurveyFinishedIds()
3124 {
3125 $ilDB = $this->db;
3127
3128 $users = array();
3129 $result = $ilDB->queryF(
3130 "SELECT * FROM svy_finished WHERE survey_fi = %s",
3131 array('integer'),
3132 array($this->getSurveyId())
3133 );
3134 if ($result->numRows()) {
3135 while ($row = $ilDB->fetchAssoc($result)) {
3136 array_push($users, $row["finished_id"]);
3137 }
3138 }
3139 return $users;
3140 }
3141
3148 public function getUserSpecificResults($finished_ids)
3149 {
3150 $evaluation = array();
3151
3152 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3153 foreach (array_keys($this->getSurveyQuestions()) as $question_id) {
3154 // get question instance
3155 $question_type = SurveyQuestion::_getQuestionType($question_id);
3156 SurveyQuestion::_includeClass($question_type);
3157 $question = new $question_type();
3158 $question->loadFromDb($question_id);
3159
3160 $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($question_id, $finished_ids);
3161 $q_res = $q_eval->getResults();
3162
3163 $data = array();
3164 foreach ($finished_ids as $user_id) {
3165 $data[$user_id] = $q_eval->parseUserSpecificResults($q_res, $user_id);
3166 }
3167
3168 $evaluation[$question_id] = $data;
3169 }
3170
3171 return $evaluation;
3172 }
3173
3181 public function getUserDataFromActiveId($active_id, $force_non_anonymous = false)
3182 {
3183 $ilDB = $this->db;
3184
3185 $surveySetting = new ilSetting("survey");
3186 $use_anonymous_id = array_key_exists("use_anonymous_id", $_GET) ? $_GET["use_anonymous_id"] : $surveySetting->get("use_anonymous_id");
3187 $result = $ilDB->queryF(
3188 "SELECT * FROM svy_finished WHERE finished_id = %s",
3189 array('integer'),
3190 array($active_id)
3191 );
3192 $row = array();
3193 $foundrows = $result->numRows();
3194 if ($foundrows) {
3195 $row = $ilDB->fetchAssoc($result);
3196 }
3197 $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3198 $userdata = array(
3199 "fullname" => $name,
3200 "sortname" => $name,
3201 "firstname" => "",
3202 "lastname" => "",
3203 "login" => "",
3204 "gender" => "",
3205 "active_id" => "$active_id"
3206 );
3207 if ($foundrows) {
3208 if (($row["user_fi"] > 0) &&
3209 (($row["user_fi"] != ANONYMOUS_USER_ID &&
3210 !$this->hasAnonymizedResults() &&
3211 !$this->get360Mode()) || // 360° uses ANONYMIZE_CODE_ALL which is wrong - see ilObjSurveyGUI::afterSave()
3212 (bool) $force_non_anonymous)) {
3213 include_once './Services/User/classes/class.ilObjUser.php';
3214 if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0) {
3215 $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3216 } else {
3217 $user = new ilObjUser($row["user_fi"]);
3218 $userdata["fullname"] = $user->getFullname();
3219 $gender = $user->getGender();
3220 if (strlen($gender) == 1) {
3221 $gender = $this->lng->txt("gender_$gender");
3222 }
3223 $userdata["gender"] = $gender;
3224 $userdata["firstname"] = $user->getFirstname();
3225 $userdata["lastname"] = $user->getLastname();
3226 $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3227 $userdata["login"] = $user->getLogin();
3228 }
3229 }
3230 }
3231 return $userdata;
3232 }
3233
3243 public function &getEvaluationByUser($questions, $active_id)
3244 {
3245 $ilDB = $this->db;
3246
3247 // collect all answers
3248 $answers = array();
3249 $result = $ilDB->queryF(
3250 "SELECT * FROM svy_answer WHERE active_fi = %s",
3251 array('integer'),
3252 array($active_id)
3253 );
3254 while ($row = $ilDB->fetchAssoc($result)) {
3255 if (!is_array($answers[$row["question_fi"]])) {
3256 $answers[$row["question_fi"]] = array();
3257 }
3258 array_push($answers[$row["question_fi"]], $row);
3259 }
3260 $userdata = $this->getUserDataFromActiveId($active_id);
3261 $resultset = array(
3262 "name" => $userdata["fullname"],
3263 "firstname" => $userdata["firstname"],
3264 "lastname" => $userdata["lastname"],
3265 "login" => $userdata["login"],
3266 "gender" => $userdata["gender"],
3267 "answers" => array()
3268 );
3269 foreach ($questions as $key => $question) {
3270 if (array_key_exists($key, $answers)) {
3271 $resultset["answers"][$key] = $answers[$key];
3272 } else {
3273 $resultset["answers"][$key] = array();
3274 }
3275 sort($resultset["answers"][$key]);
3276 }
3277 return $resultset;
3278 }
3279
3285 public function getQuestionsTable($arrFilter)
3286 {
3288 $ilDB = $this->db;
3289 $where = "";
3290 if (is_array($arrFilter)) {
3291 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3292 $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3293 }
3294 if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description'])) {
3295 $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3296 }
3297 if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author'])) {
3298 $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3299 }
3300 if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type'])) {
3301 $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3302 }
3303 if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl'])) {
3304 $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3305 }
3306 }
3307
3308 $spls =&$this->getAvailableQuestionpools($use_obj_id = true, $could_be_offline = false, $showPath = false);
3309 $forbidden = "";
3310 $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3311 $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3312 $existing = "";
3313 $existing_questions =&$this->getExistingQuestions();
3314 if (count($existing_questions)) {
3315 $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3316 }
3317
3318 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
3320
3321 $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id" .
3322 " FROM svy_question, svy_qtype, object_reference" .
3323 " WHERE svy_question.original_id IS NULL" . $forbidden . $existing .
3324 " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0" .
3325 " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3326
3327 $rows = array();
3328 if ($query_result->numRows()) {
3329 while ($row = $ilDB->fetchAssoc($query_result)) {
3330 if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt'])) {
3331 if (!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt'])) {
3332 continue;
3333 }
3334 }
3335
3336 $row['ttype'] = $trans[$row['type_tag']];
3337 if ($row["plugin"]) {
3338 if ($this->isPluginActive($row["type_tag"])) {
3339 array_push($rows, $row);
3340 }
3341 } else {
3342 array_push($rows, $row);
3343 }
3344 }
3345 }
3346 return $rows;
3347 }
3348
3354 public function getQuestionblocksTable($arrFilter)
3355 {
3357 $ilDB = $this->db;
3358
3359 $where = "";
3360 if (is_array($arrFilter)) {
3361 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3362 $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3363 }
3364 }
3365
3366 $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE " .
3367 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi " .
3368 "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, " .
3369 "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3370 $rows = array();
3371 if ($query_result->numRows()) {
3372 $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3373 $surveytitles = array();
3374 foreach ($survey_ref_ids as $survey_ref_id) {
3375 $survey_id = ilObject::_lookupObjId($survey_ref_id);
3377 }
3378 while ($row = $ilDB->fetchAssoc($query_result)) {
3379 $questions_array =&$this->getQuestionblockQuestions($row["questionblock_id"]);
3380 $counter = 1;
3381 foreach ($questions_array as $key => $value) {
3382 $questions_array[$key] = "$counter. $value";
3383 $counter++;
3384 }
3385 if (strlen($surveytitles[$row["obj_fi"]])) { // only questionpools which are not in trash
3386 $rows[$row["questionblock_id"]] = array(
3387 "questionblock_id" => $row["questionblock_id"],
3388 "title" => $row["title"],
3389 "svy" => $surveytitles[$row["obj_fi"]],
3390 "contains" => join($questions_array, ", "),
3391 "owner" => $row["owner_fi"]
3392 );
3393 }
3394 }
3395 }
3396 return $rows;
3397 }
3398
3405 public function toXML()
3406 {
3407 include_once("./Services/Xml/classes/class.ilXmlWriter.php");
3408 $a_xml_writer = new ilXmlWriter;
3409 // set xml header
3410 $a_xml_writer->xmlHeader();
3411 $attrs = array(
3412 "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3413 "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3414 );
3415 $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3416 $attrs = array(
3417 "id" => $this->getSurveyId(),
3418 "title" => $this->getTitle()
3419 );
3420 $a_xml_writer->xmlStartTag("survey", $attrs);
3421
3422 $a_xml_writer->xmlElement("description", null, $this->getDescription());
3423 $a_xml_writer->xmlElement("author", null, $this->getAuthor());
3424 $a_xml_writer->xmlStartTag("objectives");
3425 $attrs = array(
3426 "label" => "introduction"
3427 );
3428 $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), true, true, $attrs);
3429 $attrs = array(
3430 "label" => "outro"
3431 );
3432 $this->addMaterialTag($a_xml_writer, $this->getOutro(), true, true, $attrs);
3433 $a_xml_writer->xmlEndTag("objectives");
3434
3435 if ($this->getAnonymize()) {
3436 $attribs = array("enabled" => "1");
3437 } else {
3438 $attribs = array("enabled" => "0");
3439 }
3440 $a_xml_writer->xmlElement("anonymisation", $attribs);
3441 $a_xml_writer->xmlStartTag("restrictions");
3442 if ($this->getAnonymize() == 2) {
3443 $attribs = array("type" => "free");
3444 } else {
3445 $attribs = array("type" => "restricted");
3446 }
3447 $a_xml_writer->xmlElement("access", $attribs);
3448 if ($this->getStartDate()) {
3449 $attrs = array("type" => "date");
3450 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3451 $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]));
3452 }
3453 if ($this->getEndDate()) {
3454 $attrs = array("type" => "date");
3455 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3456 $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]));
3457 }
3458 $a_xml_writer->xmlEndTag("restrictions");
3459
3460 // constraints
3461 $pages =&$this->getSurveyPages();
3462 $hasconstraints = false;
3463 foreach ($pages as $question_array) {
3464 foreach ($question_array as $question) {
3465 if (count($question["constraints"])) {
3466 $hasconstraints = true;
3467 }
3468 }
3469 }
3470
3471 if ($hasconstraints) {
3472 $a_xml_writer->xmlStartTag("constraints");
3473 foreach ($pages as $question_array) {
3474 foreach ($question_array as $question) {
3475 if (count($question["constraints"])) {
3476 // found constraints
3477 foreach ($question["constraints"] as $constraint) {
3478 $attribs = array(
3479 "sourceref" => $question["question_id"],
3480 "destref" => $constraint["question"],
3481 "relation" => $constraint["short"],
3482 "value" => $constraint["value"],
3483 "conjunction" => $constraint["conjunction"]
3484 );
3485 $a_xml_writer->xmlElement("constraint", $attribs);
3486 }
3487 }
3488 }
3489 }
3490 $a_xml_writer->xmlEndTag("constraints");
3491 }
3492
3493 // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
3494 $a_xml_writer->xmlStartTag("metadata");
3495
3496 $custom_properties = array();
3497 $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
3498 $custom_properties["status"] = $this->getStatus();
3499 $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
3500 $custom_properties["pool_usage"] = (int) $this->getPoolUsage();
3501
3502 $custom_properties["own_results_view"] = (int) $this->hasViewOwnResults();
3503 $custom_properties["own_results_mail"] = (int) $this->hasMailOwnResults();
3504 $custom_properties["confirmation_mail"] = (int) $this->hasMailConfirmation();
3505
3506 $custom_properties["anon_user_list"] = (int) $this->hasAnonymousUserList();
3507
3508 $custom_properties["mode_360"] = (int) $this->get360Mode();
3509 $custom_properties["mode_360_self_eval"] = (int) $this->get360SelfEvaluation();
3510 $custom_properties["mode_360_self_rate"] = (int) $this->get360SelfRaters();
3511 $custom_properties["mode_360_self_appr"] = (int) $this->get360SelfAppraisee();
3512 $custom_properties["mode_360_results"] = $this->get360Results();
3513 $custom_properties["mode_360_skill_service"] = (int) $this->get360SkillService();
3514
3515
3516 // :TODO: skills?
3517
3518 // reminder/tutor notification are (currently?) not exportable
3519
3520 foreach ($custom_properties as $label => $value) {
3521 $a_xml_writer->xmlStartTag("metadatafield");
3522 $a_xml_writer->xmlElement("fieldlabel", null, $label);
3523 $a_xml_writer->xmlElement("fieldentry", null, $value);
3524 $a_xml_writer->xmlEndTag("metadatafield");
3525 }
3526
3527 $a_xml_writer->xmlStartTag("metadatafield");
3528 $a_xml_writer->xmlElement("fieldlabel", null, "SCORM");
3529 include_once "./Services/MetaData/classes/class.ilMD.php";
3530 $md = new ilMD($this->getId(), 0, $this->getType());
3531 $writer = new ilXmlWriter();
3532 $md->toXml($writer);
3533 $metadata = $writer->xmlDumpMem();
3534 $a_xml_writer->xmlElement("fieldentry", null, $metadata);
3535 $a_xml_writer->xmlEndTag("metadatafield");
3536
3537 $a_xml_writer->xmlEndTag("metadata");
3538 $a_xml_writer->xmlEndTag("survey");
3539
3540 $attribs = array("id" => $this->getId());
3541 $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
3542 // add questionblock descriptions
3543 foreach ($pages as $question_array) {
3544 if (count($question_array) > 1) {
3545 $attribs = array("id" => $question_array[0]["question_id"]);
3546 $attribs = array("showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
3547 "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"]);
3548 $a_xml_writer->xmlStartTag("questionblock", $attribs);
3549 if (strlen($question_array[0]["questionblock_title"])) {
3550 $a_xml_writer->xmlElement("questionblocktitle", null, $question_array[0]["questionblock_title"]);
3551 }
3552 }
3553 foreach ($question_array as $question) {
3554 if (strlen($question["heading"])) {
3555 $a_xml_writer->xmlElement("textblock", null, $question["heading"]);
3556 }
3557 $questionObject = self::_instanciateQuestion($question["question_id"]);
3558 //questionObject contains all the fields from the database. (loadFromDb)
3559 //we don't need the value from svy_qst_oblig table, we already have the values from svy_question table.
3560 //if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
3561 if ($questionObject !== false) {
3562 $questionObject->insertXML($a_xml_writer, false);
3563 }
3564 }
3565 if (count($question_array) > 1) {
3566 $a_xml_writer->xmlEndTag("questionblock");
3567 }
3568 }
3569
3570 $a_xml_writer->xmlEndTag("surveyquestions");
3571 $a_xml_writer->xmlEndTag("surveyobject");
3572 $xml = $a_xml_writer->xmlDumpMem(false);
3573 return $xml;
3574 }
3575
3583 public static function _instanciateQuestion($question_id)
3584 {
3585 if ($question_id < 1) {
3586 return false;
3587 }
3588 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3589 $question_type = SurveyQuestion::_getQuestionType($question_id);
3590 if (strlen($question_type) == 0) {
3591 return false;
3592 }
3593 SurveyQuestion::_includeClass($question_type);
3594 $question = new $question_type();
3595 $question->loadFromDb($question_id);
3596 return $question;
3597 }
3598
3605 public function locateImportFiles($a_dir)
3606 {
3607 if (!is_dir($a_dir) || is_int(strpos($a_dir, ".."))) {
3608 return;
3609 }
3610 $importDirectory = "";
3611 $xmlFile = "";
3612
3613 $current_dir = opendir($a_dir);
3614 $files = array();
3615 while ($entryname = readdir($current_dir)) {
3616 $files[] = $entryname;
3617 }
3618
3619 foreach ($files as $file) {
3620 if (is_dir($a_dir . "/" . $file) and ($file != "." and $file!="..")) {
3621 // found directory created by zip
3622 $importDirectory = $a_dir . "/" . $file;
3623 }
3624 }
3625 closedir($current_dir);
3626 if (strlen($importDirectory)) {
3627 // find the xml file
3628 $current_dir = opendir($importDirectory);
3629 $files = array();
3630 while ($entryname = readdir($current_dir)) {
3631 $files[] = $entryname;
3632 }
3633 foreach ($files as $file) {
3634 if (@is_file($importDirectory . "/" . $file) &&
3635 ($file != "." && $file!="..") &&
3636 (preg_match("/^[0-9]{10}__[0-9]+__(svy_)*[0-9]+\.[A-Za-z]{1,3}$/", $file) ||
3637 preg_match("/^[0-9]{10}__[0-9]+__(survey__)*[0-9]+\.[A-Za-z]{1,3}$/", $file))) {
3638 // found xml file
3639 $xmlFile = $importDirectory . "/" . $file;
3640 }
3641 }
3642 }
3643 return array("dir" => $importDirectory, "xml" => $xmlFile);
3644 }
3645
3654 public function importObject($file_info, $svy_qpl_id)
3655 {
3656 if ($svy_qpl_id < 1) {
3657 $svy_qpl_id = -1;
3658 }
3659 // check if file was uploaded
3660 $source = $file_info["tmp_name"];
3661 $error = "";
3662 if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK) {
3663 $error = $this->lng->txt("import_no_file_selected");
3664 }
3665 // check correct file type
3666 $isXml = false;
3667 $isZip = false;
3668 if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0)) {
3669 $this->log->debug("isXML");
3670 $isXml = true;
3671 }
3672 // too many different mime-types, so we use the suffix
3673 $suffix = pathinfo($file_info["name"]);
3674 if (strcmp(strtolower($suffix["extension"]), "zip") == 0) {
3675 $this->log->debug("isZip");
3676 $isZip = true;
3677 }
3678 if (!$isXml && !$isZip) {
3679 $error = $this->lng->txt("import_wrong_file_type");
3680 $this->log->debug("Survey: Import error. Filetype was \"" . $file_info["type"] . "\"");
3681 }
3682 if (strlen($error) == 0) {
3683 // import file as a survey
3684 $import_dir = $this->getImportDirectory();
3685 $import_subdir = "";
3686 $importfile = "";
3687 if ($isZip) {
3688 $importfile = $import_dir . "/" . $file_info["name"];
3689 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3690 ilUtil::unzip($importfile);
3691 $found = $this->locateImportFiles($import_dir);
3692 if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0))) {
3693 $error = $this->lng->txt("wrong_import_file_structure");
3694 return $error;
3695 }
3696 $importfile = $found["xml"];
3697 $import_subdir = $found["dir"];
3698 } else {
3699 $importfile = tempnam($import_dir, "survey_import");
3700 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3701 }
3702
3703 $this->log->debug("Import file = $importfile");
3704 $this->log->debug("Import subdir = $import_subdir");
3705
3706 $fh = fopen($importfile, "r");
3707 if (!$fh) {
3708 $error = $this->lng->txt("import_error_opening_file");
3709 return $error;
3710 }
3711 $xml = fread($fh, filesize($importfile));
3712 $result = fclose($fh);
3713 if (!$result) {
3714 $error = $this->lng->txt("import_error_closing_file");
3715 return $error;
3716 }
3717
3718 unset($_SESSION["import_mob_xhtml"]);
3719 if (strpos($xml, "questestinterop")) {
3720 include_once("./Modules/Survey/exceptions/class.ilInvalidSurveyImportFileException.php");
3721 throw new ilInvalidSurveyImportFileException("Unsupported survey version (< 3.8) found.");
3722 /*
3723 include_once "./Services/Survey/classes/class.SurveyImportParserPre38.php";
3724 $import = new SurveyImportParserPre38($svy_qpl_id, "", TRUE);
3725 $import->setSurveyObject($this);
3726 $import->setXMLContent($xml);
3727 $import->startParsing();*/
3728 } else {
3729 $this->log->debug("survey id = " . $this->getId());
3730 $this->log->debug("question pool id = " . $svy_qpl_id);
3731
3732 include_once("./Services/Export/classes/class.ilImport.php");
3733 $imp = new ilImport();
3734 $config = $imp->getConfig("Modules/Survey");
3735 $config->setQuestionPoolID($svy_qpl_id);
3736 $imp->getMapping()->addMapping("Modules/Survey", "svy", 0, $this->getId());
3737 $imp->importFromDirectory($import_subdir, "svy", "Modules/Survey");
3738 $this->log->debug("config(Modules/survey)->getQuestionPoolId =" . $config->getQuestionPoolID());
3739 return "";
3740
3741 //old code
3742 include_once "./Services/Survey/classes/class.SurveyImportParser.php";
3743 $import = new SurveyImportParser($svy_qpl_id, "", true);
3744 $import->setSurveyObject($this);
3745 $import->setXMLContent($xml);
3746 $import->startParsing();
3747 }
3748
3749 if (is_array($_SESSION["import_mob_xhtml"])) {
3750 include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
3751 include_once "./Services/RTE/classes/class.ilRTE.php";
3752 include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3753 foreach ($_SESSION["import_mob_xhtml"] as $mob) {
3754 $importfile = $import_subdir . "/" . $mob["uri"];
3755 if (file_exists($importfile)) {
3756 if (!$mob["type"]) {
3757 $mob["type"] = "svy:html";
3758 }
3759
3760 $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, false);
3761
3762 // survey mob
3763 if ($mob["type"] == "svy:html") {
3764 ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
3765 $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
3766 $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
3767 }
3768 // question mob
3769 elseif ($import->questions[$mob["id"]]) {
3770 $new_qid = $import->questions[$mob["id"]];
3771 ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
3772 $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
3773 $qtext = $new_question->getQuestiontext();
3774 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
3775 $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
3776 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
3777 $new_question->setQuestiontext($qtext);
3778 $new_question->saveToDb();
3779
3780 // also fix existing original in pool
3781 if ($new_question->getOriginalId()) {
3782 $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
3783 $pool_question->setQuestiontext($qtext);
3784 $pool_question->saveToDb();
3785 }
3786 }
3787 } else {
3789 $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
3790 }
3791 }
3794 $this->saveToDb();
3795 }
3796
3797 // delete import directory
3799 }
3800 return $error;
3801 }
3802
3811 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
3812 {
3813 $ilDB = $this->db;
3814
3815 $this->loadFromDb();
3816
3817 // Copy settings
3818 $newObj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
3819 $this->cloneMetaData($newObj);
3820 $newObj->updateMetaData();
3821
3822 $newObj->setAuthor($this->getAuthor());
3823 $newObj->setIntroduction($this->getIntroduction());
3824 $newObj->setOutro($this->getOutro());
3825 $newObj->setEvaluationAccess($this->getEvaluationAccess());
3826 $newObj->setStartDate($this->getStartDate());
3827 $newObj->setEndDate($this->getEndDate());
3828 $newObj->setInvitation($this->getInvitation());
3829 $newObj->setInvitationMode($this->getInvitationMode());
3830 $newObj->setAnonymize($this->getAnonymize());
3831 $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
3832 $newObj->setTemplate($this->getTemplate());
3833 $newObj->setPoolUsage($this->getPoolUsage());
3834 $newObj->setViewOwnResults($this->hasViewOwnResults());
3835 $newObj->setMailOwnResults($this->hasMailOwnResults());
3836 $newObj->setMailConfirmation($this->hasMailConfirmation());
3837 $newObj->setAnonymousUserList($this->hasAnonymousUserList());
3838
3839 // #12661
3840 if ($this->get360Mode()) {
3841 $newObj->set360Mode(true);
3842 $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
3843 $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
3844 $newObj->set360SelfRaters($this->get360SelfRaters());
3845 $newObj->set360Results($this->get360Results());
3846 $newObj->set360SkillService($this->get360SkillService());
3847 }
3848
3849 // reminder/notification
3850 $newObj->setReminderStatus($this->getReminderStatus());
3851 $newObj->setReminderStart($this->getReminderStart());
3852 $newObj->setReminderEnd($this->getReminderEnd());
3853 $newObj->setReminderFrequency($this->getReminderFrequency());
3854 $newObj->setReminderTarget($this->getReminderTarget());
3855 $newObj->setReminderTemplate($this->getReminderTemplate());
3856 // reminder_last_sent must not be copied!
3857 $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
3858 $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
3859 $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
3860
3861 $newObj->setMailNotification($this->getMailNotification());
3862 $newObj->setMailAddresses($this->getMailAddresses());
3863 $newObj->setMailParticipantData($this->getMailParticipantData());
3864
3865 $question_pointer = array();
3866 // clone the questions
3867 $mapping = array();
3868 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3869
3870 foreach ($this->questions as $key => $question_id) {
3871 $question = self::_instanciateQuestion($question_id);
3872 if ($question) { // #10824
3873 $question->id = -1;
3874 $original_id = SurveyQuestion::_getOriginalId($question_id, false);
3875 $question->saveToDb($original_id);
3876 $newObj->questions[$key] = $question->getId();
3877 $question_pointer[$question_id] = $question->getId();
3878 $mapping[$question_id] = $question->getId();
3879 }
3880 }
3881
3882 //copy online status if object is not the root copy object
3883 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
3884
3885 if (!$cp_options->isRootNode($this->getRefId())) {
3886 $newObj->setStatus($this->isOnline()?self::STATUS_ONLINE: self::STATUS_OFFLINE);
3887 }
3888
3889 $newObj->saveToDb();
3890 $newObj->cloneTextblocks($mapping);
3891
3892 // #14929
3893 if ($this->get360Mode() &&
3894 $this->get360SkillService()) {
3895 include_once "./Modules/Survey/classes/class.ilSurveySkill.php";
3896 $src_skills = new ilSurveySkill($this);
3897 $tgt_skills = new ilSurveySkill($newObj);
3898
3899 foreach ($mapping as $src_qst_id => $tgt_qst_id) {
3900 $qst_skill = $src_skills->getSkillForQuestion($src_qst_id);
3901 if ($qst_skill) {
3902 $tgt_skills->addQuestionSkillAssignment($tgt_qst_id, $qst_skill["base_skill_id"], $qst_skill["tref_id"]);
3903 }
3904 }
3905 }
3906
3907 // clone the questionblocks
3908 $questionblocks = array();
3909 $questionblock_questions = array();
3910 $result = $ilDB->queryF(
3911 "SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
3912 array('integer'),
3913 array($this->getSurveyId())
3914 );
3915 if ($result->numRows() > 0) {
3916 while ($row = $ilDB->fetchAssoc($result)) {
3917 array_push($questionblock_questions, $row);
3918 $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
3919 }
3920 }
3921 // create new questionblocks
3922 foreach ($questionblocks as $key => $value) {
3923 $questionblock = self::_getQuestionblock($key);
3924 $questionblock_id = self::_addQuestionblock($questionblock["title"], $questionblock["owner_fi"], $questionblock["show_questiontext"], $questionblock["show_blocktitle"]);
3925 $questionblocks[$key] = $questionblock_id;
3926 }
3927 // create new questionblock questions
3928 foreach ($questionblock_questions as $key => $value) {
3929 if ($questionblocks[$value["questionblock_fi"]] &&
3930 $question_pointer[$value["question_fi"]]) {
3931 $next_id = $ilDB->nextId('svy_qblk_qst');
3932 $affectedRows = $ilDB->manipulateF(
3933 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) " .
3934 "VALUES (%s, %s, %s, %s)",
3935 array('integer','integer','integer','integer'),
3936 array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
3937 );
3938 }
3939 }
3940
3941 // clone the constraints
3942 $constraints = self::_getConstraints($this->getSurveyId());
3943 $newConstraints = array();
3944 foreach ($constraints as $key => $constraint) {
3945 if ($question_pointer[$constraint["for_question"]] &&
3946 $question_pointer[$constraint["question"]]) {
3947 if (!array_key_exists($constraint['id'], $newConstraints)) {
3948 $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
3949 $newConstraints[$constraint['id']] = $constraint_id;
3950 }
3951 $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
3952 }
3953 }
3954
3955 // #16210 - clone LP settings
3956 include_once('./Services/Tracking/classes/class.ilLPObjSettings.php');
3957 $obj_settings = new ilLPObjSettings($this->getId());
3958 $obj_settings->cloneSettings($newObj->getId());
3959 unset($obj_settings);
3960
3961 return $newObj;
3962 }
3963
3964 public function getTextblock($question_id)
3965 {
3966 $ilDB = $this->db;
3967 $result = $ilDB->queryF(
3968 "SELECT * FROM svy_svy_qst WHERE question_fi = %s",
3969 array('integer'),
3970 array($question_id)
3971 );
3972 if ($result->numRows()) {
3973 $row = $ilDB->fetchAssoc($result);
3974 return $row["heading"];
3975 } else {
3976 return "";
3977 }
3978 }
3979
3985 public function cloneTextblocks($mapping)
3986 {
3987 foreach ($mapping as $original_id => $new_id) {
3988 $textblock = $this->getTextblock($original_id);
3989 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
3990 $this->saveHeading(ilUtil::stripSlashes($textblock, true, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
3991 }
3992 }
3993
4001 public function createExportDirectory()
4002 {
4003 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
4004 ilUtil::makeDir($svy_data_dir);
4005 if (!is_writable($svy_data_dir)) {
4006 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4007 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
4008 }
4009
4010 // create learning module directory (data_dir/lm_data/lm_<id>)
4011 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
4012 ilUtil::makeDir($svy_dir);
4013 if (!@is_dir($svy_dir)) {
4014 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4015 throw new ilSurveyException("Creation of Survey Directory failed.");
4016 }
4017 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
4018 $export_dir = $svy_dir . "/export";
4019 ilUtil::makeDir($export_dir);
4020 if (!@is_dir($export_dir)) {
4021 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4022 throw new ilSurveyException("Creation of Export Directory failed.");
4023 }
4024 }
4025
4029 public function getExportDirectory()
4030 {
4031 $export_dir = ilUtil::getDataDir() . "/svy_data" . "/svy_" . $this->getId() . "/export";
4032
4033 return $export_dir;
4034 }
4035
4043 public function createImportDirectory()
4044 {
4045 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
4046 ilUtil::makeDir($svy_data_dir);
4047
4048 if (!is_writable($svy_data_dir)) {
4049 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4050 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
4051 }
4052
4053 // create test directory (data_dir/svy_data/svy_<id>)
4054 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
4055 ilUtil::makeDir($svy_dir);
4056 if (!@is_dir($svy_dir)) {
4057 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4058 throw new ilSurveyException("Creation of Survey Directory failed.");
4059 }
4060
4061 // create import subdirectory (data_dir/svy_data/svy_<id>/import)
4062 $import_dir = $svy_dir . "/import";
4063 ilUtil::makeDir($import_dir);
4064 if (!@is_dir($import_dir)) {
4065 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4066 throw new ilSurveyException("Creation of Import Directory failed.");
4067 }
4068 }
4069
4073 public function getImportDirectory()
4074 {
4075 $import_dir = ilUtil::getDataDir() . "/svy_data" .
4076 "/svy_" . $this->getId() . "/import";
4077 if (!is_dir($import_dir)) {
4078 ilUtil::makeDirParents($import_dir);
4079 }
4080 if (@is_dir($import_dir)) {
4081 return $import_dir;
4082 } else {
4083 return false;
4084 }
4085 }
4086
4087 public function saveHeading($heading = "", $insertbefore)
4088 {
4089 $ilDB = $this->db;
4090 if ($heading) {
4091 $affectedRows = $ilDB->manipulateF(
4092 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4093 array('text','integer','integer'),
4094 array($heading, $this->getSurveyId(), $insertbefore)
4095 );
4096 } else {
4097 $affectedRows = $ilDB->manipulateF(
4098 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4099 array('text','integer','integer'),
4100 array(null, $this->getSurveyId(), $insertbefore)
4101 );
4102 }
4103 }
4104
4105 public function isAnonymousKey($key)
4106 {
4107 $ilDB = $this->db;
4108
4109 $result = $ilDB->queryF(
4110 "SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
4111 array('text','integer'),
4112 array($key, $this->getSurveyId())
4113 );
4114 return ($result->numRows() == 1) ? true : false;
4115 }
4116
4117 public function bindSurveyCodeToUser($user_id, $code)
4118 {
4119 $ilDB = $this->db;
4120
4121 if ($user_id == ANONYMOUS_USER_ID) {
4122 return;
4123 }
4124
4125 if ($this->checkSurveyCode($code)) {
4126 $ilDB->manipulate("UPDATE svy_anonymous" .
4127 " SET user_key = " . $ilDB->quote(md5($user_id), "text") .
4128 " WHERE survey_key = " . $ilDB->quote($code, "text"));
4129 }
4130 }
4131
4133 {
4134 $ilDB = $this->db;
4135
4136 $result = $ilDB->queryF(
4137 "SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
4138 array('text','integer'),
4139 array($key, $this->getSurveyId())
4140 );
4141 return ($result->numRows() == 1) ? true : false;
4142 }
4143
4144 public function checkSurveyCode($code)
4145 {
4146 if ($this->isAnonymousKey($code)) {
4147 if ($this->isSurveyStarted("", $code) == 1) {
4148 return false;
4149 } else {
4150 return true;
4151 }
4152 } else {
4153 return false;
4154 }
4155 }
4156
4164 public function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
4165 {
4166 $ilDB = $this->db;
4168 $lng = $this->lng;
4169
4170 include_once "./Services/Link/classes/class.ilLink.php";
4171
4172 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4173 " FROM svy_anonymous" .
4174 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4175 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
4176 " AND svy_anonymous.user_key IS NULL";
4177
4178 if ($a_codes) {
4179 $sql .= " AND " . $ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
4180 } elseif ($a_ids) {
4181 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
4182 }
4183
4184 $export = array();
4185
4186 // #14905
4187 $titles = array();
4188 $titles[] = '"' . $lng->txt("survey_code") . '"';
4189 $titles[] = '"' . $lng->txt("email") . '"';
4190 $titles[] = '"' . $lng->txt("lastname") . '"';
4191 $titles[] = '"' . $lng->txt("firstname") . '"';
4192 $titles[] = '"' . $lng->txt("create_date") . '"';
4193 $titles[] = '"' . $lng->txt("used") . '"';
4194 $titles[] = '"' . $lng->txt("mail_sent_short") . '"';
4195 $titles[] = '"' . $lng->txt("survey_code_url") . '"';
4196 $export[] = implode(";", $titles);
4197
4198 $result = $ilDB->query($sql);
4199 $default_lang = $ilUser->getPref("survey_code_language");
4200 while ($row = $ilDB->fetchAssoc($result)) {
4201 $item = array();
4202 $item[] = $row["survey_key"];
4203
4204 if ($row["externaldata"]) {
4205 $ext = unserialize($row["externaldata"]);
4206 $item[] = $ext["email"];
4207 $item[] = $ext["lastname"];
4208 $item[] = $ext["firstname"];
4209 } else {
4210 $item[] = "";
4211 $item[] = "";
4212 $item[] = "";
4213 }
4214
4215 // No relative (today, tomorrow...) dates in export.
4216 $date = new ilDateTime($row['tstamp'], IL_CAL_UNIX);
4217 $item[] = $date->get(IL_CAL_DATETIME);
4218
4219 $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4220 $item[] = ($row["sent"]) ? 1 : 0;
4221
4222 $params = array("accesscode" => $row["survey_key"]);
4223 if ($default_lang) {
4224 $params["lang"] = $default_lang;
4225 }
4226 $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4227
4228 $export[] = '"' . implode('";"', $item) . '"';
4229 }
4230 return implode("\n", $export);
4231 }
4232
4240 public function getSurveyCodesTableData(array $ids = null, $lang = null)
4241 {
4242 $ilDB = $this->db;
4243
4244 include_once "./Services/Link/classes/class.ilLink.php";
4245
4246 $codes = array();
4247
4248 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4249 " FROM svy_anonymous" .
4250 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4251 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") /*.
4252 " AND svy_anonymous.user_key IS NULL" */; // #15860
4253
4254 if ($ids) {
4255 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4256 }
4257
4258 $sql .= " ORDER BY tstamp, survey_key ASC";
4259 $result = $ilDB->query($sql);
4260 if ($result->numRows() > 0) {
4261 while ($row = $ilDB->fetchAssoc($result)) {
4262 $href = "";
4263 $used = false;
4264 if ($this->isSurveyCodeUsed($row["survey_key"])) {
4265 $used = true;
4266 } else {
4267 $params = array("accesscode" => $row["survey_key"]);
4268 if ($lang) {
4269 $params["lang"] = $lang;
4270 }
4271 $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4272 }
4273
4274
4275 $item = array(
4276 'id' => $row["anonymous_id"],
4277 'code' => $row["survey_key"],
4278 'date' => $row["tstamp"],
4279 'used' => $used,
4280 'sent' => $row['sent'],
4281 'href' => $href,
4282 'email' => '',
4283 'last_name' => '',
4284 'first_name' => ''
4285 );
4286
4287 if ($row["externaldata"]) {
4288 $ext = unserialize($row["externaldata"]);
4289 $item['email'] = $ext['email'];
4290 $item['last_name'] = $ext['lastname'];
4291 $item['first_name'] = $ext['firstname'];
4292 }
4293
4294 array_push($codes, $item);
4295 }
4296 }
4297 return $codes;
4298 }
4299
4300 public function isSurveyCodeUsed($code)
4301 {
4302 $ilDB = $this->db;
4303 $result = $ilDB->queryF(
4304 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4305 array('integer','text'),
4306 array($this->getSurveyId(), $code)
4307 );
4308 return ($result->numRows() > 0) ? true : false;
4309 }
4310
4311 public function isSurveyCodeUnique($code)
4312 {
4313 $ilDB = $this->db;
4314 $result = $ilDB->queryF(
4315 "SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4316 array('integer','text'),
4317 array($this->getSurveyId(), $code)
4318 );
4319 return ($result->numRows() > 0) ? false : true;
4320 }
4321
4322 public function createSurveyCodes($nrOfCodes)
4323 {
4324 $ilDB = $this->db;
4325
4326 $res = array();
4327
4328 for ($i = 0; $i < $nrOfCodes; $i++) {
4329 $next_id = $ilDB->nextId('svy_anonymous');
4330 $ilDB->manipulateF(
4331 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) " .
4332 "VALUES (%s, %s, %s, %s)",
4333 array('integer','text','integer','integer'),
4334 array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4335 );
4336 $res[] = $next_id;
4337 }
4338
4339 return $res;
4340 }
4341
4342 public function importSurveyCode($a_anonymize_key, $a_created, $a_data)
4343 {
4344 $ilDB = $this->db;
4345
4346 $next_id = $ilDB->nextId('svy_anonymous');
4347 $ilDB->manipulateF(
4348 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4349 "VALUES (%s, %s, %s, %s, %s)",
4350 array('integer','text','integer','text','integer'),
4351 array($next_id, $a_anonymize_key, $this->getSurveyId(), serialize($a_data), $a_created)
4352 );
4353 }
4354
4356 {
4357 $ilDB = $this->db;
4358
4359 $ids = array();
4360 foreach ($data as $dataset) {
4361 $anonymize_key = $this->createNewAccessCode();
4362 $next_id = $ilDB->nextId('svy_anonymous');
4363 $affectedRows = $ilDB->manipulateF(
4364 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4365 "VALUES (%s, %s, %s, %s, %s)",
4366 array('integer','text','integer','text','integer'),
4367 array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
4368 );
4369 $ids[] = $next_id;
4370 }
4371 return $ids;
4372 }
4373
4374 public function sendCodes($not_sent, $subject, $message, $lang)
4375 {
4376 global $DIC;
4377 /*
4378 * 0 = all
4379 * 1 = not sent
4380 * 2 = finished
4381 * 3 = not finished
4382 */
4383 $check_finished = ($not_sent > 1);
4384
4385 include_once "./Services/Mail/classes/class.ilMail.php";
4386 include_once "./Services/Link/classes/class.ilLink.php";
4387
4388 #19956
4389 $user_id = $DIC->user()->getId();
4390 $mail = new ilMail($user_id);
4391 $recipients = $this->getExternalCodeRecipients($check_finished);
4392 foreach ($recipients as $data) {
4393 if ($data['email'] && $data['code']) {
4394 $do_send = false;
4395 switch ((int) $not_sent) {
4396 case 1:
4397 $do_send = !(bool) $data['sent'];
4398 break;
4399
4400 case 2:
4401 $do_send = $data['finished'];
4402 break;
4403
4404 case 3:
4405 $do_send = !$data['finished'];
4406 break;
4407
4408 default:
4409 $do_send = true;
4410 break;
4411 }
4412 if ($do_send) {
4413 // build text
4414 $messagetext = $message;
4416 $this->getRefId(),
4417 "svy",
4418 array(
4419 "accesscode" => $data["code"],
4420 "lang" => $lang
4421 )
4422 );
4423 $messagetext = str_replace('[url]', $url, $messagetext);
4424 foreach ($data as $key => $value) {
4425 $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
4426 }
4427
4428 // send mail
4429 $mail->sendMail(
4430 $data['email'], // to
4431 "", // cc
4432 "", // bcc
4433 $subject, // subject
4434 $messagetext, // message
4435 array(), // attachments
4436 array('normal') // type
4437 );
4438 }
4439 }
4440 }
4441
4442 $ilDB = $this->db;
4443 $ilDB->manipulateF(
4444 "UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
4445 array('integer','integer'),
4446 array(1, $this->getSurveyId())
4447 );
4448 }
4449
4450 public function getExternalCodeRecipients($a_check_finished = false)
4451 {
4452 $ilDB = $this->db;
4453 $result = $ilDB->queryF(
4454 "SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
4455 array('integer'),
4456 array($this->getSurveyId())
4457 );
4458 $res = array();
4459 while ($row = $ilDB->fetchAssoc($result)) {
4460 if (!$row['externaldata']) {
4461 continue;
4462 }
4463
4464 $externaldata = unserialize($row['externaldata']);
4465 if (!$externaldata['email']) {
4466 continue;
4467 }
4468
4469 $externaldata['code'] = $row['code'];
4470 $externaldata['sent'] = $row['sent'];
4471
4472 if ($a_check_finished) {
4473 #23294
4474 //$externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
4475 $externaldata['finished'] = $this->isSurveyFinishedByCode($row['code']);
4476 }
4477
4478 array_push($res, $externaldata);
4479 }
4480 return $res;
4481 }
4482
4488 public function isSurveyFinishedByCode($a_code)
4489 {
4490 $result = $this->db->queryF(
4491 "SELECT state FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4492 array('integer','text'),
4493 array($this->getSurveyId(), $a_code)
4494 );
4495
4496 $row = $this->db->fetchAssoc($result);
4497
4498 return $row['state'];
4499 }
4500
4506 public function deleteSurveyCode($survey_code)
4507 {
4508 $ilDB = $this->db;
4509
4510 if (strlen($survey_code) > 0) {
4511 $affectedRows = $ilDB->manipulateF(
4512 "DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4513 array('integer', 'text'),
4514 array($this->getSurveyId(), $survey_code)
4515 );
4516 }
4517 }
4518
4525 public function getUserAccessCode($user_id)
4526 {
4527 $ilDB = $this->db;
4528 $access_code = "";
4529 $result = $ilDB->queryF(
4530 "SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
4531 array('integer','text'),
4532 array($this->getSurveyId(), md5($user_id))
4533 );
4534 if ($result->numRows()) {
4535 $row = $ilDB->fetchAssoc($result);
4536 $access_code = $row["survey_key"];
4537 }
4538 return $access_code;
4539 }
4540
4547 public function saveUserAccessCode($user_id, $access_code)
4548 {
4549 $ilDB = $this->db;
4550
4551 // not really sure what to do about ANONYMOUS_USER_ID
4552
4553 $next_id = $ilDB->nextId('svy_anonymous');
4554 $affectedRows = $ilDB->manipulateF(
4555 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) " .
4556 "VALUES (%s, %s, %s, %s, %s)",
4557 array('integer','text', 'integer', 'text', 'integer'),
4558 array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
4559 );
4560 }
4561
4567 public function createNewAccessCode()
4568 {
4569 // create a 5 character code
4570 $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4571 mt_srand();
4572 $code = "";
4573 for ($i = 1; $i <=5; $i++) {
4574 $index = mt_rand(0, strlen($codestring)-1);
4575 $code .= substr($codestring, $index, 1);
4576 }
4577 // verify it against the database
4578 while (!$this->isSurveyCodeUnique($code)) {
4579 $code = $this->createNewAccessCode();
4580 }
4581 return $code;
4582 }
4583
4584 public function getLastAccess($finished_id)
4585 {
4586 $ilDB = $this->db;
4587
4588 $result = $ilDB->queryF(
4589 "SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
4590 array('integer'),
4591 array($finished_id)
4592 );
4593 if ($result->numRows()) {
4594 $row = $ilDB->fetchAssoc($result);
4595 return $row["tstamp"];
4596 } else {
4597 $result = $ilDB->queryF(
4598 "SELECT tstamp FROM svy_finished WHERE finished_id = %s",
4599 array('integer'),
4600 array($finished_id)
4601 );
4602 if ($result->numRows()) {
4603 $row = $ilDB->fetchAssoc($result);
4604 return $row["tstamp"];
4605 }
4606 }
4607 return "";
4608 }
4609
4616 public function prepareTextareaOutput($txt_output)
4617 {
4618 return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
4619 }
4620
4628 public function isHTML($a_text)
4629 {
4630 if (preg_match("/<[^>]*?>/", $a_text)) {
4631 return true;
4632 } else {
4633 return false;
4634 }
4635 }
4636
4645 public function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = true, $add_mobs = true, $attribs = null)
4646 {
4647 include_once "./Services/RTE/classes/class.ilRTE.php";
4648 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
4649
4650 $a_xml_writer->xmlStartTag("material", $attribs);
4651 $attrs = array(
4652 "type" => "text/plain"
4653 );
4654 if ($this->isHTML($a_material)) {
4655 $attrs["type"] = "text/xhtml";
4656 }
4657 $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
4658 $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
4659
4660 if ($add_mobs) {
4661 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
4662 foreach ($mobs as $mob) {
4663 $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
4664 if (strpos($mattext, $mob_id) !== false) {
4665 $mob_obj = new ilObjMediaObject($mob);
4666 $imgattrs = array(
4667 "label" => $mob_id,
4668 "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
4669 "type" => "svy:html",
4670 "id" => $this->getId()
4671 );
4672 $a_xml_writer->xmlElement("matimage", $imgattrs, null);
4673 }
4674 }
4675 }
4676 if ($close_material_tag) {
4677 $a_xml_writer->xmlEndTag("material");
4678 }
4679 }
4680
4689 public function canExportSurveyCode()
4690 {
4691 if ($this->getAnonymize() != self::ANONYMIZE_OFF) {
4692 if ($this->surveyCodeSecurity == false) {
4693 return true;
4694 }
4695 }
4696 return false;
4697 }
4698
4706 public function processPrintoutput2FO($print_output)
4707 {
4708 if (extension_loaded("tidy")) {
4709 $config = array(
4710 "indent" => false,
4711 "output-xml" => true,
4712 "numeric-entities" => true
4713 );
4714 $tidy = new tidy();
4715 $tidy->parseString($print_output, $config, 'utf8');
4716 $tidy->cleanRepair();
4717 $print_output = tidy_get_output($tidy);
4718 $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
4719 } else {
4720 $print_output = str_replace("&nbsp;", "&#160;", $print_output);
4721 $print_output = str_replace("&otimes;", "X", $print_output);
4722
4723 // #17680 - metric questions use &#160; in print view
4724 $print_output = str_replace("&gt;", "~|gt|~", $print_output); // see #21550
4725 $print_output = str_replace("&lt;", "~|lt|~", $print_output);
4726 $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
4727 $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
4728 $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
4729 $print_output = str_replace("~|gt|~", "&gt;", $print_output);
4730 $print_output = str_replace("~|lt|~", "&lt;", $print_output);
4731 }
4732 $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
4733
4734 // additional font support
4735 $xsl = str_replace(
4736 'font-family="Helvetica, unifont"',
4737 'font-family="' . $GLOBALS['ilSetting']->get('rpc_pdf_font', 'Helvetica, unifont') . '"',
4738 $xsl
4739 );
4740 $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
4741 $xh = xslt_create();
4742 $params = array();
4743 try {
4744 $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
4745 } catch (Exception $e) {
4746 $this->log->error("Print XSLT failed:");
4747 $this->log->error("Content: " . $print_output);
4748 $this->log->error("Xsl: " . $xsl);
4749 throw ($e);
4750 }
4751 xslt_error($xh);
4752 xslt_free($xh);
4753
4754 return $output;
4755 }
4756
4763 public function deliverPDFfromFO($fo)
4764 {
4766
4767 $fo_file = ilUtil::ilTempnam() . ".fo";
4768 $fp = fopen($fo_file, "w");
4769 fwrite($fp, $fo);
4770 fclose($fp);
4771
4772 include_once './Services/WebServices/RPC/classes/class.ilRpcClientFactory.php';
4773 try {
4774 $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
4775 ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
4776 return true;
4777 } catch (Exception $e) {
4778 $ilLog->write(__METHOD__ . ': ' . $e->getMessage());
4779 return false;
4780 }
4781 }
4782
4789 public function isPluginActive($a_pname)
4790 {
4791 $ilPluginAdmin = $this->plugin_admin;
4792 if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname)) {
4793 return true;
4794 } else {
4795 return false;
4796 }
4797 }
4798
4804 public function setSurveyId($survey_id)
4805 {
4806 $this->survey_id = $survey_id;
4807 }
4808
4815 public function &getUserData($ids)
4816 {
4817 $ilDB = $this->db;
4818
4819 if (!is_array($ids) || count($ids) ==0) {
4820 return array();
4821 }
4822
4823 $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
4824 $result_array = array();
4825 while ($row = $ilDB->fetchAssoc($result)) {
4826 $result_array[$row["usr_id"]]= $row;
4827 }
4828 return $result_array;
4829 }
4830
4831 public function getMailNotification()
4832 {
4834 }
4835
4836 public function setMailNotification($a_notification)
4837 {
4838 $this->mailnotification = ($a_notification) ? true : false;
4839 }
4840
4841 public function getMailAddresses()
4842 {
4843 return $this->mailaddresses;
4844 }
4845
4846 public function setMailAddresses($a_addresses)
4847 {
4848 $this->mailaddresses = $a_addresses;
4849 }
4850
4851 public function getMailParticipantData()
4852 {
4854 }
4855
4856 public function setMailParticipantData($a_data)
4857 {
4858 $this->mailparticipantdata = $a_data;
4859 }
4860
4861 public function setStartTime($finished_id, $first_question)
4862 {
4863 $ilDB = $this->db;
4864 $time = time();
4865 //primary for table svy_times
4866 $id = $ilDB->nextId('svy_times');
4867 $_SESSION['svy_entered_page'] = $time;
4868 $affectedRows = $ilDB->manipulateF(
4869 "INSERT INTO svy_times (id, finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s,%s)",
4870 array('integer','integer', 'integer', 'integer', 'integer'),
4871 array($id, $finished_id, $time, null, $first_question)
4872 );
4873 }
4874
4875 public function setEndTime($finished_id)
4876 {
4877 $ilDB = $this->db;
4878 $time = time();
4879 $affectedRows = $ilDB->manipulateF(
4880 "UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
4881 array('integer', 'integer', 'integer'),
4882 array($time, $finished_id, $_SESSION['svy_entered_page'])
4883 );
4884 unset($_SESSION['svy_entered_page']);
4885 }
4886
4887 public function getWorkingtimeForParticipant($finished_id)
4888 {
4889 $ilDB = $this->db;
4890
4891 $result = $ilDB->queryF(
4892 "SELECT * FROM svy_times WHERE finished_fi = %s",
4893 array('integer'),
4894 array($finished_id)
4895 );
4896 $total = 0;
4897 while ($row = $ilDB->fetchAssoc($result)) {
4898 if ($row['left_page'] > 0 && $row['entered_page'] > 0) {
4899 $total += $row['left_page'] - $row['entered_page'];
4900 }
4901 }
4902 return $total;
4903 }
4904
4905 public function setTemplate($template_id)
4906 {
4907 $this->template_id = (int) $template_id;
4908 }
4909
4910 public function getTemplate()
4911 {
4912 return $this->template_id;
4913 }
4914
4915 public function updateOrder(array $a_order)
4916 {
4917 if (sizeof($this->questions) == sizeof($a_order)) {
4918 $this->questions = array_flip($a_order);
4919 $this->saveQuestionsToDB();
4920 }
4921 }
4922
4923 public function getPoolUsage()
4924 {
4925 return $this->pool_usage;
4926 }
4927
4928 public function setPoolUsage($a_value)
4929 {
4930 $this->pool_usage = (bool) $a_value;
4931 }
4932
4938 public function isPoolActive()
4939 {
4940 $use_pool = (bool) $this->getPoolUsage();
4941 $template_settings = $this->getTemplate();
4942 if ($template_settings) {
4943 include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
4944 $template_settings = new ilSettingsTemplate($template_settings);
4945 $template_settings = $template_settings->getSettings();
4946 $template_settings = $template_settings["use_pool"];
4947 if ($template_settings && $template_settings["hide"]) {
4948 $use_pool = (bool) $template_settings["value"];
4949 }
4950 }
4951 return $use_pool;
4952 }
4953
4960 {
4961 if (!$template_id) {
4962 return;
4963 }
4964
4965 include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
4967 $template_settings = $template->getSettings();
4968 //ilUtil::dumpVar($template_settings); exit;
4969 if ($template_settings) {
4970 if ($template_settings["show_question_titles"] !== null) {
4971 if ($template_settings["show_question_titles"]["value"]) {
4972 $this->setShowQuestionTitles(true);
4973 } else {
4974 $this->setShowQuestionTitles(false);
4975 }
4976 }
4977
4978 if ($template_settings["use_pool"] !== null) {
4979 if ($template_settings["use_pool"]["value"]) {
4980 $this->setPoolUsage(true);
4981 } else {
4982 $this->setPoolUsage(false);
4983 }
4984 }
4985
4986
4987 /* see #0021719
4988 if($template_settings["anonymization_options"]["value"])
4989 {
4990 $anon_map = array('personalized' => self::ANONYMIZE_OFF,
4991 'anonymize_with_code' => self::ANONYMIZE_ON,
4992 'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
4993 $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
4994 }*/
4995
4996 // see #0021719 and ilObjectSurveyGUI::savePropertiesObject
4997 $this->setEvaluationAccess($template_settings["evaluation_access"]["value"]);
4998 $codes = (bool) $template_settings["acc_codes"]["value"];
4999 $anon = (bool) $template_settings["anonymization_options"]["value"];
5000 if (!$anon) {
5001 if (!$codes) {
5003 } else {
5005 }
5006 } else {
5007 if ($codes) {
5009 } else {
5011 }
5012
5013 $this->setAnonymousUserList($_POST["anon_list"]);
5014 }
5015
5016
5017
5018 /* other settings: not needed here
5019 * - enabled_end_date
5020 * - enabled_start_date
5021 * - rte_switch
5022 */
5023 }
5024
5025 $this->setTemplate($template_id);
5026 $this->saveToDb();
5027 }
5028
5029 public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
5030 {
5031 $ilDB = $this->db;
5032
5033 $a_email = trim($a_email);
5034
5035 // :TODO:
5036 if (($a_email && !ilUtil::is_email($a_email)) || $a_email == "") {
5037 return false;
5038 }
5039
5040 $data = array("email" => $a_email,
5041 "lastname" => trim($a_last_name),
5042 "firstname" => trim($a_first_name));
5043
5044 $fields = array(
5045 "externaldata" => array("text", serialize($data)),
5046 "sent" => array("integer", $a_sent)
5047 );
5048
5049 $ilDB->update(
5050 "svy_anonymous",
5051 $fields,
5052 array("anonymous_id" => array("integer", $a_id))
5053 );
5054
5055 return true;
5056 }
5057
5058
5059 //
5060 // 360°
5061 //
5062
5063 public function set360Mode($a_value)
5064 {
5065 $this->mode_360 = (bool) $a_value;
5066 }
5067
5068 public function get360Mode()
5069 {
5070 return (bool) $this->mode_360;
5071 }
5072
5073 public function set360SelfEvaluation($a_value)
5074 {
5075 $this->mode_360_self_eval = (bool) $a_value;
5076 }
5077
5078 public function get360SelfEvaluation()
5079 {
5080 return (bool) $this->mode_360_self_eval;
5081 }
5082
5083 public function set360SelfAppraisee($a_value)
5084 {
5085 $this->mode_360_self_appr = (bool) $a_value;
5086 }
5087
5088 public function get360SelfAppraisee()
5089 {
5090 return (bool) $this->mode_360_self_appr;
5091 }
5092
5093 public function set360SelfRaters($a_value)
5094 {
5095 $this->mode_360_self_rate = (bool) $a_value;
5096 }
5097
5098 public function get360SelfRaters()
5099 {
5100 return (bool) $this->mode_360_self_rate;
5101 }
5102
5103 public function set360Results($a_value)
5104 {
5105 $this->mode_360_results = (int) $a_value;
5106 }
5107
5108 public function get360Results()
5109 {
5110 return (int) $this->mode_360_results;
5111 }
5112
5113 public function addAppraisee($a_user_id)
5114 {
5115 global $DIC;
5116
5117 $ilDB = $DIC->database();
5118 $access = $DIC->access();
5119
5120 if (!$this->isAppraisee($a_user_id) &&
5121 $a_user_id != ANONYMOUS_USER_ID) {
5122 $fields = array(
5123 "obj_id" => array("integer", $this->getSurveyId()),
5124 "user_id" => array("integer", $a_user_id)
5125 );
5126 $ilDB->insert("svy_360_appr", $fields);
5127
5128 // send notification and add to desktop
5129 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
5130 $this->sendAppraiseeNotification($a_user_id);
5131 $type = ilObject::_lookupType($this->getRefId(), true);
5132 ilObjUser::_addDesktopItem($a_user_id, $this->getRefId(), $type);
5133 }
5134 }
5135 }
5136
5142 public function sendAppraiseeNotification($a_user_id)
5143 {
5144 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5145 $ntf = new ilSystemNotification();
5146 $ntf->setLangModules(array("svy", "survey"));
5147 $ntf->setRefId($this->getRefId());
5148 $ntf->setGotoLangId('url');
5149
5150 // user specific language
5151 $lng = $ntf->getUserLanguage($a_user_id);
5152
5153 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_mail");
5154 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
5155
5156 // #10044
5157 $mail = new ilMail(ANONYMOUS_USER_ID);
5158 //$mail->enableSOAP(false); // #10410
5159 $mail->sendMail(
5160 ilObjUser::_lookupLogin($a_user_id),
5161 null,
5162 null,
5163 $subject,
5164 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5165 null,
5166 array("system")
5167 );
5168 }
5169
5175 public function sendAppraiseeCloseNotification($a_user_id)
5176 {
5177 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5178 $ntf = new ilSystemNotification();
5179 $ntf->setLangModules(array("svy", "survey"));
5180 $ntf->setRefId($this->getRefId());
5181 $ntf->setGotoLangId('url');
5182
5183 // user specific language
5184 $lng = $ntf->getUserLanguage($a_user_id);
5185
5186 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_close_mail");
5187 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
5188
5189 // #10044
5190 $mail = new ilMail(ANONYMOUS_USER_ID);
5191 //$mail->enableSOAP(false); // #10410
5192 $mail->sendMail(
5193 ilObjUser::_lookupLogin($a_user_id),
5194 null,
5195 null,
5196 $subject,
5197 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5198 null,
5199 array("system")
5200 );
5201 }
5202
5208 public function sendRaterNotification($a_user_id, $a_appraisee_id)
5209 {
5210 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5211 $ntf = new ilSystemNotification();
5212 $ntf->setLangModules(array("svy", "survey"));
5213 $ntf->setRefId($this->getRefId());
5214 $ntf->setGotoLangId('url');
5215
5216 // user specific language
5217 $lng = $ntf->getUserLanguage($a_user_id);
5218
5219 $ntf->setIntroductionLangId("svy_user_added_360_rater_mail");
5220 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5221 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($a_appraisee_id, false, false, "", true));
5222
5223 // #10044
5224 $mail = new ilMail(ANONYMOUS_USER_ID);
5225 //$mail->enableSOAP(false); // #10410
5226 $mail->sendMail(
5227 ilObjUser::_lookupLogin($a_user_id),
5228 null,
5229 null,
5230 $subject,
5231 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5232 null,
5233 array("system")
5234 );
5235 }
5236
5237 public function isAppraisee($a_user_id)
5238 {
5239 $ilDB = $this->db;
5240
5241 $set = $ilDB->query("SELECT user_id" .
5242 " FROM svy_360_appr" .
5243 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5244 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5245 return (bool) $ilDB->numRows($set);
5246 }
5247
5248 public function isAppraiseeClosed($a_user_id)
5249 {
5250 $ilDB = $this->db;
5251
5252 $set = $ilDB->query("SELECT has_closed" .
5253 " FROM svy_360_appr" .
5254 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5255 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5256 $row = $ilDB->fetchAssoc($set);
5257 return $row["has_closed"];
5258 }
5259
5260 public function deleteAppraisee($a_user_id)
5261 {
5262 $ilDB = $this->db;
5263
5264 $ilDB->manipulate("DELETE FROM svy_360_appr" .
5265 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5266 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5267
5268 $set = $ilDB->query("SELECT user_id" .
5269 " FROM svy_360_rater" .
5270 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5271 " AND appr_id = " . $ilDB->quote($a_user_id, "integer"));
5272 while ($row = $ilDB->fetchAssoc($set)) {
5273 $this->deleteRater($a_user_id, $row["user_id"]);
5274 }
5275 // appraisee will not be part of raters table
5276 if ($this->get360SelfEvaluation()) {
5277 $this->deleteRater($a_user_id, $a_user_id);
5278 }
5279 }
5280
5281 public function getAppraiseesData()
5282 {
5283 $ilDB = $this->db;
5284
5285 $res = array();
5286
5287 $set = $ilDB->query("SELECT * FROM svy_360_appr" .
5288 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5289 while ($row = $ilDB->fetchAssoc($set)) {
5290 $name = ilObjUser::_lookupName($row["user_id"]);
5291 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5292 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5293 $res[$row["user_id"]] = $name;
5294
5295 $finished = 0;
5296 $raters = $this->getRatersData($row["user_id"]);
5297 foreach ($raters as $rater) {
5298 if ($rater["finished"]) {
5299 $finished++;
5300 }
5301 }
5302 $res[$row["user_id"]]["finished"] = $finished . "/" . sizeof($raters);
5303 $res[$row["user_id"]]["closed"] = $row["has_closed"];
5304 }
5305
5306 return $res;
5307 }
5308
5309 public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5310 {
5311 global $DIC;
5312
5313 $ilDB = $DIC->database();
5314 $access = $DIC->access();
5315
5316 if ($this->isAppraisee($a_appraisee_id) &&
5317 !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id)) {
5318 $fields = array(
5319 "obj_id" => array("integer", $this->getSurveyId()),
5320 "appr_id" => array("integer", $a_appraisee_id),
5321 "user_id" => array("integer", $a_user_id),
5322 "anonymous_id" => array("integer", $a_anonymous_id)
5323 );
5324 $ilDB->insert("svy_360_rater", $fields);
5325
5326 // send notification and add to desktop
5327 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
5328 $this->sendRaterNotification($a_user_id, $a_appraisee_id);
5329 $type = ilObject::_lookupType($this->getRefId(), true);
5330 ilObjUser::_addDesktopItem($a_user_id, $this->getRefId(), $type);
5331 }
5332 }
5333 }
5334
5335 public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5336 {
5337 $ilDB = $this->db;
5338
5339 // user is rater if already appraisee and active self-evaluation
5340 if ($this->isAppraisee($a_user_id) &&
5341 $this->get360SelfEvaluation() &&
5342 (!$a_appraisee_id || $a_appraisee_id == $a_user_id)) {
5343 return true;
5344 }
5345
5346 // :TODO: should we get rid of code as well?
5347
5348 $sql = "SELECT user_id" .
5349 " FROM svy_360_rater" .
5350 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5351 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5352 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5353 if ($a_appraisee_id) {
5354 $sql .= " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer");
5355 }
5356 $set = $ilDB->query($sql);
5357 return (bool) $ilDB->numRows($set);
5358 }
5359
5360 public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5361 {
5362 $ilDB = $this->db;
5363
5364 $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5365 if ($finished_id) {
5366 $this->removeSelectedSurveyResults(array($finished_id));
5367 }
5368
5369 $ilDB->manipulate("DELETE FROM svy_360_rater" .
5370 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5371 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5372 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5373 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5374 }
5375
5376 public function getRatersData($a_appraisee_id)
5377 {
5378 $ilDB = $this->db;
5379
5380 $res = $anonymous_ids = array();
5381
5382 $set = $ilDB->query("SELECT * FROM svy_360_rater" .
5383 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5384 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer"));
5385 while ($row = $ilDB->fetchAssoc($set)) {
5386 if ($row["anonymous_id"]) {
5387 $res["a" . $row["anonymous_id"]] = array(
5388 "lastname" => "unknown code " . $row["anonymous_id"],
5389 "sent" => $row["mail_sent"],
5390 "finished" => null
5391 );
5392 $anonymous_ids[] = $row["anonymous_id"];
5393 } else {
5394 $name = ilObjUser::_lookupName($row["user_id"]);
5395 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5396 $name["user_id"] = "u" . $name["user_id"];
5397 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5398 $name["sent"] = $row["mail_sent"];
5399 $name["finished"] = (bool) $this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
5400 $res["u" . $row["user_id"]] = $name;
5401 }
5402 }
5403
5404 if (sizeof($anonymous_ids)) {
5405 $data = $this->getSurveyCodesTableData($anonymous_ids);
5406 foreach ($data as $item) {
5407 if (isset($res["a" . $item["id"]])) {
5408 $res["a" . $item["id"]] = array(
5409 "user_id" => "a" . $item["id"],
5410 "lastname" => $item["last_name"],
5411 "firstname" => $item["first_name"],
5412 "name" => $item["last_name"] . ", " . $item["first_name"],
5413 "login" => "",
5414 "email" => $item["email"],
5415 "code" => $item["code"],
5416 "href" => $item["href"],
5417 "sent" => $res["a" . $item["id"]]["sent"],
5418 "finished" => (bool) $this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
5419 );
5420 }
5421 }
5422 }
5423
5424 return $res;
5425 }
5426
5427 public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
5428 {
5429 $ilDB = $this->db;
5430
5431 $res = array();
5432
5433 $sql = "SELECT appr_id FROM svy_360_rater" .
5434 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer");
5435
5436 if ($a_user_id) {
5437 $sql .= " AND user_id = " . $ilDB->quote($a_user_id, "integer");
5438 } else {
5439 $sql .= " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5440 }
5441
5442 $set = $ilDB->query($sql);
5443 while ($row = $ilDB->fetchAssoc($set)) {
5444 $res[] = $row["appr_id"];
5445 }
5446
5447 // user may evaluate himself if already appraisee
5448 if ($this->get360SelfEvaluation() &&
5449 $this->isAppraisee($a_user_id) &&
5450 !in_array($a_user_id, $res)) {
5451 $res[] = $a_user_id;
5452 }
5453
5454 return $res;
5455 }
5456
5457 public function getAnonymousIdByCode($a_code)
5458 {
5459 $ilDB = $this->db;
5460
5461 $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous" .
5462 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5463 " AND survey_key = " . $ilDB->quote($a_code, "text"));
5464 $res = $ilDB->fetchAssoc($set);
5465 return $res["anonymous_id"];
5466 }
5467
5468 public function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
5469 {
5470 $ilDB = $this->db;
5471
5472 $sql = "SELECT * FROM svy_finished" .
5473 " WHERE survey_fi =" . $ilDB->quote($this->getSurveyId(), "integer") .
5474 " AND appr_id = " . $ilDB->quote($appr_id, "integer");
5475 if ($user_id) {
5476 $sql .= " AND user_fi = " . $ilDB->quote($user_id, "integer");
5477 } else {
5478 $sql .= " AND anonymous_id = " . $ilDB->quote($anonymous_code, "text");
5479 }
5480 $result = $ilDB->query($sql);
5481 if ($result->numRows() == 0) {
5482 return false;
5483 } else {
5484 $row = $ilDB->fetchAssoc($result);
5485 return (int) $row["state"];
5486 }
5487 }
5488
5489 public function getUserSurveyExecutionStatus($a_code = null)
5490 {
5492 $ilDB = $this->db;
5493
5494 $user_id = $ilUser->getId();
5495
5496 // code is obligatory?
5497 if (!$this->isAccessibleWithoutCode()) {
5498 if (!$a_code) {
5499 // registered raters do not need code
5500 if ($this->get360Mode() &&
5501 $user_id != ANONYMOUS_USER_ID &&
5502 $this->isRater(0, $user_id)) {
5503 // auto-generate code
5504 $a_code = $this->createNewAccessCode();
5505 $this->saveUserAccessCode($user_id, $a_code);
5506 } else {
5507 return null;
5508 }
5509 }
5510 } elseif ($user_id == ANONYMOUS_USER_ID ||
5511 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS) {
5512 if (!$a_code) {
5513 // auto-generate code
5514 $a_code = $this->createNewAccessCode();
5515 $this->saveUserAccessCode($user_id, $a_code);
5516 }
5517 } else {
5518 $a_code = null;
5519 }
5520
5521 $res = array();
5522
5523 $sql = "SELECT * FROM svy_finished" .
5524 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
5525 // if proper user id is given, use it or current code
5526 if ($user_id != ANONYMOUS_USER_ID) {
5527 $sql .= " AND (user_fi = " . $ilDB->quote($user_id, "integer") .
5528 " OR anonymous_id = " . $ilDB->quote($a_code, "text") . ")";
5529 }
5530 // use anonymous code to find finished id(s)
5531 else {
5532 $sql .= " AND anonymous_id = " . $ilDB->quote($a_code, "text");
5533 }
5534 $set = $ilDB->query($sql);
5535 while ($row = $ilDB->fetchAssoc($set)) {
5536 $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
5537 "user_id" => $row["user_fi"],
5538 "code" => $row["anonymous_id"],
5539 "finished" => (bool) $row["state"]);
5540 }
5541
5542 return array("code"=>$a_code, "runs"=>$res);
5543 }
5544
5545 public function findCodeForUser($a_user_id)
5546 {
5547 $ilDB = $this->db;
5548
5549 if ($a_user_id != ANONYMOUS_USER_ID) {
5550 $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf" .
5551 " WHERE sf.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5552 " AND sf.user_fi = " . $ilDB->quote($a_user_id, "integer"));
5553 $a_code = $ilDB->fetchAssoc($set);
5554 return $a_code["anonymous_id"];
5555 }
5556 }
5557
5558 public function isUnusedCode($a_code, $a_user_id)
5559 {
5560 $ilDB = $this->db;
5561
5562 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
5563 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5564 " AND anonymous_id = " . $ilDB->quote($a_code, "text"));
5565 $user_id = $ilDB->fetchAssoc($set);
5566 $user_id = $user_id["user_fi"];
5567
5568 if ($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID)) {
5569 return false;
5570 }
5571 return true;
5572 }
5573
5574 public function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
5575 {
5576 $ilDB = $this->db;
5577
5578 $res = array();
5579
5580 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5581 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5582 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer"));
5583 while ($row = $ilDB->fetchAssoc($set)) {
5584 if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id) {
5585 continue;
5586 }
5587 $res[] = $row["finished_id"];
5588 }
5589
5590 return $res;
5591 }
5592
5600 public function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
5601 {
5602 $ilDB = $this->db;
5603
5604 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5605 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5606 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer") .
5607 " AND user_fi = " . $ilDB->quote($a_rat_id, "integer"));
5608 $row = $ilDB->fetchAssoc($set);
5609 return $row["finished_id"];
5610 }
5611
5612
5613 // 360° using competence/skill service
5614
5620 public function set360SkillService($a_val)
5621 {
5622 $this->mode_360_skill_service = $a_val;
5623 }
5624
5630 public function get360SkillService()
5631 {
5633 }
5634
5635 public function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
5636 {
5637 $ilDB = $this->db;
5638
5639 if (!$a_tstamp) {
5640 $a_tstamp = time();
5641 }
5642
5643 $ilDB->manipulate("UPDATE svy_360_rater" .
5644 " SET mail_sent = " . $ilDB->quote($a_tstamp, "integer") .
5645 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5646 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5647 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5648 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5649 }
5650
5651 public function closeAppraisee($a_user_id)
5652 {
5653 global $DIC;
5654
5655 $ilDB = $DIC->database();
5656 $user = $DIC->user();
5657
5658 // close the appraisee
5659 $ilDB->manipulate("UPDATE svy_360_appr" .
5660 " SET has_closed = " . $ilDB->quote(time(), "integer") .
5661 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5662 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5663
5664 // write competences
5665 include_once("./Services/Skill/classes/class.ilSkillManagementSettings.php");
5666 $skmg_set = new ilSkillManagementSettings();
5667 if ($this->get360SkillService() && $skmg_set->isActivated()) {
5668 include_once("./Modules/Survey/classes/class.ilSurveySkill.php");
5669 $sskill = new ilSurveySkill($this);
5670 $sskill->writeAppraiseeSkills($a_user_id);
5671 }
5672
5673 // send notification
5674 if ($user->getId() != $a_user_id) {
5675 $this->sendAppraiseeCloseNotification($a_user_id);
5676 }
5677 }
5678
5679 public function openAllAppraisees()
5680 {
5681 $ilDB = $this->db;
5682
5683 $ilDB->manipulate("UPDATE svy_360_appr" .
5684 " SET has_closed = " . $ilDB->quote(null, "integer") .
5685 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5686 }
5687
5688 public static function validateExternalRaterCode($a_ref_id, $a_code)
5689 {
5690 if (!isset($_SESSION["360_extrtr"][$a_ref_id])) {
5691 $svy = new self($a_ref_id);
5692 $svy->loadFromDB();
5693
5694 if ($svy->canStartSurvey(null, true) &&
5695 $svy->get360Mode() &&
5696 $svy->isAnonymousKey($a_code)) {
5697 $anonymous_id = $svy->getAnonymousIdByCode($a_code);
5698 if ($anonymous_id) {
5699 if (sizeof($svy->getAppraiseesToRate(null, $anonymous_id))) {
5700 $_SESSION["360_extrtr"][$a_ref_id] = true;
5701 return true;
5702 }
5703 }
5704 }
5705
5706 $_SESSION["360_extrtr"][$a_ref_id] = false;
5707 return false;
5708 }
5709
5710 return $_SESSION["360_extrtr"][$a_ref_id];
5711 }
5712
5713
5714 //
5715 // reminder/notification
5716 //
5717
5718 public function getReminderStatus()
5719 {
5720 return (bool) $this->reminder_status;
5721 }
5722
5723 public function setReminderStatus($a_value)
5724 {
5725 $this->reminder_status = (bool) $a_value;
5726 }
5727
5728 public function getReminderStart()
5729 {
5730 return $this->reminder_start;
5731 }
5732
5733 public function setReminderStart(ilDate $a_value = null)
5734 {
5735 $this->reminder_start = $a_value;
5736 }
5737
5738 public function getReminderEnd()
5739 {
5740 return $this->reminder_end;
5741 }
5742
5743 public function setReminderEnd(ilDate $a_value = null)
5744 {
5745 $this->reminder_end = $a_value;
5746 }
5747
5748 public function getReminderFrequency()
5749 {
5751 }
5752
5753 public function setReminderFrequency($a_value)
5754 {
5755 $this->reminder_frequency = (int) $a_value;
5756 }
5757
5758 public function getReminderTarget()
5759 {
5761 }
5762
5763 public function setReminderTarget($a_value)
5764 {
5765 $this->reminder_target = (int) $a_value;
5766 }
5767
5768 public function getReminderLastSent()
5769 {
5771 }
5772
5773 public function setReminderLastSent($a_value)
5774 {
5775 $this->reminder_last_sent = $a_value;
5776 }
5777
5778 public function getReminderTemplate()
5779 {
5780 return $this->reminder_tmpl;
5781 }
5782
5783 public function setReminderTemplate($a_value)
5784 {
5785 $this->reminder_tmpl = $a_value;
5786 }
5787
5789 {
5790 return (bool) $this->tutor_ntf_status;
5791 }
5792
5793 public function setTutorNotificationStatus($a_value)
5794 {
5795 $this->tutor_ntf_status = (bool) $a_value;
5796 }
5797
5799 {
5801 }
5802
5803 public function setTutorNotificationRecipients(array $a_value)
5804 {
5805 $this->tutor_ntf_recipients = $a_value;
5806 }
5807
5809 {
5811 }
5812
5813 public function setTutorNotificationTarget($a_value)
5814 {
5815 $this->tutor_ntf_target = (int) $a_value;
5816 }
5817
5818 protected function checkTutorNotification()
5819 {
5820 $ilDB = $this->db;
5821
5822 if ($this->getTutorNotificationStatus()) {
5823 $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
5824 if ($user_ids) {
5825 $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished" .
5826 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5827 " AND state = " . $ilDB->quote(1, "integer") .
5828 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
5829 $row = $ilDB->fetchAssoc($set);
5830 if ($row["numall"] == sizeof($user_ids)) {
5831 $this->sendTutorNotification();
5832 }
5833 }
5834 }
5835 }
5836
5843 public function sent360Reminders()
5844 {
5845 global $DIC;
5846
5847 $access = $DIC->access();
5848
5849 // collect all open ratings
5850 $rater_ids = array();
5851 foreach ($this->getAppraiseesData() as $app) {
5852 $this->log->debug("Handle appraisee " . $app['user_id']);
5853
5854 if (!$this->isAppraiseeClosed($app['user_id'])) {
5855 $this->log->debug("Check self evaluation, self: " . $this->get360SelfAppraisee() . ", target: " . $this->getReminderTarget());
5856
5857 // self evaluation?
5858 if ($this->get360SelfEvaluation() &&
5860 $this->log->debug("...1");
5861 // did user already finished self evaluation?
5862 if (!$this->is360SurveyStarted($app['user_id'], $app['user_id'])) {
5863 $this->log->debug("...2");
5864 if (!is_array($rater_ids[$app['user_id']])) {
5865 $rater_ids[$app['user_id']] = array();
5866 }
5867 if (!in_array($app["user_id"], $rater_ids[$app['user_id']])) {
5868 $rater_ids[$app['user_id']][] = $app["user_id"];
5869 }
5870 }
5871 }
5872
5873 $this->log->debug("Check raters.");
5874
5875 // should raters be notified?
5877 foreach ($this->getRatersData($app['user_id']) as $rater) {
5878 // is rater not anonymous and did not rate yet?
5879 if (!$rater["anonymous_id"] && !$rater["finished"]) {
5880 if (!is_array($rater_ids[$rater["user_id"]])) {
5881 $rater_ids[$rater["user_id"]] = array();
5882 }
5883 if (!in_array($app["user_id"], $rater_ids[$rater["user_id"]])) {
5884 $rater_ids[$rater["user_id"]][] = $app["user_id"];
5885 }
5886 }
5887 }
5888 }
5889 }
5890 }
5891
5892 $this->log->debug("Found raters:" . count($rater_ids));
5893
5894 foreach ($rater_ids as $id => $app) {
5895 if ($access->checkAccessOfUser($id, "read", "", $this->getRefId())) {
5896 $this->send360ReminderToUser($id, $app);
5897 }
5898 }
5899 }
5900
5906 public function send360ReminderToUser($a_user_id, $a_appraisee_ids)
5907 {
5908 $this->log->debug("Send mail to:" . $a_user_id);
5909
5910 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5911 $ntf = new ilSystemNotification();
5912 $ntf->setLangModules(array("svy", "survey"));
5913 $ntf->setRefId($this->getRefId());
5914 $ntf->setGotoLangId('url');
5915
5916 // user specific language
5917 $lng = $ntf->getUserLanguage($a_user_id);
5918
5919 $ntf->setIntroductionLangId("svy_user_added_360_rater_reminder_mail");
5920 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5921
5922 foreach ($a_appraisee_ids as $appraisee_id) {
5923 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($appraisee_id, false, false, "", true));
5924 }
5925
5926 // #10044
5927 $mail = new ilMail(ANONYMOUS_USER_ID);
5928 $mail->enableSOAP(false); // #10410
5929 $mail->sendMail(
5930 ilObjUser::_lookupLogin($a_user_id),
5931 null,
5932 null,
5933 $subject,
5934 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5935 null,
5936 array("system")
5937 );
5938 }
5939
5940
5941 public function getNotificationTargetUserIds($a_use_invited)
5942 {
5944
5945 if ((bool) $a_use_invited) {
5946 $user_ids = $this->getInvitedUsers();
5947 } else {
5948 $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
5949 if ($parent_grp_ref_id) {
5950 include_once "Modules/Group/classes/class.ilGroupParticipants.php";
5951 $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
5952 $user_ids = $part->getMembers();
5953 } else {
5954 $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
5955 if ($parent_crs_ref_id) {
5956 include_once "Modules/Course/classes/class.ilCourseParticipants.php";
5957 $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
5958 $user_ids = $part->getMembers();
5959 }
5960 }
5961 }
5962 return $user_ids;
5963 }
5964
5965 protected function sendTutorNotification()
5966 {
5967 include_once "./Services/Mail/classes/class.ilMail.php";
5968 include_once "./Services/User/classes/class.ilObjUser.php";
5969 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
5970 include_once "./Services/User/classes/class.ilUserUtil.php";
5971 include_once "./Services/Link/classes/class.ilLink.php";
5972 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
5973
5974 foreach ($this->getTutorNotificationRecipients() as $user_id) {
5975 // use language of recipient to compose message
5976 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
5977 $ulng->loadLanguageModule('survey');
5978
5979 $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
5980 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
5981
5982 $message .= $ulng->txt('survey_notification_tutor_body') . ":\n\n";
5983 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
5984 $message .= "\n" . $ulng->txt('survey_notification_tutor_link') . ": " . $link;
5985
5986 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
5987 $mail_obj->appendInstallationSignature(true);
5988 $mail_obj->sendMail(
5989 ilObjUser::_lookupLogin($user_id),
5990 "",
5991 "",
5992 $subject,
5993 $message,
5994 array(),
5995 array("system")
5996 );
5997 }
5998 }
5999
6000 public function checkReminder()
6001 {
6002 $ilDB = $this->db;
6003 $ilAccess = $this->access;
6004
6005 $now = time();
6006 $now_with_format = date("YmdHis", $now);
6007 $today = date("Y-m-d");
6008
6009 $this->log->debug("Check status and dates.");
6010
6011 // object settings / participation period
6012 if ($this->isOffline() ||
6013 !$this->getReminderStatus() ||
6014 ($this->getStartDate() && $now_with_format < $this->getStartDate()) ||
6015 ($this->getEndDate() && $now_with_format > $this->getEndDate())) {
6016 return false;
6017 }
6018
6019 // reminder period
6020 $start = $this->getReminderStart();
6021 if ($start) {
6022 $start = $start->get(IL_CAL_DATE);
6023 }
6024 $end = $this->getReminderEnd();
6025 if ($end) {
6026 $end = $end->get(IL_CAL_DATE);
6027 }
6028 if ($today < $start ||
6029 ($end && $today > $end)) {
6030 return false;
6031 }
6032
6033 $this->log->debug("Check access period.");
6034
6035 // object access period
6036 include_once "Services/Object/classes/class.ilObjectActivation.php";
6037 $item_data = ilObjectActivation::getItem($this->getRefId());
6038 if ($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
6039 ($now < $item_data["timing_start"] ||
6040 $now > $item_data["timing_end"])) {
6041 return false;
6042 }
6043
6044 $this->log->debug("Check frequency.");
6045
6046 // check frequency
6047 $cut = new ilDate($today, IL_CAL_DATE);
6048 $cut->increment(IL_CAL_DAY, $this->getReminderFrequency()*-1);
6049 if (!$this->getReminderLastSent() ||
6050 $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10)) {
6051 $missing_ids = array();
6052
6053 if (!$this->get360Mode()) {
6054 $this->log->debug("Entering survey mode.");
6055
6056 // #16871
6057 $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
6058 if ($user_ids) {
6059 // gather participants who already finished
6060 $finished_ids = array();
6061 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
6062 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
6063 " AND state = " . $ilDB->quote(1, "text") .
6064 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
6065 while ($row = $ilDB->fetchAssoc($set)) {
6066 $finished_ids[] = $row["user_fi"];
6067 }
6068
6069 // some users missing out?
6070 $missing_ids = array_diff($user_ids, $finished_ids);
6071 if ($missing_ids) {
6072 foreach ($missing_ids as $idx => $user_id) {
6073 // should be able to participate
6074 if (!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId())) {
6075 unset($missing_ids[$idx]);
6076 }
6077 }
6078 }
6079 if ($missing_ids) {
6080 $this->sentReminder($missing_ids);
6081 }
6082 }
6083 } else {
6084 $this->log->debug("Entering 360 mode.");
6085
6086 $this->sent360Reminders();
6087 }
6088
6089
6090 $this->setReminderLastSent($today);
6091 $this->saveToDb();
6092
6093 return sizeof($missing_ids);
6094 }
6095
6096 return false;
6097 }
6098
6099 protected function sentReminder(array $a_recipient_ids)
6100 {
6101 include_once "./Services/Mail/classes/class.ilMail.php";
6102
6103 // use mail template
6104 if ($this->getReminderTemplate() &&
6105 array_key_exists($this->getReminderTemplate(), $this->getReminderMailTemplates())) {
6106 $prov = new ilMailTemplateDataProvider();
6107 $tmpl = $prov->getTemplateById($this->getReminderTemplate());
6108
6109 $tmpl_params = array(
6110 "ref_id" => $this->getRefId(),
6111 "ts" => time()
6112 );
6113 } else {
6114 $tmpl = null;
6115
6116 include_once "./Services/Link/classes/class.ilLink.php";
6117 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6118
6119 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6120 }
6121
6122 foreach ($a_recipient_ids as $user_id) {
6123 if ($tmpl) {
6124 $subject = $tmpl->getSubject();
6125 $message = $this->sentReminderPlaceholders($tmpl->getMessage(), $user_id, $tmpl_params);
6126 }
6127 // use lng
6128 else {
6129 // use language of recipient to compose message
6130 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6131 $ulng->loadLanguageModule('survey');
6132
6133 $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
6134 $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
6135
6136 $message .= $ulng->txt('survey_reminder_body') . ":\n\n";
6137 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
6138 $message .= "\n" . $ulng->txt('survey_reminder_link') . ": " . $link;
6139 }
6140
6141 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6142 $mail_obj->appendInstallationSignature(true);
6143 $mail_obj->sendMail(
6144 ilObjUser::_lookupLogin($user_id),
6145 "",
6146 "",
6147 $subject,
6148 $message,
6149 array(),
6150 array("system")
6151 );
6152 }
6153 }
6154
6155 public function setActivationStartDate($starting_time = null)
6156 {
6157 $this->activation_starting_time = $starting_time;
6158 }
6159
6160 public function setActivationEndDate($ending_time = null)
6161 {
6162 $this->activation_ending_time = $ending_time;
6163 }
6164
6165 public function getActivationStartDate()
6166 {
6167 return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : null;
6168 }
6169
6170 public function getActivationEndDate()
6171 {
6172 return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : null;
6173 }
6174
6175 public function setViewOwnResults($a_value)
6176 {
6177 $this->view_own_results = (bool) $a_value;
6178 }
6179
6180 public function hasViewOwnResults()
6181 {
6183 }
6184
6185 public function setMailOwnResults($a_value)
6186 {
6187 $this->mail_own_results = (bool) $a_value;
6188 }
6189
6190 public function hasMailOwnResults()
6191 {
6193 }
6194
6195 public function setMailConfirmation($a_value)
6196 {
6197 $this->mail_confirmation = (bool) $a_value;
6198 }
6199
6200 public function hasMailConfirmation()
6201 {
6203 }
6204
6205 public function setAnonymousUserList($a_value)
6206 {
6207 $this->anon_user_list = (bool) $a_value;
6208 }
6209
6210 public function hasAnonymousUserList()
6211 {
6212 return $this->anon_user_list;
6213 }
6214
6215 public static function getSurveySkippedValue()
6216 {
6217 global $DIC;
6218
6219 $lng = $DIC->language();
6220
6221 // #13541
6222
6223 include_once "./Services/Administration/classes/class.ilSetting.php";
6224 $surveySetting = new ilSetting("survey");
6225 if (!$surveySetting->get("skipped_is_custom", false)) {
6226 return $lng->txt("skipped");
6227 } else {
6228 return $surveySetting->get("skipped_custom_value", "");
6229 }
6230 }
6231
6233 {
6234 $res = array();
6235
6236 include_once "Services/Mail/classes/class.ilMailTemplateDataProvider.php";
6237 include_once "Modules/Survey/classes/class.ilSurveyMailTemplateReminderContext.php";
6238 $mprov = new ilMailTemplateDataProvider();
6239 foreach ($mprov->getTemplateByContextId(ilSurveyMailTemplateReminderContext::ID) as $tmpl) {
6240 $res[$tmpl->getTplId()] = $tmpl->getTitle();
6241 }
6242
6243 return $res;
6244 }
6245
6246 protected function sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
6247 {
6248 // see ilMail::replacePlaceholders()
6249 include_once "Modules/Survey/classes/class.ilSurveyMailTemplateReminderContext.php";
6250
6251 try {
6252 require_once 'Services/Mail/classes/class.ilMailTemplateService.php';
6254
6255 $user = new ilObjUser($a_user_id);
6256
6257 require_once 'Services/Mail/classes/class.ilMailTemplatePlaceholderResolver.php';
6258 require_once 'Services/Mail/classes/class.ilMailFormCall.php';
6259 $processor = new ilMailTemplatePlaceholderResolver($context, $a_message);
6260 $a_message = $processor->resolve($user, ilMailFormCall::getContextParameters());
6261 } catch (Exception $e) {
6262 require_once './Services/Logging/classes/public/class.ilLoggerFactory.php';
6263 ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
6264 }
6265
6266 return $a_message;
6267 }
6268} // END class.ilObjSurvey
sprintf('%.4f', $callTime)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
$result
user()
Definition: user.php:4
$size
Definition: RandomTest.php:84
$total
Definition: Utf8Test.php:87
$files
Definition: add-vimline.php:18
$metadata['__DYNAMIC:1__']
$source
Definition: linkback.php:22
$users
Definition: authpage.php:44
$_GET["client_id"]
$_POST["username"]
$_SESSION["AccountId"]
An exception for terminatinating execution or to throw for unit testing.
Survey Question Import Parser.
static _getQuestionGUI($questiontype, $question_id=-1)
Creates a question gui representation.
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
static _getOriginalId($question_id, $a_return_question_id_if_no_original=true)
Returns the original id of a question.
static _isComplete($question_id)
Checks whether the question is complete or not.
static _getQuestionType($question_id)
Returns the question type of a question with a given id.
static _instanciateQuestionEvaluation($question_id, array $a_finished_ids=null)
Creates an instance of a question evaluation with a given question id.
static _includeClass($question_type, $gui=0)
Include the php class file for a given question type.
const IL_COMP_MODULE
const IL_CAL_DATE
const IL_CAL_TIMESTAMP
const IL_CAL_UNIX
const IL_CAL_DATETIME
const IL_CAL_DAY
static _getInstance($a_copy_id)
Get instance of copy wizard options.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false)
Format a date @access public.
@classDescription Date and time handling
Class for single dates.
Import class.
static _getLanguageOfUser($a_usr_id)
Get language object of user.
static getLogger($a_component_id)
Get component logger.
Class ilMailTemplateDataProvider.
This class handles base functions for mail handling.
static _getUsedHTMLTagsAsString($a_module="")
Returns a string of all allowed HTML tags for text editing.
Class ilObjMediaObject.
static _saveUsage($a_mob_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
Save usage of mob within another container (e.g.
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _removeUsage($a_mob_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
Remove usage of mob in another container.
static _saveTempFileAsMediaObject($name, $tmp_name, $upload=true)
Create new media object and update page in db and return new media object.
static _getAvailableQuestionpools($use_object_id=false, $could_be_offline=false, $showPath=false, $permission="read")
Returns the available question pools for the active user.
setShowQuestionTitles($a_show)
Sets the status of the display_question_titles attribute.
isAccessibleWithoutCode()
Checks if the survey is accessable without a survey code.
setAuthor($author="")
Sets the authors name of the ilObjSurvey object.
setActivationVisibility($a_value)
const MODE_PREDEFINED_USERS
getUserAccessCode($user_id)
Returns a survey access code that was saved for a registered user.
getParticipantTextResults($active_id)
deleteConstraints($question_id)
Deletes the constraints for a question.
insertQuestion($question_id)
Inserts a question in the survey and saves the relation to the database.
const EVALUATION_ACCESS_PARTICIPANTS
finishSurvey($finished_id)
Finishes the survey creating an entry in the database.
getActiveID($user_id, $anonymize_id, $appr_id)
Checks if a user already started a survey.
setTutorNotificationStatus($a_value)
deleteAppraisee($a_user_id)
deleteSurveyCode($survey_code)
Deletes a given survey access code.
getExportDirectory()
get export directory of survey
getStatus()
Gets the survey status.
removeConstraintsConcerningQuestion($question_id)
Remove constraints concerning a question with a given question_id.
isOffline()
Gets the survey status.
getInvitation()
Gets the invitation status.
getAnonymize()
get anonymize status
setActivationStartDate($starting_time=null)
addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag=true, $add_mobs=true, $attribs=null)
Creates an XML material tag from a plain text or xhtml text.
getConstraints($question_id)
Returns the constraints to a given question or questionblock.
addQuestion($question_id)
Adds a question to the survey (used in importer!)
prepareTextareaOutput($txt_output)
Prepares a string for a text area output in surveys.
getQuestionType($question_id)
Returns the question type of a question with a given id.
setIntroduction($introduction="")
Sets the introduction text.
showQuestionTitles()
Sets the question titles visible during the query.
setMailOwnResults($a_value)
deleteWorkingData($question_id, $active_id)
Deletes the working data of a question in the database.
setActivationLimited($a_value)
createImportDirectory()
creates data directory for import files (data_dir/svy_data/svy_<id>/import, depending on data directo...
setStartDateAndTime($start_date="", $start_time)
Sets the start date of the survey.
setInvitationMode($invitation_mode=0)
Sets the invitation mode.
hasAnonymizedResults()
Checks if the survey results are to be anonymized.
updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
Updates a precondition.
findCodeForUser($a_user_id)
setTutorNotificationTarget($a_value)
disinviteUser($user_id)
Disinvites a user from a survey.
updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
loadQuestionsFromDb()
Loads the survey questions from the database.
static _getConstraints($survey_id)
Returns the constraints to a given question or questionblock.
setMailAddresses($a_addresses)
addQuestionToBlock($question_id, $questionblock_id)
__construct($a_id=0, $a_call_by_reference=true)
Constructor @access public.
processPrintoutput2FO($print_output)
Convert a print output to XSL-FO.
getOutro()
Gets the outro text.
create($a_upload=false)
create survey object
isQuestionInAnyBlock($a_question_fi)
Is question already in a block?
addAppraisee($a_user_id)
getRatersData($a_appraisee_id)
createSurveyCodesForExternalData($data)
getQuestionGUI($questiontype, $question_id)
Returns a question gui object to a given questiontype and question id.
createMetaData()
Create meta data entry.
sendAppraiseeCloseNotification($a_user_id)
Send appraisee notification.
cloneTextblocks($mapping)
Clones the textblocks of survey questions.
getPrecondition($id)
Returns a precondition with a given id.
setReminderLastSent($a_value)
importSurveyCode($a_anonymize_key, $a_created, $a_data)
setOutro($outro="")
Sets the outro text.
setActivationEndDate($ending_time=null)
setObligatoryStates($obligatory_questions)
Sets the obligatory states for questions in a survey from the questions form.
isRater($a_appraisee_id, $a_user_id, $a_anonymous_id=0)
cloneObject($a_target_id, $a_copy_id=0, $a_omit_tree=false)
Clone object.
saveHeading($heading="", $insertbefore)
getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
Get finished id for an appraisee and a rater.
addRater($a_appraisee_id, $a_user_id, $a_anonymous_id=0)
deleteConstraint($constraint_id)
Deletes a constraint of a question.
getUserSurveyExecutionStatus($a_code=null)
const NOTIFICATION_INVITED_USERS
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
getInvitationMode()
Gets the invitation mode.
locateImportFiles($a_dir)
Locates the import directory and the xml file in a directory with an unzipped import file.
sendCodes($not_sent, $subject, $message, $lang)
duplicateQuestionForSurvey($question_id, $a_force=false)
Takes a question and creates a copy of the question for use in the survey.
isHTML($a_text)
Checks if a given string contains HTML or not.
getWorkingtimeForParticipant($finished_id)
checkConstraint($constraint_data, $working_data)
Checks if a constraint is valid.
setSurveyId($survey_id)
Sets the survey id.
disinviteAllUsers()
Disinvite all users.
setReminderStart(ilDate $a_value=null)
deleteAllUserData()
Deletes all user data of a survey.
const NOTIFICATION_PARENT_COURSE
setMailConfirmation($a_value)
const EVALUATION_ACCESS_ALL
closeAppraisee($a_user_id)
setStatus($status=self::STATUS_OFFLINE)
Sets the survey status.
deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id=0)
setMailNotification($a_notification)
getTextblock($question_id)
setReminderTemplate($a_value)
applySettingsTemplate($template_id)
Apply settings template.
isUnusedCode($a_code, $a_user_id)
setMailParticipantData($a_data)
setInvitation($invitation=0)
Sets the invitation status.
moveQuestions($move_questions, $target_index, $insert_mode)
Move questions and/or questionblocks to another position.
canStartSurvey($anonymous_id=null, $a_no_rbac=false)
Checks if the survey can be started.
isAnonymizedParticipant($key)
updateConjunctionForQuestions($questions, $conjunction)
set360Results($a_value)
getQuestionblocksTable($arrFilter)
Calculates the data for the output of the questionblock browser.
isAppraisee($a_user_id)
isPoolActive()
Get current pool status.
getUserSettings($usr_id, $key)
getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee=false)
const QUESTIONTITLES_VISIBLE
isQuestionInSurvey($a_question_fi)
Check if a question is already in the survey.
& getInvitedUsers()
Returns a list of all invited users in a survey.
getExternalCodeRecipients($a_check_finished=false)
& getSurveyParticipants($finished_ids=null, $force_non_anonymous=false)
toXML()
Returns a QTI xml representation of the survey.
getEvaluationAccess()
Gets the learners evaluation access.
createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
Creates a question block for the survey.
static _hasDatasets($survey_id)
getAnonymousIdByCode($a_code)
getLastAccess($finished_id)
getAppraiseesToRate($a_user_id, $a_anonymous_id=null)
const NOTIFICATION_APPRAISEES_AND_RATERS
& getSurveyPages()
Returns the survey pages in an array (a page contains one or more questions)
saveToDb()
Saves a survey object to a database.
insertQuestionblock($questionblock_id)
Inserts a questionblock in the survey and saves the relation to the database.
hideQuestionTitles()
Sets the question titles hidden during the query.
setAnonymousUserList($a_value)
const ANONYMIZE_FREEACCESS
saveQuestionsToDb()
Saves the survey questions to the database.
modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
Modifies a question block.
updateOrder(array $a_order)
createNewAccessCode()
Returns a new, unused survey access code.
read()
read object data from db into object @access public
loadFromDb()
Loads a survey object from a database.
static _getQuestionblock($questionblock_id)
Returns the database row for a given question block.
setStartTime($finished_id, $first_question)
getQuestionsTable($arrFilter)
Calculates the data for the output of the question browser.
sendNotificationMail($user_id, $anonymize_id, $appr_id)
saveUserSettings($usr_id, $key, $title, $value)
unfoldQuestionblocks($questionblocks)
Unfolds question blocks of a question pool.
deliverPDFfromFO($fo)
Delivers a PDF file from a XSL-FO string.
is360SurveyStarted($appr_id, $user_id, $anonymous_code=null)
removeSelectedSurveyResults($finished_ids)
Deletes the user data of a given array of survey participants.
setViewOwnResults($a_value)
& getSurveyQuestions($with_answers=false)
Returns the survey questions and questionblocks in an array.
getSurveyId()
Returns the survey database id.
isSurveyFinishedByCode($a_code)
Get if survey is finished for an specific anonymous user code.
setStartDate($start_date="")
Sets the start date of the survey.
removeQuestionFromBlock($question_id, $questionblock_id)
getUserSpecificResults($finished_ids)
Calculates the evaluation data for the user specific results.
sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
setInvitationAndMode($invitation=0, $invitation_mode=0)
Sets the invitation status and mode (a more performant solution if you change both)
update()
update object data
setEvaluationAccess($evaluation_access=self::EVALUATION_ACCESS_OFF)
Sets the learners evaluation access.
getEndDate()
Gets the end date of the survey.
sendRaterNotification($a_user_id, $a_appraisee_id)
Send rater notification.
set360SelfEvaluation($a_value)
setPoolUsage($a_value)
setTutorNotificationRecipients(array $a_value)
send360ReminderToUser($a_user_id, $a_appraisee_ids)
Send rater notification.
isComplete()
Returns 1, if a survey is complete for use.
getSurveyCodesForExport(array $a_codes=null, array $a_ids=null)
Returns a list of survey codes for file export.
getUserDataFromActiveId($active_id, $force_non_anonymous=false)
Returns the user information from an active_id (survey_finished.finished_id)
setReminderTarget($a_value)
set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp=null)
saveCompletionStatus()
Saves the completion status of the survey.
static getSurveySkippedValue()
getAllRelations($short_as_key=false)
Returns all available relations.
getNextPage($active_page_question_id, $direction)
Returns the next "page" of a running test.
const EVALUATION_ACCESS_OFF
& getUserData($ids)
Returns a data of all users specified by id list.
createReference()
creates reference for object
static validateExternalRaterCode($a_ref_id, $a_code)
removeQuestion($question_id)
Remove a question from the survey.
set360Mode($a_value)
bindSurveyCodeToUser($user_id, $code)
& getEvaluationByUser($questions, $active_id)
Calculates the evaluation data for a given user or anonymous id.
getStartDate()
Gets the start date of the survey.
static _addQuestionblock($title="", $owner=0, $show_questiontext=true, $show_blocktitle=false)
Adds a questionblock to the database.
& getVariables($question_id)
Returns all variables of a question.
getImportDirectory()
get import directory of survey
deleteSurveyRecord()
Deletes the survey from the database.
getSurveyCodesTableData(array $ids=null, $lang=null)
Fetches the data for the survey codes table.
getNotificationTargetUserIds($a_use_invited)
setReminderStatus($a_value)
startSurvey($user_id, $anonymous_id, $appraisee_id)
Starts the survey creating an entry in the database.
sent360Reminders()
Send 360 reminders.
& getQuestionblockQuestions($questionblock_id)
Returns the question titles of all questions of a question block.
saveUserAccessCode($user_id, $access_code)
Saves a survey access code for a registered user to the database.
const NOTIFICATION_APPRAISEES
removeQuestions($remove_questions, $remove_questionblocks)
Remove questions from the survey.
sentReminder(array $a_recipient_ids)
fixSequenceStructure()
Remove duplicate sequence entries, see #22018.
const ANONYMIZE_CODE_ALL
& getSurveyFinishedIds()
Get the finished id's of all survey participants.
set360SelfAppraisee($a_value)
getLastActivePage($active_id)
Returns the question id of the last active page a user visited in a survey.
getIntroduction()
Gets the introduction text.
setReminderEnd(ilDate $a_value=null)
setEndDateAndTime($end_date="", $end_time)
Sets the end date of the survey.
setEndDate($end_date="")
Sets the end date of the survey.
sendAppraiseeNotification($a_user_id)
Send appraisee notification.
setTemplate($template_id)
setReminderFrequency($a_value)
createSurveyCodes($nrOfCodes)
getAuthor()
Gets the authors name of the ilObjSurvey object.
& getExistingQuestions()
Gets the question id's of the questions which are already in the survey.
& getQuestionblockQuestionIds($questionblock_id)
Returns the question id's of all questions of a question block.
getShowQuestionTitles()
Gets the status of the display_question_titles attribute.
setAnonymize($a_anonymize)
set anonymize status
isSurveyStarted($user_id, $anonymize_id, $appr_id=0)
Checks if a user already started a survey.
addConstraint($if_question_id, $relation, $value, $conjunction)
Adds a constraint.
& getQuestionpoolTitles($could_be_offline=false, $showPath=false)
Get the titles of all available survey question pools.
set360SelfRaters($a_value)
getAnonymousId($id)
Checks for an anomyous survey id in the database an returns the id.
setEndTime($finished_id)
loadWorkingData($question_id, $active_id)
Gets the working data of question from the database.
isAppraiseeClosed($a_user_id)
addConstraintToQuestion($to_question_id, $constraint_id)
Adds a constraint to a question.
set360SkillService($a_val)
Set skill service.
createExportDirectory()
creates data directory for export files (data_dir/svy_data/svy_<id>/export, depending on data directo...
isOnline()
Gets the survey status.
setPage($finished_id, $page_id)
Sets the number of the active survey page.
saveAuthorToMetadata($a_author="")
Saves an authors name into the lifecycle metadata if no lifecycle metadata exists This will only be c...
get360SkillService()
Get skill service.
canExportSurveyCode()
Checks if the survey code can be exported with the survey evaluation.
importObject($file_info, $svy_qpl_id)
Imports a survey from XML into the ILIAS database.
isPluginActive($a_pname)
Checks whether or not a question plugin with a given name is active.
inviteUser($user_id)
Invites a user to a survey.
const QUESTIONTITLES_HIDDEN
& getAvailableQuestionpools($use_obj_id=false, $could_be_offline=false, $showPath=false, $permission="read")
Returns the available question pools for the active user.
static _lookupEmail($a_user_id)
Lookup email.
static _getUserData($a_internalids)
return user data for given user ids
static _lookupLogin($a_user_id)
lookup login
static _dropDesktopItem($a_usr_id, $a_item_id, $a_type)
drop an item from user's personal desktop
static _lookupName($a_user_id)
lookup user name
static _lookupFullname($a_user_id)
Lookup Full Name.
static _addDesktopItem($a_usr_id, $a_item_id, $a_type, $a_par="")
add an item to user's personal desktop
Class ilObjectActivation.
setTimingType($a_type)
Set timing type.
static getItem($a_ref_id)
Get item data.
static getInstance($a_obj_id)
Class ilObject Basic functions for all objects.
getType()
get object type @access public
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
deleteMetaData()
delete meta data entry
updateMetaData()
update meta data entry
getRefId()
get reference id @access public
getDescription()
get object description
cloneMetaData($target_obj)
Copy meta data.
getId()
get object id @access public
static _lookupType($a_id, $a_reference=false)
lookup object type
getTitle()
get object title @access public
countReferences()
count references of object
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static factory($a_package, $a_timeout=0)
Creates an ilRpcClient instance to our ilServer.
ILIAS Setting Class.
Settings template application class.
Survey exception class.
Skill/Competence handling in surveys.
Wrapper classes for system notifications.
static getNamePresentation( $a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false, $a_ctrl_path="ilpublicuserprofilegui")
Default behaviour is:
static getDataDir()
get data directory (outside webspace)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static sortArray( $array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static prepareTextareaOutput($txt_output, $prepare_for_latex_output=false, $omitNl2BrWhenTextArea=false)
Prepares a string for a text area output where latex code may be in it If the text is HTML-free,...
static deliverData($a_data, $a_filename, $mime="application/octet-stream", $charset="")
deliver data for download via browser.
static _getObjectsByOperations($a_obj_type, $a_operation, $a_usr_id=0, $limit=0)
Get all objects of a specific type and check access This function is not recursive,...
static is_email($a_email, ilMailRfc822AddressParserFactory $mailAddressParserFactory=null)
This preg-based function checks whether an e-mail address is formally valid.
static ilTempnam($a_temp_path=null)
Create a temporary file in an ILIAS writable directory.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
XML writer class.
xmlHeader()
Writes xml header @access public.
$counter
$template
$lang
Definition: consent.php:3
$key
Definition: croninfo.php:18
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
$userdata
Definition: demo.php:48
$i
Definition: disco.tpl.php:19
$y
Definition: example_007.php:83
$h
$code
Definition: example_050.php:99
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
const INVITATION_ON
const INVITATION_OFF
xslt_error(&$proc)
xslt_free(&$proc)
xslt_create()
$time
Definition: cron.php:21
if($format !==null) $name
Definition: metadata.php:146
$index
Definition: metadata.php:60
$xml
Definition: metadata.php:240
$end
Definition: saml1-acs.php:18
catch(Exception $e) $message
$messages
Definition: en-x-test.php:7
update($pash, $contents, Config $config)
$url
$s
Definition: pwgen.php:45
$old
$insert
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
$dataset
Definition: showstats.php:45
global $ilDB
$mobs
$ilUser
Definition: imgupload.php:18
$params
Definition: disable.php:11
$text
Definition: errorreport.php:18
$rows
Definition: xhr_table.php:10