ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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
35
36 const INVITATION_OFF = 0;
37 const INVITATION_ON = 1;
38
39 const MODE_UNLIMITED = 0;
41
42 const ANONYMIZE_OFF = 0; // personalized, no codes
43 const ANONYMIZE_ON = 1; // anonymized, codes
44 const ANONYMIZE_FREEACCESS = 2; // anonymized, no codes
45 const ANONYMIZE_CODE_ALL = 3; // personalized, codes
46
49
50 // constants to define the print view values.
51 const PRINT_HIDE_LABELS = 1; // Show only the titles in "print" and "PDF Export"
52 const PRINT_SHOW_LABELS = 3; // Show titles and labels in "print" and "PDF Export"
53
60 public $survey_id;
61
68 public $author;
69
76
82 public $outro;
83
84
91
98
104 public $end_date;
105
112
119
126
132
138
145
151
155 protected $log;
156
160
161 // 360°
162 protected $mode_360_self_eval; // [bool]
163 protected $mode_360_self_appr; // [bool]
164 protected $mode_360_self_rate; // [bool]
165 protected $mode_360_results; // [int]
166 protected $mode_skill_service; // [bool]
167
171
172 // reminder/notification
173 protected $reminder_status; // [bool]
174 protected $reminder_start; // [ilDate]
175 protected $reminder_end; // [ilDate]
176 protected $reminder_frequency; // [int]
177 protected $reminder_target; // [int]
178 protected $reminder_last_sent; // [bool]
179 protected $reminder_tmpl; // [int]
180 protected $tutor_ntf_status; // [bool]
181 protected $tutor_ntf_recipients; // [array]
182 protected $tutor_ntf_target; // [int]
183
184 protected $view_own_results; // [bool]
185 protected $mail_own_results; // [bool]
186 protected $mail_confirmation; // [bool]
187
188 protected $anon_user_list; // [bool]
189
195
196 protected $mode; //[int]
197 protected $mode_self_eval_results; //[int]
198
199 //MODE TYPES
200 const MODE_STANDARD = 0;
201 const MODE_360 = 1;
202 const MODE_SELF_EVAL = 2;
203
204 //self evaluation only access to results
208
209
216 public function __construct($a_id = 0, $a_call_by_reference = true)
217 {
218 global $DIC;
219
220 $this->user = $DIC->user();
221 $this->lng = $DIC->language();
222 $this->db = $DIC->database();
223 $this->access = $DIC->access();
224 $this->log = $DIC["ilLog"];
225 $this->plugin_admin = $DIC["ilPluginAdmin"];
226 $this->tree = $DIC->repositoryTree();
227 $ilUser = $DIC->user();
228 $lng = $DIC->language();
229
230 $this->type = "svy";
231 $this->survey_id = -1;
232 $this->introduction = "";
233 $this->outro = $lng->txt("survey_finished");
234 $this->author = $ilUser->getFullname();
235 $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
236 $this->questions = array();
237 $this->invitation = self::INVITATION_OFF;
238 $this->invitation_mode = self::MODE_PREDEFINED_USERS;
239 $this->anonymize = self::ANONYMIZE_OFF;
240 $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
241 $this->surveyCodeSecurity = true;
242 $this->template_id = null;
243 $this->pool_usage = true;
244 $this->log = ilLoggerFactory::getLogger("svy");
245 $this->mode = self::MODE_STANDARD;
246 $this->mode_self_eval_results = self::RESULTS_SELF_EVAL_OWN;
247
248 parent::__construct($a_id, $a_call_by_reference);
249 }
250
254 public function create($a_upload = false)
255 {
256 parent::create();
257 if (!$a_upload) {
258 $this->createMetaData();
259 }
260 $this->setOfflineStatus(true);
261 $this->update($a_upload);
262 }
263
269 public function createMetaData()
270 {
271 parent::createMetaData();
272 $this->saveAuthorToMetadata();
273 }
274
281 public function update($a_upload = false)
282 {
283 if (!$a_upload) {
284 $this->updateMetaData();
285 }
286
287 if (!parent::update()) {
288 return false;
289 }
290
291 // put here object specific stuff
292
293 return true;
294 }
295
296 public function createReference()
297 {
298 $result = parent::createReference();
299 $this->saveToDb();
300 return $result;
301 }
302
307 public function read()
308 {
309 parent::read();
310 $this->loadFromDb();
311 }
312
319 public function addQuestion($question_id)
320 {
321 array_push($this->questions, $question_id);
322 }
323
330 public function delete()
331 {
332 if ($this->countReferences() == 1) {
333 $this->deleteMetaData();
334
335 // Delete all survey questions, constraints and materials
336 foreach ($this->questions as $question_id) {
337 $this->removeQuestion($question_id);
338 }
339 $this->deleteSurveyRecord();
340
342 }
343
344 $remove = parent::delete();
345
346 // always call parent delete function first!!
347 if (!$remove) {
348 return false;
349 }
350 return true;
351 }
352
358 public function deleteSurveyRecord()
359 {
361
362 $affectedRows = $ilDB->manipulateF(
363 "DELETE FROM svy_svy WHERE survey_id = %s",
364 array('integer'),
365 array($this->getSurveyId())
366 );
367
368 $result = $ilDB->queryF(
369 "SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
370 array('integer'),
371 array($this->getSurveyId())
372 );
373 $questionblocks = array();
374 while ($row = $ilDB->fetchAssoc($result)) {
375 array_push($questionblocks, $row["questionblock_fi"]);
376 }
377 if (count($questionblocks)) {
378 $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
379 }
380 $affectedRows = $ilDB->manipulateF(
381 "DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
382 array('integer'),
383 array($this->getSurveyId())
384 );
385 $this->deleteAllUserData(false);
386
387 $affectedRows = $ilDB->manipulateF(
388 "DELETE FROM svy_anonymous WHERE survey_fi = %s",
389 array('integer'),
390 array($this->getSurveyId())
391 );
392
393 // delete export files
394 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
395 $directory = $svy_data_dir . "/svy_" . $this->getId();
396 if (is_dir($directory)) {
397 ilUtil::delDir($directory);
398 }
399
400 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
401 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
402 // remaining usages are not in text anymore -> delete them
403 // and media objects (note: delete method of ilObjMediaObject
404 // checks whether object is used in another context; if yes,
405 // the object is not deleted!)
406 foreach ($mobs as $mob) {
407 ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
408 $mob_obj = new ilObjMediaObject($mob);
409 $mob_obj->delete();
410 }
411 }
412
419 public function deleteAllUserData($reset_LP = true)
420 {
422
423 $result = $ilDB->queryF(
424 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
425 array('integer'),
426 array($this->getSurveyId())
427 );
428 $active_array = array();
429 while ($row = $ilDB->fetchAssoc($result)) {
430 array_push($active_array, $row["finished_id"]);
431 }
432
433 $affectedRows = $ilDB->manipulateF(
434 "DELETE FROM svy_finished WHERE survey_fi = %s",
435 array('integer'),
436 array($this->getSurveyId())
437 );
438
439 foreach ($active_array as $active_fi) {
440 $affectedRows = $ilDB->manipulateF(
441 "DELETE FROM svy_answer WHERE active_fi = %s",
442 array('integer'),
443 array($active_fi)
444 );
445 $affectedRows = $ilDB->manipulateF(
446 "DELETE FROM svy_times WHERE finished_fi = %s",
447 array('integer'),
448 array($active_fi)
449 );
450 }
451
452 if ($reset_LP) {
453 include_once "Services/Object/classes/class.ilObjectLP.php";
454 $lp_obj = ilObjectLP::getInstance($this->getId());
455 $lp_obj->resetLPDataForCompleteObject();
456 }
457 }
458
464 public function removeSelectedSurveyResults($finished_ids)
465 {
467
468 $user_ids[] = array();
469
470 foreach ($finished_ids as $finished_id) {
471 $result = $ilDB->queryF(
472 "SELECT finished_id FROM svy_finished WHERE finished_id = %s",
473 array('integer'),
474 array($finished_id)
475 );
476 $row = $ilDB->fetchAssoc($result);
477
478 if ($row["user_fi"]) {
479 $user_ids[] = $row["user_fi"];
480 }
481
482 $affectedRows = $ilDB->manipulateF(
483 "DELETE FROM svy_answer WHERE active_fi = %s",
484 array('integer'),
485 array($row["finished_id"])
486 );
487
488 $affectedRows = $ilDB->manipulateF(
489 "DELETE FROM svy_finished WHERE finished_id = %s",
490 array('integer'),
491 array($finished_id)
492 );
493
494 $affectedRows = $ilDB->manipulateF(
495 "DELETE FROM svy_times WHERE finished_fi = %s",
496 array('integer'),
497 array($row["finished_id"])
498 );
499 }
500
501 if (sizeof($user_ids)) {
502 include_once "Services/Object/classes/class.ilObjectLP.php";
503 $lp_obj = ilObjectLP::getInstance($this->getId());
504 $lp_obj->resetLPDataForUserIds($user_ids);
505 }
506 }
507
508 public function &getSurveyParticipants($finished_ids = null, $force_non_anonymous = false)
509 {
511
512 $sql = "SELECT * FROM svy_finished" .
513 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
514 if ($finished_ids) {
515 $sql .= " AND " . $ilDB->in("finished_id", $finished_ids, "", "integer");
516 }
517
518 $result = $ilDB->query($sql);
519 $participants = array();
520 if ($result->numRows() > 0) {
521 while ($row = $ilDB->fetchAssoc($result)) {
522 $userdata = $this->getUserDataFromActiveId($row["finished_id"], $force_non_anonymous);
523 $userdata["finished"] = (bool) $row["state"];
524 $userdata["finished_tstamp"] = $row["tstamp"];
525 $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
526 }
527 }
528 return $participants;
529 }
530
537 public function isComplete()
538 {
539 if (($this->getTitle()) and (count($this->questions))) {
540 return 1;
541 } else {
542 return 0;
543 }
544 }
545
551 public function saveCompletionStatus()
552 {
554
555 $complete = 0;
556 if ($this->isComplete()) {
557 $complete = 1;
558 }
559 if ($this->getSurveyId() > 0) {
560 $affectedRows = $ilDB->manipulateF(
561 "UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
562 array('text','integer','integer'),
563 array($this->isComplete(), time(), $this->getSurveyId())
564 );
565 }
566 }
567
575 public function duplicateQuestionForSurvey($question_id, $a_force = false)
576 {
578
579 $questiontype = $this->getQuestionType($question_id);
580 $question_gui = $this->getQuestionGUI($questiontype, $question_id);
581
582 // check if question is a pool question at all, if not do nothing
583 if ($this->getId() == $question_gui->object->getObjId() && !$a_force) {
584 return $question_id;
585 }
586
587 $duplicate_id = $question_gui->object->duplicate(true, "", "", "", $this->getId());
588 return $duplicate_id;
589 }
590
596 public function insertQuestion($question_id)
597 {
599
600 $this->log->debug("insert question, id:" . $question_id);
601
602 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
603 if (!SurveyQuestion::_isComplete($question_id)) {
604 $this->log->debug("question is not complete");
605 return false;
606 } else {
607 // get maximum sequence index in test
608 // @todo: refactor this
609 $result = $ilDB->queryF(
610 "SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
611 array('integer'),
612 array($this->getSurveyId())
613 );
614 $sequence = $result->numRows();
615 $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
616 $this->log->debug("duplicate, id: " . $question_id . ", duplicate id: " . $duplicate_id);
617
618 // check if question is not already in the survey, see #22018
619 if ($this->isQuestionInSurvey($duplicate_id)) {
620 return false;
621 }
622
623 $next_id = $ilDB->nextId('svy_svy_qst');
624 $affectedRows = $ilDB->manipulateF(
625 "INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
626 array('integer', 'integer', 'integer', 'integer', 'integer'),
627 array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
628 );
629
630 $this->log->debug("added entry to svy_svy_qst, id: " . $next_id . ", question id: " . $duplicate_id . ", sequence: " . $sequence);
631
632 $this->loadQuestionsFromDb();
633 return true;
634 }
635 }
636
643 public function isQuestionInSurvey($a_question_fi)
644 {
645 global $DIC;
646 //return false;
647 $ilDB = $DIC->database();
648
649 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
650 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
651 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
652 if ($rec = $ilDB->fetchAssoc($set)) {
653 return true;
654 }
655 return false;
656 }
657
658
659
665 public function insertQuestionblock($questionblock_id)
666 {
668 $result = $ilDB->queryF(
669 "SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle," .
670 " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst" .
671 " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi" .
672 " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi" .
673 " AND svy_qblk.questionblock_id = %s" .
674 " ORDER BY svy_svy_qst.sequence",
675 array('integer'),
676 array($questionblock_id)
677 );
678 $questions = array();
679 $show_questiontext = 0;
680 $show_blocktitle = 0;
681 while ($row = $ilDB->fetchAssoc($result)) {
682 $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
683 array_push($questions, $duplicate_id);
684 $title = $row["title"];
685 $show_questiontext = $row["show_questiontext"];
686 $show_blocktitle = $row["show_blocktitle"];
687 }
688 $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
689 }
690
691 public function saveUserSettings($usr_id, $key, $title, $value)
692 {
694
695 $next_id = $ilDB->nextId('svy_settings');
696 $affectedRows = $ilDB->insert("svy_settings", array(
697 "settings_id" => array("integer", $next_id),
698 "usr_id" => array("integer", $usr_id),
699 "keyword" => array("text", $key),
700 "title" => array("text", $title),
701 "value" => array("clob", $value)
702 ));
703 }
704
705 public function deleteUserSettings($id)
706 {
708
709 $affectedRows = $ilDB->manipulateF(
710 "DELETE FROM svy_settings WHERE settings_id = %s",
711 array('integer'),
712 array($id)
713 );
714 return $affectedRows;
715 }
716
717 public function getUserSettings($usr_id, $key)
718 {
720
721 $result = $ilDB->queryF(
722 "SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
723 array('integer', 'text'),
724 array($usr_id, $key)
725 );
726 $found = array();
727 if ($result->numRows()) {
728 while ($row = $ilDB->fetchAssoc($result)) {
729 $found[$row['settings_id']] = $row;
730 }
731 }
732 return $found;
733 }
734
740 public function saveToDb()
741 {
743
744 // date handling
745 $rmd_start = $this->getReminderStart();
746 if (is_object($rmd_start)) {
747 $rmd_start = $rmd_start->get(IL_CAL_DATE);
748 }
749 $rmd_end = $this->getReminderEnd();
750 if (is_object($rmd_end)) {
751 $rmd_end = $rmd_end->get(IL_CAL_DATE);
752 }
753
754 include_once("./Services/RTE/classes/class.ilRTE.php");
755 if ($this->getSurveyId() < 1) {
756 $next_id = $ilDB->nextId('svy_svy');
757 $affectedRows = $ilDB->insert("svy_svy", array(
758 "survey_id" => array("integer", $next_id),
759 "obj_fi" => array("integer", $this->getId()),
760 "author" => array("text", $this->getAuthor()),
761 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
762 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
763 "startdate" => array("text", $this->getStartDate()),
764 "enddate" => array("text", $this->getEndDate()),
765 "evaluation_access" => array("text", $this->getEvaluationAccess()),
766 "invitation" => array("text", $this->getInvitation()),
767 "invitation_mode" => array("text", $this->getInvitationMode()),
768 "complete" => array("text", $this->isComplete()),
769 "created" => array("integer", time()),
770 "anonymize" => array("text", $this->getAnonymize()),
771 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
772 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
773 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
774 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
775 "tstamp" => array("integer", time()),
776 "template_id" => array("integer", $this->getTemplate()),
777 "pool_usage" => array("integer", $this->getPoolUsage()),
778 // Mode type
779 "mode" => array("integer", $this->getMode()),
780 // 360°
781 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
782 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
783 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
784 "mode_360_results" => array("integer", $this->get360Results()),
785 // competences
786 "mode_skill_service" => array("integer", (int) $this->getSkillService()),
787 // Self Evaluation Only
788 "mode_self_eval_results" => array("integer", ilObjSurvey::RESULTS_SELF_EVAL_OWN),
789 // reminder/notification
790 "reminder_status" => array("integer", (int) $this->getReminderStatus()),
791 "reminder_start" => array("datetime", $rmd_start),
792 "reminder_end" => array("datetime", $rmd_end),
793 "reminder_frequency" => array("integer", (int) $this->getReminderFrequency()),
794 "reminder_target" => array("integer", (int) $this->getReminderTarget()),
795 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
796 "reminder_tmpl" => array("text", $this->getReminderTemplate(true)),
797 "tutor_ntf_status" => array("integer", (int) $this->getTutorNotificationStatus()),
798 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
799 "tutor_ntf_target" => array("integer", (int) $this->getTutorNotificationTarget()),
800 "own_results_view" => array("integer", $this->hasViewOwnResults()),
801 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
802 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
803 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
804 ));
805 $this->setSurveyId($next_id);
806 } else {
807 $affectedRows = $ilDB->update("svy_svy", array(
808 "author" => array("text", $this->getAuthor()),
809 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
810 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
811 "startdate" => array("text", $this->getStartDate()),
812 "enddate" => array("text", $this->getEndDate()),
813 "evaluation_access" => array("text", $this->getEvaluationAccess()),
814 "invitation" => array("text", $this->getInvitation()),
815 "invitation_mode" => array("text", $this->getInvitationMode()),
816 "complete" => array("text", $this->isComplete()),
817 "anonymize" => array("text", $this->getAnonymize()),
818 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
819 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
820 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
821 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
822 "tstamp" => array("integer", time()),
823 "template_id" => array("integer", $this->getTemplate()),
824 "pool_usage" => array("integer", $this->getPoolUsage()),
825 //MODE TYPE
826 "mode" => array("integer", $this->getMode()),
827 // 360°
828 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
829 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
830 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
831 "mode_360_results" => array("integer", $this->get360Results()),
832 // Competences
833 "mode_skill_service" => array("integer", (int) $this->getSkillService()),
834 // Self Evaluation Only
835 "mode_self_eval_results" => array("integer", $this->getSelfEvaluationResults()),
836 // reminder/notification
837 "reminder_status" => array("integer", $this->getReminderStatus()),
838 "reminder_start" => array("datetime", $rmd_start),
839 "reminder_end" => array("datetime", $rmd_end),
840 "reminder_frequency" => array("integer", $this->getReminderFrequency()),
841 "reminder_target" => array("integer", $this->getReminderTarget()),
842 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
843 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
844 "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
845 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
846 "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget()),
847 "own_results_view" => array("integer", $this->hasViewOwnResults()),
848 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
849 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
850 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
851 ), array(
852 "survey_id" => array("integer", $this->getSurveyId())
853 ));
854 }
855 if ($affectedRows) {
856 // save questions to db
857 $this->saveQuestionsToDb();
858 }
859
860 // moved activation to ilObjectActivation
861 if ($this->ref_id) {
862 include_once "./Services/Object/classes/class.ilObjectActivation.php";
863 ilObjectActivation::getItem($this->ref_id);
864
865 $item = new ilObjectActivation;
866 if (!$this->isActivationLimited()) {
868 } else {
869 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
870 $item->setTimingStart($this->getActivationStartDate());
871 $item->setTimingEnd($this->getActivationEndDate());
872 $item->toggleVisible($this->getActivationVisibility());
873 }
874
875 $item->update($this->ref_id);
876 }
877 }
878
885 public function saveQuestionsToDb()
886 {
888
889 $this->log->debug("save questions");
890
891 // gather old questions state
892 $old_questions = array();
893 $result = $ilDB->queryF(
894 "SELECT survey_question_id,question_fi,sequence" .
895 " FROM svy_svy_qst WHERE survey_fi = %s",
896 array('integer'),
897 array($this->getSurveyId())
898 );
899 while ($row = $ilDB->fetchAssoc($result)) {
900 $old_questions[$row["question_fi"]] = $row; // problem, as soon as duplicates exist, they will be hidden here
901 }
902
903 // #15231 - diff with current questions state
904 $insert = $update = $delete = array();
905 foreach ($this->questions as $seq => $fi) {
906 if (!array_key_exists($fi, $old_questions)) { // really new fi IDs
907 $insert[] = $fi; // this should be ok, should not create duplicates here
908 } elseif ($old_questions[$fi]["sequence"] != $seq) { // we are updating one of the duplicates (if any)
909 $update[$fi] = $old_questions[$fi]["survey_question_id"];
910 }
911 // keep track of still relevant questions
912 unset($old_questions[$fi]); // deleting old question, if they are not in current array
913 }
914
915 // delete obsolete question relations
916 if (sizeof($old_questions)) {
917 $del_ids = array();
918 foreach ($old_questions as $fi => $old) {
919 $del_ids[] = $old["survey_question_id"];
920 }
921 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
922 " WHERE " . $ilDB->in("survey_question_id", $del_ids, "", "integer"));
923 $this->log->debug("delete: " . $q);
924 }
925 unset($old_questions);
926
927 // create/update question relations
928 foreach ($this->questions as $seq => $fi) {
929 if (in_array($fi, $insert)) {
930 // check if question is not already in the survey, see #22018
931 if (!$this->isQuestionInSurvey($fi)) {
932 $next_id = $ilDB->nextId('svy_svy_qst');
933 $ilDB->manipulateF(
934 "INSERT INTO svy_svy_qst" .
935 " (survey_question_id, survey_fi, question_fi, heading, sequence, tstamp)" .
936 " VALUES (%s, %s, %s, %s, %s, %s)",
937 array('integer', 'integer', 'integer', 'text', 'integer', 'integer'),
938 array($next_id, $this->getSurveyId(), $fi, null, $seq, time())
939 );
940 $this->log->debug("insert svy_svy_qst, id:" . $next_id . ", fi: " . $fi . ", seq:" . $seq);
941 }
942 } elseif (array_key_exists($fi, $update)) {
943 $ilDB->manipulate("UPDATE svy_svy_qst" .
944 " SET sequence = " . $ilDB->quote($seq, "integer") .
945 ", tstamp = " . $ilDB->quote(time(), "integer") .
946 " WHERE survey_question_id = " . $ilDB->quote($update[$fi], "integer"));
947 $this->log->debug("update svy_svy_qst, id:" . $update[$fi] . ", fi: " . $fi . ", seq:" . $seq);
948 }
949 }
950 }
951
959 public function getAnonymousId($id)
960 {
962 $result = $ilDB->queryF(
963 "SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
964 array('text'),
965 array($id)
966 );
967 if ($result->numRows()) {
968 $row = $ilDB->fetchAssoc($result);
969 return $row["anonymous_id"];
970 } else {
971 return "";
972 }
973 }
974
981 public function getQuestionGUI($questiontype, $question_id)
982 {
983 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestionGUI.php";
984 return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
985 }
986
994 public function getQuestionType($question_id)
995 {
997 if ($question_id < 1) {
998 return -1;
999 }
1000 $result = $ilDB->queryF(
1001 "SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
1002 "svy_question.questiontype_fi = svy_qtype.questiontype_id",
1003 array('integer'),
1004 array($question_id)
1005 );
1006 if ($result->numRows() == 1) {
1007 $data = $ilDB->fetchAssoc($result);
1008 return $data["type_tag"];
1009 } else {
1010 return "";
1011 }
1012 }
1013
1020 public function getSurveyId()
1021 {
1022 return $this->survey_id;
1023 }
1024
1028 public function setAnonymize($a_anonymize)
1029 {
1030 switch ($a_anonymize) {
1032 case self::ANONYMIZE_ON:
1035 $this->anonymize = $a_anonymize;
1036 break;
1037 default:
1038 $this->anonymize = self::ANONYMIZE_OFF;
1039 break;
1040 }
1041 }
1042
1048 public function getAnonymize()
1049 {
1050 return ($this->anonymize) ? $this->anonymize : 0;
1051 }
1052
1058 public function isAccessibleWithoutCode()
1059 {
1060 return ($this->getAnonymize() == self::ANONYMIZE_OFF ||
1061 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1062 }
1063
1069 public function hasAnonymizedResults()
1070 {
1071 return ($this->getAnonymize() == self::ANONYMIZE_ON ||
1072 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1073 }
1074
1080 public function loadFromDb()
1081 {
1082 $ilDB = $this->db;
1083 $result = $ilDB->queryF(
1084 "SELECT * FROM svy_svy WHERE obj_fi = %s",
1085 array('integer'),
1086 array($this->getId())
1087 );
1088 if ($result->numRows() == 1) {
1089 $data = $ilDB->fetchAssoc($result);
1090 $this->setSurveyId($data["survey_id"]);
1091 $this->setAuthor($data["author"]);
1092 include_once("./Services/RTE/classes/class.ilRTE.php");
1093 $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1094 if (strcmp($data["outro"], "survey_finished") == 0) {
1095 $this->setOutro($this->lng->txt("survey_finished"));
1096 } else {
1098 }
1099 $this->setInvitation($data["invitation"]);
1100 $this->setInvitationMode($data["invitation_mode"]);
1101 $this->setShowQuestionTitles($data["show_question_titles"]);
1102 $this->setStartDate($data["startdate"]);
1103 $this->setEndDate($data["enddate"]);
1104 $this->setAnonymize($data["anonymize"]);
1105 $this->setEvaluationAccess($data["evaluation_access"]);
1106 $this->loadQuestionsFromDb();
1107 $this->setMailNotification($data['mailnotification']);
1108 $this->setMailAddresses($data['mailaddresses']);
1109 $this->setMailParticipantData($data['mailparticipantdata']);
1110 $this->setTemplate($data['template_id']);
1111 $this->setPoolUsage($data['pool_usage']);
1112 // Mode
1113 $this->setMode($data['mode']);
1114 // 360°
1115 $this->set360SelfEvaluation($data['mode_360_self_eval']);
1116 $this->set360SelfRaters($data['mode_360_self_rate']);
1117 $this->set360SelfAppraisee($data['mode_360_self_appr']);
1118 $this->set360Results($data['mode_360_results']);
1119 // Mode self evaluated
1120 $this->setSelfEvaluationResults($data['mode_self_eval_results']);
1121 // Competences
1122 $this->setSkillService($data['mode_skill_service']);
1123 // reminder/notification
1124 $this->setReminderStatus($data["reminder_status"]);
1125 $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1126 $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1127 $this->setReminderFrequency($data["reminder_frequency"]);
1128 $this->setReminderTarget($data["reminder_target"]);
1129 $this->setReminderLastSent($data["reminder_last_sent"]);
1130 $this->setReminderTemplate($data["reminder_tmpl"]);
1131 $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1132 $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1133 $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1134
1135 $this->setViewOwnResults($data["own_results_view"]);
1136 $this->setMailOwnResults($data["own_results_mail"]);
1137 $this->setMailConfirmation($data["confirmation_mail"]);
1138
1139 $this->setAnonymousUserList($data["anon_user_list"]);
1140 }
1141
1142 // moved activation to ilObjectActivation
1143 if ($this->ref_id) {
1144 include_once "./Services/Object/classes/class.ilObjectActivation.php";
1145 $activation = ilObjectActivation::getItem($this->ref_id);
1146 switch ($activation["timing_type"]) {
1148 $this->setActivationLimited(true);
1149 $this->setActivationStartDate($activation["timing_start"]);
1150 $this->setActivationEndDate($activation["timing_end"]);
1151 $this->setActivationVisibility($activation["visible"]);
1152 break;
1153
1154 default:
1155 $this->setActivationLimited(false);
1156 break;
1157 }
1158 }
1159 }
1160
1167 public function loadQuestionsFromDb()
1168 {
1169 $ilDB = $this->db;
1170 $this->questions = array();
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 while ($data = $ilDB->fetchAssoc($result)) {
1177 $this->questions[$data["sequence"]] = $data["question_fi"];
1178 }
1179 }
1180
1184 public function fixSequenceStructure()
1185 {
1186 global $DIC;
1187
1188 $ilDB = $DIC->database();
1189 //return;
1190 // we keep all survey question ids with their lowest sequence
1191 $result = $ilDB->queryF(
1192 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1193 array('integer'),
1194 array($this->getSurveyId())
1195 );
1196
1197 // step 1: find duplicates -> $to_delete_ids
1198 $fis = array();
1199 $to_delete_ids = array();
1200 while ($data = $ilDB->fetchAssoc($result)) {
1201 if (in_array($data["question_fi"], $fis)) { // found a duplicate
1202 $to_delete_ids[] = $data["survey_question_id"];
1203 } else {
1204 $fis[] = $data["question_fi"];
1205 }
1206 }
1207
1208 // step 2: we delete the duplicates
1209 if (count($to_delete_ids) > 0) {
1210 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
1211 " WHERE " . $ilDB->in("survey_question_id", $to_delete_ids, false, "integer") .
1212 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1213 $this->log->debug("delete: " . $q);
1214
1215 $ilDB->manipulate($q = "DELETE FROM svy_qblk_qst " .
1216 " WHERE " . $ilDB->in("question_fi", $fis, true, "integer") .
1217 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1218 $this->log->debug("delete: " . $q);
1219 }
1220
1221 // step 3: we fix the sequence
1222 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
1223 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") . " ORDER BY sequence");
1224 $seq = 0;
1225 while ($rec = $ilDB->fetchAssoc($set)) {
1226 $ilDB->manipulate(
1227 $q = "UPDATE svy_svy_qst SET " .
1228 " sequence = " . $ilDB->quote($seq++, "integer") .
1229 " WHERE survey_question_id = " . $ilDB->quote($rec["survey_question_id"], "integer")
1230 );
1231 $this->log->debug("update: " . $q);
1232 }
1233 }
1234
1235
1243 public function setAuthor($author = "")
1244 {
1245 $this->author = $author;
1246 }
1247
1257 public function saveAuthorToMetadata($a_author = "")
1258 {
1259 $md = new ilMD($this->getId(), 0, $this->getType());
1260 $md_life = &$md->getLifecycle();
1261 if (!$md_life) {
1262 if (strlen($a_author) == 0) {
1264 $a_author = $ilUser->getFullname();
1265 }
1266
1267 $md_life = &$md->addLifecycle();
1268 $md_life->save();
1269 $con = &$md_life->addContribute();
1270 $con->setRole("Author");
1271 $con->save();
1272 $ent = &$con->addEntity();
1273 $ent->setEntity($a_author);
1274 $ent->save();
1275 }
1276 }
1277
1285 public function getAuthor()
1286 {
1287 $author = array();
1288 include_once "./Services/MetaData/classes/class.ilMD.php";
1289 $md = new ilMD($this->getId(), 0, $this->getType());
1290 $md_life = &$md->getLifecycle();
1291 if ($md_life) {
1292 $ids = &$md_life->getContributeIds();
1293 foreach ($ids as $id) {
1294 $md_cont = &$md_life->getContribute($id);
1295 if (strcmp($md_cont->getRole(), "Author") == 0) {
1296 $entids = &$md_cont->getEntityIds();
1297 foreach ($entids as $entid) {
1298 $md_ent = &$md_cont->getEntity($entid);
1299 array_push($author, $md_ent->getEntity());
1300 }
1301 }
1302 }
1303 }
1304 return join(",", $author);
1305 }
1306
1313 public function getShowQuestionTitles()
1314 {
1315 return ($this->display_question_titles) ? 1 : 0;
1316 }
1317
1324 public function setShowQuestionTitles($a_show)
1325 {
1326 $this->display_question_titles = ($a_show) ? 1 : 0;
1327 }
1328
1335 public function showQuestionTitles()
1336 {
1337 $this->display_question_titles = 1;
1338 }
1339
1346 public function hideQuestionTitles()
1347 {
1348 $this->display_question_titles = 0;
1349 }
1350
1358 public function setInvitation($invitation = 0)
1359 {
1360 $ilDB = $this->db;
1361 $ilAccess = $this->access;
1362
1363 $this->invitation = $invitation;
1365 $this->disinviteAllUsers();
1366 } elseif ($invitation == self::INVITATION_ON) {
1367 if ($this->getInvitationMode() == self::MODE_UNLIMITED) {
1368 $result = $ilDB->query("SELECT usr_id FROM usr_data");
1369 while ($row = $ilDB->fetchAssoc($result)) {
1370 if ($ilAccess->checkAccessOfUser($row["usr_id"], "read", "", $this->getRefId(), "svy", $this->getId())) {
1371 $this->inviteUser($row['usr_id']);
1372 }
1373 }
1374 }
1375 }
1376 }
1377
1386 {
1387 $this->invitation_mode = $invitation_mode;
1388 }
1389
1399 {
1400 $this->invitation_mode = $invitation_mode;
1401 $this->setInvitation($invitation);
1402 }
1403
1410 public function setIntroduction($introduction = "")
1411 {
1412 $this->introduction = $introduction;
1413 }
1414
1421 public function setOutro($outro = "")
1422 {
1423 $this->outro = $outro;
1424 }
1425
1433 public function getInvitation()
1434 {
1435 return ($this->invitation) ? $this->invitation : self::INVITATION_OFF;
1436 }
1437
1445 public function getInvitationMode()
1446 {
1447 include_once "./Services/Administration/classes/class.ilSetting.php";
1448 $surveySetting = new ilSetting("survey");
1449 $unlimited_invitation = $surveySetting->get("unlimited_invitation");
1450 if (!$unlimited_invitation && $this->invitation_mode == self::MODE_UNLIMITED) {
1452 } else {
1453 return ($this->invitation_mode) ? $this->invitation_mode : self::MODE_UNLIMITED;
1454 }
1455 }
1456
1464 public function getStartDate()
1465 {
1466 return (strlen($this->start_date)) ? $this->start_date : null;
1467 }
1468
1475 public function canStartSurvey($anonymous_id = null, $a_no_rbac = false)
1476 {
1477 $ilAccess = $this->access;
1478
1479 $result = true;
1480 $messages = array();
1481 $edit_settings = false;
1482 // check start date
1483 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches)) {
1484 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1485 $now = time();
1486 if ($now < $epoch_time) {
1487 array_push($messages, $this->lng->txt('start_date_not_reached') . ' (' .
1489 $result = false;
1490 $edit_settings = true;
1491 }
1492 }
1493 // check end date
1494 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches)) {
1495 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1496 $now = time();
1497 if ($now > $epoch_time) {
1498 array_push($messages, $this->lng->txt('end_date_reached') . ' (' .
1500 $result = false;
1501 $edit_settings = true;
1502 }
1503 }
1504
1505 // check online status
1506 if ($this->getOfflineStatus()) {
1507 array_push($messages, $this->lng->txt("survey_is_offline"));
1508 $result = false;
1509 $edit_settings = true;
1510 }
1511 // check rbac permissions
1512 if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id)) {
1513 array_push($messages, $this->lng->txt("cannot_participate_survey"));
1514 $result = false;
1515 }
1516 /*
1517 // 2. check previous access
1518 if (!$result["error"])
1519 {
1520 $ilUser = $this->user;
1521 $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1522 if ($survey_started === 1)
1523 {
1524 array_push($messages, $this->lng->txt("already_completed_survey"));
1525 $result = FALSE;
1526 }
1527 }
1528 */
1529 return array(
1530 "result" => $result,
1531 "messages" => $messages,
1532 "edit_settings" => $edit_settings
1533 );
1534 }
1535
1543 public function setStartDate($start_date = "")
1544 {
1545 $this->start_date = $start_date;
1546 }
1547
1556 public function setStartDateAndTime($start_date = "", $start_time)
1557 {
1558 $y = '';
1559 $m = '';
1560 $d = '';
1561 $h = '';
1562 $i = '';
1563 $s = '';
1564 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches)) {
1565 $y = $matches[1];
1566 $m = $matches[2];
1567 $d = $matches[3];
1568 }
1569 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches)) {
1570 $h = $matches[1];
1571 $i = $matches[2];
1572 $s = $matches[3];
1573 }
1574 $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1575 }
1576
1584 public function getEndDate()
1585 {
1586 return (strlen($this->end_date)) ? $this->end_date : null;
1587 }
1588
1596 public function setEndDate($end_date = "")
1597 {
1598 $this->end_date = $end_date;
1599 }
1600
1609 public function setEndDateAndTime($end_date = "", $end_time)
1610 {
1611 $y = '';
1612 $m = '';
1613 $d = '';
1614 $h = '';
1615 $i = '';
1616 $s = '';
1617 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches)) {
1618 $y = $matches[1];
1619 $m = $matches[2];
1620 $d = $matches[3];
1621 }
1622 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches)) {
1623 $h = $matches[1];
1624 $i = $matches[2];
1625 $s = $matches[3];
1626 }
1627 $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1628 }
1629
1637 public function getEvaluationAccess()
1638 {
1639 return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1640 }
1641
1649 public function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1650 {
1651 $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1652 }
1653
1654 public function setActivationVisibility($a_value)
1655 {
1656 $this->activation_visibility = (bool) $a_value;
1657 }
1658
1659 public function getActivationVisibility()
1660 {
1662 }
1663
1664 public function isActivationLimited()
1665 {
1666 return (bool) $this->activation_limited;
1667 }
1668
1669 public function setActivationLimited($a_value)
1670 {
1671 $this->activation_limited = (bool) $a_value;
1672 }
1673
1681 public function getIntroduction()
1682 {
1683 return (strlen($this->introduction)) ? $this->introduction : null;
1684 }
1685
1693 public function getOutro()
1694 {
1695 return (strlen($this->outro)) ? $this->outro : null;
1696 }
1697
1704 public function &getExistingQuestions()
1705 {
1706 $ilDB = $this->db;
1707 $existing_questions = array();
1708 $result = $ilDB->queryF(
1709 "SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1710 "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1711 array('integer'),
1712 array($this->getSurveyId())
1713 );
1714 while ($data = $ilDB->fetchAssoc($result)) {
1715 if ($data["original_id"]) {
1716 array_push($existing_questions, $data["original_id"]);
1717 }
1718 }
1719 return $existing_questions;
1720 }
1721
1728 public function &getQuestionpoolTitles($could_be_offline = false, $showPath = false)
1729 {
1730 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
1731 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = true, $could_be_offline, $showPath);
1732 }
1733
1742 public function moveQuestions($move_questions, $target_index, $insert_mode)
1743 {
1744 $array_pos = array_search($target_index, $this->questions);
1745 if ($insert_mode == 0) {
1746 $part1 = array_slice($this->questions, 0, $array_pos);
1747 $part2 = array_slice($this->questions, $array_pos);
1748 } elseif ($insert_mode == 1) {
1749 $part1 = array_slice($this->questions, 0, $array_pos + 1);
1750 $part2 = array_slice($this->questions, $array_pos + 1);
1751 }
1752 $found = 0;
1753 foreach ($move_questions as $question_id) {
1754 if (!(array_search($question_id, $part1) === false)) {
1755 unset($part1[array_search($question_id, $part1)]);
1756 $found++;
1757 }
1758 if (!(array_search($question_id, $part2) === false)) {
1759 unset($part2[array_search($question_id, $part2)]);
1760 $found++;
1761 }
1762 }
1763 // sanity check: do not move questions if they have not be found in the array
1764 if ($found != count($move_questions)) {
1765 return;
1766 }
1767 $part1 = array_values($part1);
1768 $part2 = array_values($part2);
1769 $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1770 foreach ($move_questions as $question_id) {
1771 $constraints = $this->getConstraints($question_id);
1772 foreach ($constraints as $idx => $constraint) {
1773 foreach ($part2 as $next_question_id) {
1774 if ($constraint["question"] == $next_question_id) {
1775 // constraint concerning a question that follows -> delete constraint
1776 $this->deleteConstraint($constraint["id"]);
1777 }
1778 }
1779 }
1780 }
1781 $this->saveQuestionsToDb();
1782 }
1783
1790 public function removeQuestion($question_id)
1791 {
1792 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
1793 $question = self::_instanciateQuestion($question_id);
1794 #20610 if no question found, do nothing.
1795 if ($question) {
1796 $question->delete($question_id);
1797 $this->removeConstraintsConcerningQuestion($question_id);
1798 }
1799 }
1800
1807 public function removeConstraintsConcerningQuestion($question_id)
1808 {
1809 $ilDB = $this->db;
1810 $result = $ilDB->queryF(
1811 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1812 array('integer','integer'),
1813 array($question_id, $this->getSurveyId())
1814 );
1815 if ($result->numRows() > 0) {
1816 $remove_constraints = array();
1817 while ($row = $ilDB->fetchAssoc($result)) {
1818 array_push($remove_constraints, $row["constraint_fi"]);
1819 }
1820 $affectedRows = $ilDB->manipulateF(
1821 "DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1822 array('integer','integer'),
1823 array($question_id, $this->getSurveyId())
1824 );
1825 foreach ($remove_constraints as $key => $constraint_id) {
1826 $affectedRows = $ilDB->manipulateF(
1827 "DELETE FROM svy_constraint WHERE constraint_id = %s",
1828 array('integer'),
1829 array($constraint_id)
1830 );
1831 }
1832 }
1833 }
1834
1842 public function removeQuestions($remove_questions, $remove_questionblocks)
1843 {
1844 $ilDB = $this->db;
1845
1846 $block_sizes = array();
1847 foreach ($this->getSurveyQuestions() as $question_id => $data) {
1848 if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks)) {
1849 unset($this->questions[array_search($question_id, $this->questions)]);
1850 $this->removeQuestion($question_id);
1851 } elseif ($data["questionblock_id"]) {
1852 $block_sizes[$data["questionblock_id"]]++;
1853 }
1854 }
1855
1856 // blocks with just 1 question need to be deleted
1857 foreach ($block_sizes as $block_id => $size) {
1858 if ($size < 2) {
1859 $remove_questionblocks[] = $block_id;
1860 }
1861 }
1862
1863 foreach (array_unique($remove_questionblocks) as $questionblock_id) {
1864 $affectedRows = $ilDB->manipulateF(
1865 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1866 array('integer'),
1867 array($questionblock_id)
1868 );
1869 $affectedRows = $ilDB->manipulateF(
1870 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1871 array('integer','integer'),
1872 array($questionblock_id, $this->getSurveyId())
1873 );
1874 }
1875
1876 $this->questions = array_values($this->questions);
1877 $this->saveQuestionsToDb();
1878 }
1879
1886 public function unfoldQuestionblocks($questionblocks)
1887 {
1888 $ilDB = $this->db;
1889 foreach ($questionblocks as $index) {
1890 $affectedRows = $ilDB->manipulateF(
1891 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1892 array('integer'),
1893 array($index)
1894 );
1895 $affectedRows = $ilDB->manipulateF(
1896 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1897 array('integer','integer'),
1898 array($index, $this->getSurveyId())
1899 );
1900 }
1901 }
1902
1903 public function removeQuestionFromBlock($question_id, $questionblock_id)
1904 {
1905 $ilDB = $this->db;
1906
1907 $affectedRows = $ilDB->manipulateF(
1908 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
1909 array('integer','integer','integer'),
1910 array($questionblock_id, $this->getSurveyId(), $question_id)
1911 );
1912 }
1913
1914 public function addQuestionToBlock($question_id, $questionblock_id)
1915 {
1916 $ilDB = $this->db;
1917
1918 // see #22018
1919 if (!$this->isQuestionInAnyBlock($question_id)) {
1920 $next_id = $ilDB->nextId('svy_qblk_qst');
1921 $affectedRows = $ilDB->manipulateF(
1922 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
1923 "question_fi) VALUES (%s, %s, %s, %s)",
1924 array('integer', 'integer', 'integer', 'integer'),
1925 array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
1926 );
1927
1928 $this->deleteConstraints($question_id); // #13713
1929 }
1930 }
1931
1938 public function isQuestionInAnyBlock($a_question_fi)
1939 {
1940 global $DIC;
1941
1942 $ilDB = $DIC->database();
1943
1944 $set = $ilDB->query("SELECT * FROM svy_qblk_qst " .
1945 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
1946 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
1947 if ($rec = $ilDB->fetchAssoc($set)) {
1948 return true;
1949 }
1950 return false;
1951 }
1952
1953
1960 public function &getQuestionblockQuestions($questionblock_id)
1961 {
1962 $ilDB = $this->db;
1963 $titles = array();
1964 $result = $ilDB->queryF(
1965 "SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM " .
1966 "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
1967 "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
1968 array('integer'),
1969 array($questionblock_id)
1970 );
1971 $survey_id = "";
1972 while ($row = $ilDB->fetchAssoc($result)) {
1973 $titles[$row["question_fi"]] = $row["title"];
1974 $survey_id = $row["survey_fi"];
1975 }
1976 $result = $ilDB->queryF(
1977 "SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1978 array('integer'),
1979 array($survey_id)
1980 );
1981 $resultarray = array();
1982 $counter = 1;
1983 while ($row = $ilDB->fetchAssoc($result)) {
1984 if (array_key_exists($row["question_fi"], $titles)) {
1985 $resultarray[$counter++] = $titles[$row["question_fi"]];
1986 }
1987 }
1988 return $resultarray;
1989 }
1990
1997 public function &getQuestionblockQuestionIds($questionblock_id)
1998 {
1999 $ilDB = $this->db;
2000
2001 // we need a correct order here, see #22011
2002 $result = $ilDB->queryF(
2003 "SELECT a.question_fi FROM svy_qblk_qst a JOIN svy_svy_qst b ON (a.question_fi = b.question_fi) " .
2004 " WHERE a.questionblock_fi = %s ORDER BY b.sequence",
2005 array("integer"),
2006 array($questionblock_id)
2007 );
2008 $ids = array();
2009 if ($result->numRows()) {
2010 while ($data = $ilDB->fetchAssoc($result)) {
2011 if (!in_array($data['question_fi'], $ids)) { // no duplicates, see #22018
2012 array_push($ids, $data['question_fi']);
2013 }
2014 }
2015 }
2016
2017 return $ids;
2018 }
2019
2027 public static function _getQuestionblock($questionblock_id)
2028 {
2029 global $DIC;
2030
2031 $ilDB = $DIC->database();
2032 $result = $ilDB->queryF(
2033 "SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2034 array('integer'),
2035 array($questionblock_id)
2036 );
2037 $row = $ilDB->fetchAssoc($result);
2038 return $row;
2039 }
2040
2049 public static function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false)
2050 {
2051 global $DIC;
2052
2053 $ilDB = $DIC->database();
2054 $next_id = $ilDB->nextId('svy_qblk');
2055 $ilDB->manipulateF(
2056 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
2057 " show_blocktitle, owner_fi, tstamp) " .
2058 "VALUES (%s, %s, %s, %s, %s, %s)",
2059 array('integer','text','integer','integer','integer','integer'),
2060 array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time())
2061 );
2062 return $next_id;
2063 }
2064
2072 public function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
2073 {
2074 $ilDB = $this->db;
2075
2076 // if the selected questions are not in a continous selection, move all questions of the
2077 // questionblock at the position of the first selected question
2078 $this->moveQuestions($questions, $questions[0], 0);
2079
2080 // now save the question block
2082 $next_id = $ilDB->nextId('svy_qblk');
2083 $affectedRows = $ilDB->manipulateF(
2084 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
2085 " show_blocktitle, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
2086 array('integer','text','text','text','integer','integer'),
2087 array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time())
2088 );
2089 if ($affectedRows) {
2090 $questionblock_id = $next_id;
2091 foreach ($questions as $index) {
2092 if (!$this->isQuestionInAnyBlock($index)) {
2093 $next_id = $ilDB->nextId('svy_qblk_qst'); // #22018
2094 $affectedRows = $ilDB->manipulateF(
2095 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2096 "question_fi) VALUES (%s, %s, %s, %s)",
2097 array('integer', 'integer', 'integer', 'integer'),
2098 array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2099 );
2100 $this->deleteConstraints($index);
2101 }
2102 }
2103 }
2104 }
2105
2113 public function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
2114 {
2115 $ilDB = $this->db;
2116 $affectedRows = $ilDB->manipulateF(
2117 "UPDATE svy_qblk SET title = %s, show_questiontext = %s," .
2118 " show_blocktitle = %s WHERE questionblock_id = %s",
2119 array('text','text','text','integer'),
2120 array($title, $show_questiontext, $show_blocktitle, $questionblock_id)
2121 );
2122 }
2123
2130 public function deleteConstraints($question_id)
2131 {
2132 $ilDB = $this->db;
2133 $result = $ilDB->queryF(
2134 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2135 array('integer','integer'),
2136 array($question_id, $this->getSurveyId())
2137 );
2138 $constraints = array();
2139 while ($row = $ilDB->fetchAssoc($result)) {
2140 array_push($constraints, $row["constraint_fi"]);
2141 }
2142 foreach ($constraints as $constraint_id) {
2143 $this->deleteConstraint($constraint_id);
2144 }
2145 }
2146
2154 public function deleteConstraint($constraint_id)
2155 {
2156 $ilDB = $this->db;
2157 $affectedRows = $ilDB->manipulateF(
2158 "DELETE FROM svy_constraint WHERE constraint_id = %s",
2159 array('integer'),
2160 array($constraint_id)
2161 );
2162 $affectedRows = $ilDB->manipulateF(
2163 "DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2164 array('integer'),
2165 array($constraint_id)
2166 );
2167 }
2168
2174 public function &getSurveyQuestions($with_answers = false)
2175 {
2176 $ilDB = $this->db;
2177 // get questionblocks
2178 $all_questions = array();
2179 $result = $ilDB->queryF(
2180 "SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, " .
2181 "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2182 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2183 "ORDER BY svy_svy_qst.sequence",
2184 array('integer'),
2185 array($this->getSurveyId())
2186 );
2187 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2188 while ($row = $ilDB->fetchAssoc($result)) {
2189 $add = true;
2190 if ($row["plugin"]) {
2191 if (!$this->isPluginActive($row["type_tag"])) {
2192 $add = false;
2193 }
2194 }
2195 if ($add) {
2196 $question = self::_instanciateQuestion($row["question_id"]);
2197 $questionrow = $question->getQuestionDataArray($row["question_id"]);
2198 foreach ($row as $key => $value) {
2199 $questionrow[$key] = $value;
2200 }
2201 $all_questions[$row["question_id"]] = $questionrow;
2202 $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2203 $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2204 }
2205 }
2206 // get all questionblocks
2207 $questionblocks = array();
2208 if (count($all_questions)) {
2209 $result = $ilDB->queryF(
2210 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2211 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2212 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2213 array('integer'),
2214 array($this->getSurveyId())
2215 );
2216 while ($row = $ilDB->fetchAssoc($result)) {
2217 $questionblocks[$row['question_fi']] = $row;
2218 }
2219 }
2220
2221 foreach ($all_questions as $question_id => $row) {
2222 $constraints = $this->getConstraints($question_id);
2223 if (isset($questionblocks[$question_id])) {
2224 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2225 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2226 $all_questions[$question_id]["constraints"] = $constraints;
2227 } else {
2228 $all_questions[$question_id]["questionblock_title"] = "";
2229 $all_questions[$question_id]["questionblock_id"] = "";
2230 $all_questions[$question_id]["constraints"] = $constraints;
2231 }
2232 if ($with_answers) {
2233 $answers = array();
2234 $result = $ilDB->queryF(
2235 "SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2236 "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id " .
2237 "ORDER BY sequence ASC",
2238 array('integer'),
2239 array($question_id)
2240 );
2241 if ($result->numRows() > 0) {
2242 while ($data = $ilDB->fetchAssoc($result)) {
2243 array_push($answers, $data["title"]);
2244 }
2245 }
2246 $all_questions[$question_id]["answers"] = $answers;
2247 }
2248 }
2249 return $all_questions;
2250 }
2251
2258 public function setObligatoryStates($obligatory_questions)
2259 {
2260 $ilDB = $this->db;
2261 $result = $ilDB->queryF(
2262 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2263 array('integer'),
2264 array($this->getSurveyId())
2265 );
2266 if ($result->numRows()) {
2267 while ($row = $ilDB->fetchAssoc($result)) {
2268 if (!array_key_exists($row["question_fi"], $obligatory_questions)) {
2269 $obligatory_questions[$row["question_fi"]] = 0;
2270 }
2271 }
2272 }
2273
2274 // set the obligatory states in the database
2275 foreach ($obligatory_questions as $question_fi => $obligatory) {
2276 // #12420
2277 $ilDB->manipulate("UPDATE svy_question" .
2278 " SET obligatory = " . $ilDB->quote($obligatory, "integer") .
2279 " WHERE question_id = " . $ilDB->quote($question_fi, "integer"));
2280 }
2281 }
2282
2288 public function &getSurveyPages()
2289 {
2290 $ilDB = $this->db;
2291 // get questionblocks
2292 $all_questions = array();
2293 $result = $ilDB->queryF(
2294 "SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2295 "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2296 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2297 "ORDER BY svy_svy_qst.sequence",
2298 array('integer'),
2299 array($this->getSurveyId())
2300 );
2301 while ($row = $ilDB->fetchAssoc($result)) {
2302 $all_questions[$row["question_id"]] = $row;
2303 }
2304 // get all questionblocks
2305 $questionblocks = array();
2306 if (count($all_questions)) {
2307 $result = $ilDB->queryF(
2308 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst " .
2309 "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2310 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2311 array('integer'),
2312 array($this->getSurveyId())
2313 );
2314 while ($row = $ilDB->fetchAssoc($result)) {
2315 $questionblocks[$row['question_fi']] = $row;
2316 }
2317 }
2318
2319 $all_pages = array();
2320 $pageindex = -1;
2321 $currentblock = "";
2322 foreach ($all_questions as $question_id => $row) {
2323 $constraints = array();
2324 if (isset($questionblocks[$question_id])) {
2325 if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id'])) {
2326 $pageindex++;
2327 }
2328 $all_questions[$question_id]['page'] = $pageindex;
2329 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2330 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2331 $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2332 $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2333 $currentblock = $questionblocks[$question_id]['questionblock_id'];
2334 $constraints = $this->getConstraints($question_id);
2335 $all_questions[$question_id]["constraints"] = $constraints;
2336 } else {
2337 $pageindex++;
2338 $all_questions[$question_id]['page'] = $pageindex;
2339 $all_questions[$question_id]["questionblock_title"] = "";
2340 $all_questions[$question_id]["questionblock_id"] = "";
2341 $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2342 $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2343 $currentblock = "";
2344 $constraints = $this->getConstraints($question_id);
2345 $all_questions[$question_id]["constraints"] = $constraints;
2346 }
2347 if (!isset($all_pages[$pageindex])) {
2348 $all_pages[$pageindex] = array();
2349 }
2350 array_push($all_pages[$pageindex], $all_questions[$question_id]);
2351 }
2352 // calculate position percentage for every page
2353 $max = count($all_pages);
2354 $counter = 1;
2355 foreach ($all_pages as $index => $block) {
2356 foreach ($block as $blockindex => $question) {
2357 $all_pages[$index][$blockindex]["position"] = $counter / $max;
2358 }
2359 $counter++;
2360 }
2361
2362 return $all_pages;
2363 }
2364
2373 public function getNextPage($active_page_question_id, $direction)
2374 {
2375 $foundpage = -1;
2376 $pages = &$this->getSurveyPages();
2377 if (strcmp($active_page_question_id, "") == 0) {
2378 return $pages[0];
2379 }
2380 foreach ($pages as $key => $question_array) {
2381 foreach ($question_array as $question) {
2382 if ($active_page_question_id == $question["question_id"]) {
2383 $foundpage = $key;
2384 }
2385 }
2386 }
2387 if ($foundpage == -1) {
2388 // error: page not found
2389 } else {
2390 $foundpage += $direction;
2391 if ($foundpage < 0) {
2392 return 0;
2393 }
2394 if ($foundpage >= count($pages)) {
2395 return 1;
2396 }
2397 return $pages[$foundpage];
2398 }
2399 }
2400
2407 public function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = false, $permission = "read")
2408 {
2409 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
2410 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2411 }
2412
2418 public function getPrecondition($id)
2419 {
2420 $ilDB = $this->db;
2421
2422 $result_array = array();
2423 $result = $ilDB->queryF(
2424 "SELECT svy_constraint.*, svy_relation.*, svy_qst_constraint.question_fi ref_question_fi FROM svy_qst_constraint, svy_constraint, " .
2425 "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2426 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2427 array('integer'),
2428 array($id)
2429 );
2430 $pc = array();
2431 if ($result->numRows()) {
2432 $pc = $ilDB->fetchAssoc($result);
2433 }
2434 return $pc;
2435 }
2436
2442 public function getConstraints($question_id)
2443 {
2444 $ilDB = $this->db;
2445
2446 $result_array = array();
2447 $result = $ilDB->queryF(
2448 "SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation " .
2449 "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2450 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s " .
2451 "AND svy_qst_constraint.survey_fi = %s",
2452 array('integer','integer'),
2453 array($question_id, $this->getSurveyId())
2454 );
2455 while ($row = $ilDB->fetchAssoc($result)) {
2456 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2457 $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2458 SurveyQuestion::_includeClass($question_type);
2459 $question = new $question_type();
2460 $question->loadFromDb($row["question_fi"]);
2461 $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2462 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));
2463 }
2464 return $result_array;
2465 }
2466
2472 public static function _getConstraints($survey_id)
2473 {
2474 global $DIC;
2475
2476 $ilDB = $DIC->database();
2477 $result_array = array();
2478 $result = $ilDB->queryF(
2479 "SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* " .
2480 "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id " .
2481 "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2482 array('integer'),
2483 array($survey_id)
2484 );
2485 while ($row = $ilDB->fetchAssoc($result)) {
2486 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']));
2487 }
2488 return $result_array;
2489 }
2490
2491
2497 public function &getVariables($question_id)
2498 {
2499 $ilDB = $this->db;
2500
2501 $result_array = array();
2502 $result = $ilDB->queryF(
2503 "SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN " .
2504 "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s " .
2505 "ORDER BY svy_variable.sequence",
2506 array('integer'),
2507 array($question_id)
2508 );
2509 while ($row = $ilDB->fetchObject($result)) {
2510 $result_array[$row->sequence] = $row;
2511 }
2512 return $result_array;
2513 }
2514
2523 public function addConstraint($if_question_id, $relation, $value, $conjunction)
2524 {
2525 $ilDB = $this->db;
2526
2527 $next_id = $ilDB->nextId('svy_constraint');
2528 $affectedRows = $ilDB->manipulateF(
2529 "INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES " .
2530 "(%s, %s, %s, %s, %s)",
2531 array('integer','integer','integer','float', 'integer'),
2532 array($next_id, $if_question_id, $relation, $value, $conjunction)
2533 );
2534 if ($affectedRows) {
2535 return $next_id;
2536 } else {
2537 return null;
2538 }
2539 }
2540
2541
2548 public function addConstraintToQuestion($to_question_id, $constraint_id)
2549 {
2550 $ilDB = $this->db;
2551
2552 $next_id = $ilDB->nextId('svy_qst_constraint');
2553 $affectedRows = $ilDB->manipulateF(
2554 "INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, " .
2555 "constraint_fi) VALUES (%s, %s, %s, %s)",
2556 array('integer','integer','integer','integer'),
2557 array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2558 );
2559 }
2560
2571 public function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2572 {
2573 $ilDB = $this->db;
2574 $affectedRows = $ilDB->manipulateF(
2575 "UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s " .
2576 "WHERE constraint_id = %s",
2577 array('integer','integer','float','integer','integer'),
2578 array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2579 );
2580 }
2581
2582 public function updateConjunctionForQuestions($questions, $conjunction)
2583 {
2584 $ilDB = $this->db;
2585 foreach ($questions as $question_id) {
2586 $affectedRows = $ilDB->manipulateF(
2587 "UPDATE svy_constraint SET conjunction = %s " .
2588 "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2589 array('integer','integer'),
2590 array($conjunction, $question_id)
2591 );
2592 }
2593 }
2594
2600 public function getAllRelations($short_as_key = false)
2601 {
2602 $ilDB = $this->db;
2603
2604 // #7987
2605 $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2606 $custom_order = array_flip($custom_order);
2607
2608 $result_array = array();
2609 $result = $ilDB->query("SELECT * FROM svy_relation");
2610 while ($row = $ilDB->fetchAssoc($result)) {
2611 if ($short_as_key) {
2612 $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2613 } else {
2614 $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2615 }
2616 }
2617
2618 $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2619 foreach ($result_array as $idx => $item) {
2620 unset($result_array[$idx]["order"]);
2621 }
2622
2623 return $result_array;
2624 }
2625
2629 public function disinviteAllUsers()
2630 {
2631 $ilDB = $this->db;
2632 $result = $ilDB->queryF(
2633 "SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2634 array('integer'),
2635 array($this->getSurveyId())
2636 );
2637 while ($row = $ilDB->fetchAssoc($result)) {
2638 $this->disinviteUser($row['user_fi']);
2639 }
2640 }
2641
2647 public function disinviteUser($user_id)
2648 {
2649 $ilDB = $this->db;
2650
2651 $affectedRows = $ilDB->manipulateF(
2652 "DELETE FROM svy_inv_usr WHERE survey_fi = %s AND user_fi = %s",
2653 array('integer','integer'),
2654 array($this->getSurveyId(), $user_id)
2655 );
2656 include_once './Services/User/classes/class.ilObjUser.php';
2657 ilObjUser::_dropDesktopItem($user_id, $this->getRefId(), "svy");
2658 }
2659
2666 public function inviteUser($user_id)
2667 {
2668 $ilDB = $this->db;
2669
2670 $result = $ilDB->queryF(
2671 "SELECT user_fi FROM svy_inv_usr WHERE user_fi = %s AND survey_fi = %s",
2672 array('integer','integer'),
2673 array($user_id, $this->getSurveyId())
2674 );
2675 if ($result->numRows() < 1) {
2676 $next_id = $ilDB->nextId('svy_inv_usr');
2677 $affectedRows = $ilDB->manipulateF(
2678 "INSERT INTO svy_inv_usr (invited_user_id, survey_fi, user_fi, tstamp) " .
2679 "VALUES (%s, %s, %s, %s)",
2680 array('integer','integer','integer','integer'),
2681 array($next_id, $this->getSurveyId(), $user_id, time())
2682 );
2683 }
2684 if ($this->getInvitation() == self::INVITATION_ON) {
2685 include_once './Services/User/classes/class.ilObjUser.php';
2686 ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2687 }
2688 }
2689
2696 public function &getInvitedUsers()
2697 {
2698 $ilDB = $this->db;
2699
2700 $result_array = array();
2701 $result = $ilDB->queryF(
2702 "SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2703 array('integer'),
2704 array($this->getSurveyId())
2705 );
2706 while ($row = $ilDB->fetchAssoc($result)) {
2707 array_push($result_array, $row["user_fi"]);
2708 }
2709 return $result_array;
2710 }
2711
2719 public function deleteWorkingData($question_id, $active_id)
2720 {
2721 $ilDB = $this->db;
2722
2723 $affectedRows = $ilDB->manipulateF(
2724 "DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2725 array('integer','integer'),
2726 array($question_id, $active_id)
2727 );
2728 }
2729
2738 public function loadWorkingData($question_id, $active_id)
2739 {
2740 $ilDB = $this->db;
2741 $result_array = array();
2742 $result = $ilDB->queryF(
2743 "SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2744 array('integer','integer'),
2745 array($question_id, $active_id)
2746 );
2747 if ($result->numRows() >= 1) {
2748 while ($row = $ilDB->fetchAssoc($result)) {
2749 array_push($result_array, $row);
2750 }
2751 return $result_array;
2752 } else {
2753 return $result_array;
2754 }
2755 }
2756
2763 public function startSurvey($user_id, $anonymous_id, $appraisee_id)
2764 {
2765 $ilDB = $this->db;
2766
2767 if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) {
2768 return;
2769 }
2770
2771 if (strcmp($user_id, "") == 0) {
2772 if ($user_id == ANONYMOUS_USER_ID) {
2773 $user_id = 0;
2774 }
2775 }
2776 $next_id = $ilDB->nextId('svy_finished');
2777 $affectedRows = $ilDB->manipulateF(
2778 "INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) " .
2779 "VALUES (%s, %s, %s, %s, %s, %s, %s)",
2780 array('integer','integer','integer','text','text','integer','integer'),
2781 array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
2782 );
2783 return $next_id;
2784 }
2785
2792 public function finishSurvey($finished_id)
2793 {
2794 $ilDB = $this->db;
2795
2796 $ilDB->manipulateF(
2797 "UPDATE svy_finished SET state = %s, tstamp = %s" .
2798 " WHERE survey_fi = %s AND finished_id = %s",
2799 array('text','integer','integer','integer'),
2800 array(1, time(), $this->getSurveyId(), $finished_id)
2801 );
2802
2803 // self eval writes skills on finishing
2804 if ($this->getMode() == ilObjSurvey::MODE_SELF_EVAL) {
2805 $user = $this->getUserDataFromActiveId($finished_id);
2806 $sskill = new ilSurveySkill($this);
2807 $sskill->writeSelfEvalSkills($user['usr_id']);
2808 }
2809
2810 $this->checkTutorNotification();
2811 }
2812
2820 public function setPage($finished_id, $page_id)
2821 {
2822 $ilDB = $this->db;
2823
2824 $affectedRows = $ilDB->manipulateF(
2825 "UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
2826 array('integer','integer'),
2827 array(($page_id) ? $page_id : 0, $finished_id)
2828 );
2829 }
2830
2836 public function sendNotificationMail($a_user_id, $a_anonymize_id, $a_appr_id)
2837 {
2838 // #12755
2839 $placeholders = array(
2840 "FIRST_NAME" => "firstname",
2841 "LAST_NAME" => "lastname",
2842 "LOGIN" => "login",
2843 // old style
2844 "firstname" => "firstname"
2845 );
2846
2847 //mailaddresses is just text split by commas.
2848 //sendMail can send emails if it gets an user id or an email as first parameter.
2849 $recipients = preg_split('/,/', $this->mailaddresses);
2850 foreach ($recipients as $recipient) {
2851 // #11298
2852 $ntf = new ilSystemNotification();
2853 $ntf->setLangModules(array("survey"));
2854 $ntf->setRefId($this->getRefId());
2855 $ntf->setSubjectLangId('finished_mail_subject');
2856
2857 $messagetext = $this->mailparticipantdata;
2858 if (trim($messagetext)) {
2859 if (!$this->hasAnonymizedResults()) {
2860 $data = ilObjUser::_getUserData(array($a_user_id));
2861 $data = $data[0];
2862 }
2863 foreach ($placeholders as $key => $mapping) {
2864 if ($this->hasAnonymizedResults()) { // #16480
2865 $messagetext = str_replace('[' . $key . ']', '', $messagetext);
2866 } else {
2867 $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
2868 }
2869 }
2870 $ntf->setIntroductionDirect($messagetext);
2871 } else {
2872 $ntf->setIntroductionLangId('survey_notification_finished_introduction');
2873 }
2874
2875 // 360°? add appraisee data
2876 if ($a_appr_id) {
2877 $ntf->addAdditionalInfo(
2878 'survey_360_appraisee',
2880 );
2881 }
2882
2883 $active_id = $this->getActiveID($a_user_id, $a_anonymize_id, $a_appr_id);
2884 $ntf->addAdditionalInfo(
2885 'results',
2886 $this->getParticipantTextResults($active_id),
2887 true
2888 );
2889
2890 $ntf->setGotoLangId('survey_notification_tutor_link');
2891 $ntf->setReasonLangId('survey_notification_finished_reason');
2892
2893 if (is_numeric($recipient)) {
2894 $lng = $ntf->getUserLanguage($recipient);
2895 $ntf->sendMail(array($recipient), null, null);
2896 } else {
2897 $recipient = trim($recipient);
2898 $user_ids = ilObjUser::getUserIdsByEmail($recipient);
2899 if (empty($user_ids)) {
2900 $ntf->sendMail(array($recipient), null, null);
2901 } else {
2902 foreach ($user_ids as $user_id) {
2903 $lng = $ntf->getUserLanguage($user_id);
2904 $ntf->sendMail(array($user_id), null, null);
2905 }
2906 }
2907 }
2908 }
2909 }
2910
2911 protected function getParticipantTextResults($active_id)
2912 {
2913 $textresult = "";
2914 $userResults = &$this->getUserSpecificResults(array($active_id));
2915 $questions = &$this->getSurveyQuestions(true);
2916 $questioncounter = 1;
2917 foreach ($questions as $question_id => $question_data) {
2918 $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
2919 $found = $userResults[$question_id][$active_id];
2920 $text = "";
2921 if (is_array($found)) {
2922 $text = implode("\n", $found);
2923 } else {
2924 $text = $found;
2925 }
2926 if (strlen($text) == 0) {
2928 }
2929 $text = str_replace("<br />", "\n", $text);
2930 $textresult .= $text . "\n\n";
2931 }
2932 return $textresult;
2933 }
2934
2942 public function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
2943 {
2944 $ilDB = $this->db;
2945
2946 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2947 if ($anonymize_id) {
2948 $result = $ilDB->queryF(
2949 "SELECT * FROM svy_finished" .
2950 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2951 array('integer','text','integer'),
2952 array($this->getSurveyId(), $anonymize_id, $appr_id)
2953 );
2954 } else {
2955 $result = $ilDB->queryF(
2956 "SELECT * FROM svy_finished" .
2957 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2958 array('integer','integer','integer'),
2959 array($this->getSurveyId(), $user_id, $appr_id)
2960 );
2961 }
2962 if ($result->numRows() == 0) {
2963 return false;
2964 } else {
2965 $row = $ilDB->fetchAssoc($result);
2966 // yes, we are doing it this way
2967 $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
2968
2969 return (int) $row["state"];
2970 }
2971 }
2972
2980 public function getActiveID($user_id, $anonymize_id, $appr_id)
2981 {
2982 $ilDB = $this->db;
2983
2984 // see self::isSurveyStarted()
2985
2986 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2987 if ($anonymize_id) {
2988 $result = $ilDB->queryF(
2989 "SELECT finished_id FROM svy_finished" .
2990 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2991 array('integer','text','integer'),
2992 array($this->getSurveyId(), $anonymize_id, $appr_id)
2993 );
2994 } else {
2995 $result = $ilDB->queryF(
2996 "SELECT finished_id FROM svy_finished" .
2997 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2998 array('integer','integer','integer'),
2999 array($this->getSurveyId(), $user_id, $appr_id)
3000 );
3001 }
3002 if ($result->numRows() == 0) {
3003 return false;
3004 } else {
3005 $row = $ilDB->fetchAssoc($result);
3006 return $row["finished_id"];
3007 }
3008 }
3009
3017 public function getLastActivePage($active_id)
3018 {
3019 $ilDB = $this->db;
3020 $result = $ilDB->queryF(
3021 "SELECT lastpage FROM svy_finished WHERE finished_id = %s",
3022 array('integer'),
3023 array($active_id)
3024 );
3025 if ($result->numRows() == 0) {
3026 return "";
3027 } else {
3028 $row = $ilDB->fetchAssoc($result);
3029 return ($row["lastpage"]) ? $row["lastpage"] : '';
3030 }
3031 }
3032
3041 public function checkConstraint($constraint_data, $working_data)
3042 {
3043 if (!is_array($working_data) || count($working_data) == 0) {
3044 return 0;
3045 }
3046
3047 if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0)) {
3048 return 0;
3049 }
3050
3051 $found = false;
3052 foreach ($working_data as $data) {
3053 switch ($constraint_data["short"]) {
3054 case "<":
3055 if ($data["value"] < $constraint_data["value"]) {
3056 $found = true;
3057 }
3058 break;
3059
3060 case "<=":
3061 if ($data["value"] <= $constraint_data["value"]) {
3062 $found = true;
3063 }
3064 break;
3065
3066 case "=":
3067 if ($data["value"] == $constraint_data["value"]) {
3068 $found = true;
3069 }
3070 break;
3071
3072 case "<>":
3073 if ($data["value"] <> $constraint_data["value"]) {
3074 $found = true;
3075 }
3076 break;
3077
3078 case ">=":
3079 if ($data["value"] >= $constraint_data["value"]) {
3080 $found = true;
3081 }
3082 break;
3083
3084 case ">":
3085 if ($data["value"] > $constraint_data["value"]) {
3086 $found = true;
3087 }
3088 break;
3089 }
3090 if ($found) {
3091 break;
3092 }
3093 }
3094
3095 return (int) $found;
3096 }
3097
3098 public static function _hasDatasets($survey_id)
3099 {
3100 global $DIC;
3101
3102 $ilDB = $DIC->database();
3103
3104 $result = $ilDB->queryF(
3105 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3106 array('integer'),
3107 array($survey_id)
3108 );
3109 return ($result->numRows()) ? true : false;
3110 }
3111
3118 public function &getSurveyFinishedIds()
3119 {
3120 $ilDB = $this->db;
3122
3123 $users = array();
3124 $result = $ilDB->queryF(
3125 "SELECT * FROM svy_finished WHERE survey_fi = %s",
3126 array('integer'),
3127 array($this->getSurveyId())
3128 );
3129 if ($result->numRows()) {
3130 while ($row = $ilDB->fetchAssoc($result)) {
3131 array_push($users, $row["finished_id"]);
3132 }
3133 }
3134 return $users;
3135 }
3136
3143 public function getUserSpecificResults($finished_ids)
3144 {
3145 $evaluation = array();
3146
3147 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3148 foreach (array_keys($this->getSurveyQuestions()) as $question_id) {
3149 // get question instance
3150 $question_type = SurveyQuestion::_getQuestionType($question_id);
3151 SurveyQuestion::_includeClass($question_type);
3152 $question = new $question_type();
3153 $question->loadFromDb($question_id);
3154
3155 $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($question_id, $finished_ids);
3156 $q_res = $q_eval->getResults();
3157
3158 $data = array();
3159 foreach ($finished_ids as $user_id) {
3160 $data[$user_id] = $q_eval->parseUserSpecificResults($q_res, $user_id);
3161 }
3162
3163 $evaluation[$question_id] = $data;
3164 }
3165
3166 return $evaluation;
3167 }
3168
3176 public function getUserDataFromActiveId($active_id, $force_non_anonymous = false)
3177 {
3178 $ilDB = $this->db;
3179
3180 $surveySetting = new ilSetting("survey");
3181 $use_anonymous_id = array_key_exists("use_anonymous_id", $_GET) ? $_GET["use_anonymous_id"] : $surveySetting->get("use_anonymous_id");
3182 $result = $ilDB->queryF(
3183 "SELECT * FROM svy_finished WHERE finished_id = %s",
3184 array('integer'),
3185 array($active_id)
3186 );
3187 $row = array();
3188 $foundrows = $result->numRows();
3189 if ($foundrows) {
3190 $row = $ilDB->fetchAssoc($result);
3191 }
3192 $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3193 $userdata = array(
3194 "fullname" => $name,
3195 "sortname" => $name,
3196 "firstname" => "",
3197 "lastname" => "",
3198 "login" => "",
3199 "gender" => "",
3200 "active_id" => "$active_id"
3201 );
3202 if ($foundrows) {
3203 if (($row["user_fi"] > 0) &&
3204 (($row["user_fi"] != ANONYMOUS_USER_ID &&
3205 !$this->hasAnonymizedResults() &&
3206 !$this->get360Mode()) || // 360° uses ANONYMIZE_CODE_ALL which is wrong - see ilObjSurveyGUI::afterSave()
3207 (bool) $force_non_anonymous)) {
3208 include_once './Services/User/classes/class.ilObjUser.php';
3209 if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0) {
3210 $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3211 } else {
3212 $user = new ilObjUser($row["user_fi"]);
3213 $userdata['usr_id'] = $row['user_fi'];
3214 $userdata["fullname"] = $user->getFullname();
3215 $gender = $user->getGender();
3216 if (strlen($gender) == 1) {
3217 $gender = $this->lng->txt("gender_$gender");
3218 }
3219 $userdata["gender"] = $gender;
3220 $userdata["firstname"] = $user->getFirstname();
3221 $userdata["lastname"] = $user->getLastname();
3222 $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3223 $userdata["login"] = $user->getLogin();
3224 }
3225 }
3226 }
3227 return $userdata;
3228 }
3229
3239 public function &getEvaluationByUser($questions, $active_id)
3240 {
3241 $ilDB = $this->db;
3242
3243 // collect all answers
3244 $answers = array();
3245 $result = $ilDB->queryF(
3246 "SELECT * FROM svy_answer WHERE active_fi = %s",
3247 array('integer'),
3248 array($active_id)
3249 );
3250 while ($row = $ilDB->fetchAssoc($result)) {
3251 if (!is_array($answers[$row["question_fi"]])) {
3252 $answers[$row["question_fi"]] = array();
3253 }
3254 array_push($answers[$row["question_fi"]], $row);
3255 }
3256 $userdata = $this->getUserDataFromActiveId($active_id);
3257 $resultset = array(
3258 "name" => $userdata["fullname"],
3259 "firstname" => $userdata["firstname"],
3260 "lastname" => $userdata["lastname"],
3261 "login" => $userdata["login"],
3262 "gender" => $userdata["gender"],
3263 "answers" => array()
3264 );
3265 foreach ($questions as $key => $question) {
3266 if (array_key_exists($key, $answers)) {
3267 $resultset["answers"][$key] = $answers[$key];
3268 } else {
3269 $resultset["answers"][$key] = array();
3270 }
3271 sort($resultset["answers"][$key]);
3272 }
3273 return $resultset;
3274 }
3275
3281 public function getQuestionsTable($arrFilter)
3282 {
3284 $ilDB = $this->db;
3285 $where = "";
3286 if (is_array($arrFilter)) {
3287 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3288 $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3289 }
3290 if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description'])) {
3291 $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3292 }
3293 if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author'])) {
3294 $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3295 }
3296 if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type'])) {
3297 $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3298 }
3299 if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl'])) {
3300 $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3301 }
3302 }
3303
3304 $spls = &$this->getAvailableQuestionpools($use_obj_id = true, $could_be_offline = false, $showPath = false);
3305 $forbidden = "";
3306 $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3307 $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3308 $existing = "";
3309 $existing_questions = &$this->getExistingQuestions();
3310 if (count($existing_questions)) {
3311 $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3312 }
3313
3314 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
3316
3317 $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id" .
3318 " FROM svy_question, svy_qtype, object_reference" .
3319 " WHERE svy_question.original_id IS NULL" . $forbidden . $existing .
3320 " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0" .
3321 " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3322
3323 $rows = array();
3324 if ($query_result->numRows()) {
3325 while ($row = $ilDB->fetchAssoc($query_result)) {
3326 if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt'])) {
3327 if (!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt'])) {
3328 continue;
3329 }
3330 }
3331
3332 $row['ttype'] = $trans[$row['type_tag']];
3333 if ($row["plugin"]) {
3334 if ($this->isPluginActive($row["type_tag"])) {
3335 array_push($rows, $row);
3336 }
3337 } else {
3338 array_push($rows, $row);
3339 }
3340 }
3341 }
3342 return $rows;
3343 }
3344
3350 public function getQuestionblocksTable($arrFilter)
3351 {
3353 $ilDB = $this->db;
3354
3355 $where = "";
3356 if (is_array($arrFilter)) {
3357 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3358 $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3359 }
3360 }
3361
3362 $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE " .
3363 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi " .
3364 "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, " .
3365 "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3366 $rows = array();
3367 if ($query_result->numRows()) {
3368 $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3369 $surveytitles = array();
3370 foreach ($survey_ref_ids as $survey_ref_id) {
3371 $survey_id = ilObject::_lookupObjId($survey_ref_id);
3373 }
3374 while ($row = $ilDB->fetchAssoc($query_result)) {
3375 $questions_array = &$this->getQuestionblockQuestions($row["questionblock_id"]);
3376 $counter = 1;
3377 foreach ($questions_array as $key => $value) {
3378 $questions_array[$key] = "$counter. $value";
3379 $counter++;
3380 }
3381 if (strlen($surveytitles[$row["obj_fi"]])) { // only questionpools which are not in trash
3382 $rows[$row["questionblock_id"]] = array(
3383 "questionblock_id" => $row["questionblock_id"],
3384 "title" => $row["title"],
3385 "svy" => $surveytitles[$row["obj_fi"]],
3386 "contains" => join(", ", $questions_array),
3387 "owner" => $row["owner_fi"]
3388 );
3389 }
3390 }
3391 }
3392 return $rows;
3393 }
3394
3401 public function toXML()
3402 {
3403 include_once("./Services/Xml/classes/class.ilXmlWriter.php");
3404 $a_xml_writer = new ilXmlWriter;
3405 // set xml header
3406 $a_xml_writer->xmlHeader();
3407 $attrs = array(
3408 "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3409 "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3410 );
3411 $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3412 $attrs = array(
3413 "id" => $this->getSurveyId(),
3414 "title" => $this->getTitle()
3415 );
3416 $a_xml_writer->xmlStartTag("survey", $attrs);
3417
3418 $a_xml_writer->xmlElement("description", null, $this->getDescription());
3419 $a_xml_writer->xmlElement("author", null, $this->getAuthor());
3420 $a_xml_writer->xmlStartTag("objectives");
3421 $attrs = array(
3422 "label" => "introduction"
3423 );
3424 $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), true, true, $attrs);
3425 $attrs = array(
3426 "label" => "outro"
3427 );
3428 $this->addMaterialTag($a_xml_writer, $this->getOutro(), true, true, $attrs);
3429 $a_xml_writer->xmlEndTag("objectives");
3430
3431 if ($this->getAnonymize()) {
3432 $attribs = array("enabled" => "1");
3433 } else {
3434 $attribs = array("enabled" => "0");
3435 }
3436 $a_xml_writer->xmlElement("anonymisation", $attribs);
3437 $a_xml_writer->xmlStartTag("restrictions");
3438 if ($this->getAnonymize() == 2) {
3439 $attribs = array("type" => "free");
3440 } else {
3441 $attribs = array("type" => "restricted");
3442 }
3443 $a_xml_writer->xmlElement("access", $attribs);
3444 if ($this->getStartDate()) {
3445 $attrs = array("type" => "date");
3446 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3447 $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]));
3448 }
3449 if ($this->getEndDate()) {
3450 $attrs = array("type" => "date");
3451 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3452 $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]));
3453 }
3454 $a_xml_writer->xmlEndTag("restrictions");
3455
3456 // constraints
3457 $pages = &$this->getSurveyPages();
3458 $hasconstraints = false;
3459 foreach ($pages as $question_array) {
3460 foreach ($question_array as $question) {
3461 if (count($question["constraints"])) {
3462 $hasconstraints = true;
3463 }
3464 }
3465 }
3466
3467 if ($hasconstraints) {
3468 $a_xml_writer->xmlStartTag("constraints");
3469 foreach ($pages as $question_array) {
3470 foreach ($question_array as $question) {
3471 if (count($question["constraints"])) {
3472 // found constraints
3473 foreach ($question["constraints"] as $constraint) {
3474 $attribs = array(
3475 "sourceref" => $question["question_id"],
3476 "destref" => $constraint["question"],
3477 "relation" => $constraint["short"],
3478 "value" => $constraint["value"],
3479 "conjunction" => $constraint["conjunction"]
3480 );
3481 $a_xml_writer->xmlElement("constraint", $attribs);
3482 }
3483 }
3484 }
3485 }
3486 $a_xml_writer->xmlEndTag("constraints");
3487 }
3488
3489 // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
3490 $a_xml_writer->xmlStartTag("metadata");
3491
3492 $custom_properties = array();
3493 $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
3494 $custom_properties["status"] = !$this->getOfflineStatus();
3495 $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
3496 $custom_properties["pool_usage"] = (int) $this->getPoolUsage();
3497
3498 $custom_properties["own_results_view"] = (int) $this->hasViewOwnResults();
3499 $custom_properties["own_results_mail"] = (int) $this->hasMailOwnResults();
3500 $custom_properties["confirmation_mail"] = (int) $this->hasMailConfirmation();
3501
3502 $custom_properties["anon_user_list"] = (int) $this->hasAnonymousUserList();
3503 $custom_properties["mode"] = (int) $this->getMode();
3504 $custom_properties["mode_360_self_eval"] = (int) $this->get360SelfEvaluation();
3505 $custom_properties["mode_360_self_rate"] = (int) $this->get360SelfRaters();
3506 $custom_properties["mode_360_self_appr"] = (int) $this->get360SelfAppraisee();
3507 $custom_properties["mode_360_results"] = $this->get360Results();
3508 $custom_properties["mode_skill_service"] = (int) $this->getSkillService();
3509 $custom_properties["mode_self_eval_results"] = (int) $this->getSelfEvaluationResults();
3510
3511
3512 // :TODO: skills?
3513
3514 // reminder/tutor notification are (currently?) not exportable
3515
3516 foreach ($custom_properties as $label => $value) {
3517 $a_xml_writer->xmlStartTag("metadatafield");
3518 $a_xml_writer->xmlElement("fieldlabel", null, $label);
3519 $a_xml_writer->xmlElement("fieldentry", null, $value);
3520 $a_xml_writer->xmlEndTag("metadatafield");
3521 }
3522
3523 $a_xml_writer->xmlStartTag("metadatafield");
3524 $a_xml_writer->xmlElement("fieldlabel", null, "SCORM");
3525 include_once "./Services/MetaData/classes/class.ilMD.php";
3526 $md = new ilMD($this->getId(), 0, $this->getType());
3527 $writer = new ilXmlWriter();
3528 $md->toXml($writer);
3529 $metadata = $writer->xmlDumpMem();
3530 $a_xml_writer->xmlElement("fieldentry", null, $metadata);
3531 $a_xml_writer->xmlEndTag("metadatafield");
3532
3533 $a_xml_writer->xmlEndTag("metadata");
3534 $a_xml_writer->xmlEndTag("survey");
3535
3536 $attribs = array("id" => $this->getId());
3537 $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
3538 // add questionblock descriptions
3539 foreach ($pages as $question_array) {
3540 if (count($question_array) > 1) {
3541 $attribs = array("id" => $question_array[0]["question_id"]);
3542 $attribs = array("showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
3543 "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"]);
3544 $a_xml_writer->xmlStartTag("questionblock", $attribs);
3545 if (strlen($question_array[0]["questionblock_title"])) {
3546 $a_xml_writer->xmlElement("questionblocktitle", null, $question_array[0]["questionblock_title"]);
3547 }
3548 }
3549 foreach ($question_array as $question) {
3550 if (strlen($question["heading"])) {
3551 $a_xml_writer->xmlElement("textblock", null, $question["heading"]);
3552 }
3553 $questionObject = self::_instanciateQuestion($question["question_id"]);
3554 //questionObject contains all the fields from the database. (loadFromDb)
3555 //we don't need the value from svy_qst_oblig table, we already have the values from svy_question table.
3556 //if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
3557 if ($questionObject !== false) {
3558 $questionObject->insertXML($a_xml_writer, false);
3559 }
3560 }
3561 if (count($question_array) > 1) {
3562 $a_xml_writer->xmlEndTag("questionblock");
3563 }
3564 }
3565
3566 $a_xml_writer->xmlEndTag("surveyquestions");
3567 $a_xml_writer->xmlEndTag("surveyobject");
3568 $xml = $a_xml_writer->xmlDumpMem(false);
3569 return $xml;
3570 }
3571
3579 public static function _instanciateQuestion($question_id)
3580 {
3581 if ($question_id < 1) {
3582 return false;
3583 }
3584 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3585 $question_type = SurveyQuestion::_getQuestionType($question_id);
3586 if (strlen($question_type) == 0) {
3587 return false;
3588 }
3589 SurveyQuestion::_includeClass($question_type);
3590 $question = new $question_type();
3591 $question->loadFromDb($question_id);
3592 return $question;
3593 }
3594
3601 public function locateImportFiles($a_dir)
3602 {
3603 if (!is_dir($a_dir) || is_int(strpos($a_dir, ".."))) {
3604 return;
3605 }
3606 $importDirectory = "";
3607 $xmlFile = "";
3608
3609 $current_dir = opendir($a_dir);
3610 $files = array();
3611 while ($entryname = readdir($current_dir)) {
3612 $files[] = $entryname;
3613 }
3614
3615 foreach ($files as $file) {
3616 if (is_dir($a_dir . "/" . $file) and ($file != "." and $file != "..")) {
3617 // found directory created by zip
3618 $importDirectory = $a_dir . "/" . $file;
3619 }
3620 }
3621 closedir($current_dir);
3622 if (strlen($importDirectory)) {
3623 // find the xml file
3624 $current_dir = opendir($importDirectory);
3625 $files = array();
3626 while ($entryname = readdir($current_dir)) {
3627 $files[] = $entryname;
3628 }
3629 foreach ($files as $file) {
3630 if (@is_file($importDirectory . "/" . $file) &&
3631 ($file != "." && $file != "..") &&
3632 (preg_match("/^[0-9]{10}__[0-9]+__(svy_)*[0-9]+\.[A-Za-z]{1,3}$/", $file) ||
3633 preg_match("/^[0-9]{10}__[0-9]+__(survey__)*[0-9]+\.[A-Za-z]{1,3}$/", $file))) {
3634 // found xml file
3635 $xmlFile = $importDirectory . "/" . $file;
3636 }
3637 }
3638 }
3639 return array("dir" => $importDirectory, "xml" => $xmlFile);
3640 }
3641
3650 public function importObject($file_info, $svy_qpl_id)
3651 {
3652 if ($svy_qpl_id < 1) {
3653 $svy_qpl_id = -1;
3654 }
3655 // check if file was uploaded
3656 $source = $file_info["tmp_name"];
3657 $error = "";
3658 if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK) {
3659 $error = $this->lng->txt("import_no_file_selected");
3660 }
3661 // check correct file type
3662 $isXml = false;
3663 $isZip = false;
3664 if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0)) {
3665 $this->log->debug("isXML");
3666 $isXml = true;
3667 }
3668 // too many different mime-types, so we use the suffix
3669 $suffix = pathinfo($file_info["name"]);
3670 if (strcmp(strtolower($suffix["extension"]), "zip") == 0) {
3671 $this->log->debug("isZip");
3672 $isZip = true;
3673 }
3674 if (!$isXml && !$isZip) {
3675 $error = $this->lng->txt("import_wrong_file_type");
3676 $this->log->debug("Survey: Import error. Filetype was \"" . $file_info["type"] . "\"");
3677 }
3678 if (strlen($error) == 0) {
3679 // import file as a survey
3680 $import_dir = $this->getImportDirectory();
3681 $import_subdir = "";
3682 $importfile = "";
3683 if ($isZip) {
3684 $importfile = $import_dir . "/" . $file_info["name"];
3685 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3686 ilUtil::unzip($importfile);
3687 $found = $this->locateImportFiles($import_dir);
3688 if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0))) {
3689 $error = $this->lng->txt("wrong_import_file_structure");
3690 return $error;
3691 }
3692 $importfile = $found["xml"];
3693 $import_subdir = $found["dir"];
3694 } else {
3695 $importfile = tempnam($import_dir, "survey_import");
3696 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3697 }
3698
3699 $this->log->debug("Import file = $importfile");
3700 $this->log->debug("Import subdir = $import_subdir");
3701
3702 $fh = fopen($importfile, "r");
3703 if (!$fh) {
3704 $error = $this->lng->txt("import_error_opening_file");
3705 return $error;
3706 }
3707 $xml = fread($fh, filesize($importfile));
3708 $result = fclose($fh);
3709 if (!$result) {
3710 $error = $this->lng->txt("import_error_closing_file");
3711 return $error;
3712 }
3713
3714 unset($_SESSION["import_mob_xhtml"]);
3715 if (strpos($xml, "questestinterop")) {
3716 include_once("./Modules/Survey/exceptions/class.ilInvalidSurveyImportFileException.php");
3717 throw new ilInvalidSurveyImportFileException("Unsupported survey version (< 3.8) found.");
3718 } else {
3719 $this->log->debug("survey id = " . $this->getId());
3720 $this->log->debug("question pool id = " . $svy_qpl_id);
3721
3722 include_once("./Services/Export/classes/class.ilImport.php");
3723 $imp = new ilImport();
3724 $config = $imp->getConfig("Modules/Survey");
3725 $config->setQuestionPoolID($svy_qpl_id);
3726 $imp->getMapping()->addMapping("Modules/Survey", "svy", 0, $this->getId());
3727 $imp->importFromDirectory($import_subdir, "svy", "Modules/Survey");
3728 $this->log->debug("config(Modules/survey)->getQuestionPoolId =" . $config->getQuestionPoolID());
3729 return "";
3730
3731 //old code
3732 include_once "./Services/Survey/classes/class.SurveyImportParser.php";
3733 $import = new SurveyImportParser($svy_qpl_id, "", true);
3734 $import->setSurveyObject($this);
3735 $import->setXMLContent($xml);
3736 $import->startParsing();
3737 }
3738
3739 if (is_array($_SESSION["import_mob_xhtml"])) {
3740 include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
3741 include_once "./Services/RTE/classes/class.ilRTE.php";
3742 include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3743 foreach ($_SESSION["import_mob_xhtml"] as $mob) {
3744 $importfile = $import_subdir . "/" . $mob["uri"];
3745 if (file_exists($importfile)) {
3746 if (!$mob["type"]) {
3747 $mob["type"] = "svy:html";
3748 }
3749
3750 $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, false);
3751
3752 // survey mob
3753 if ($mob["type"] == "svy:html") {
3754 ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
3755 $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
3756 $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
3757 }
3758 // question mob
3759 elseif ($import->questions[$mob["id"]]) {
3760 $new_qid = $import->questions[$mob["id"]];
3761 ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
3762 $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
3763 $qtext = $new_question->getQuestiontext();
3764 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
3765 $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
3766 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
3767 $new_question->setQuestiontext($qtext);
3768 $new_question->saveToDb();
3769
3770 // also fix existing original in pool
3771 if ($new_question->getOriginalId()) {
3772 $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
3773 $pool_question->setQuestiontext($qtext);
3774 $pool_question->saveToDb();
3775 }
3776 }
3777 } else {
3779 $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
3780 }
3781 }
3784 $this->saveToDb();
3785 }
3786
3787 // delete import directory
3789 }
3790 return $error;
3791 }
3792
3801 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
3802 {
3803 $ilDB = $this->db;
3804
3805 $this->loadFromDb();
3806
3807 //survey mode
3808 $svy_type = $this->getMode();
3809
3810 // Copy settings
3811 $newObj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
3812 $this->cloneMetaData($newObj);
3813 $newObj->updateMetaData();
3814
3815 $newObj->setAuthor($this->getAuthor());
3816 $newObj->setIntroduction($this->getIntroduction());
3817 $newObj->setOutro($this->getOutro());
3818 $newObj->setEvaluationAccess($this->getEvaluationAccess());
3819 $newObj->setStartDate($this->getStartDate());
3820 $newObj->setEndDate($this->getEndDate());
3821 $newObj->setInvitation($this->getInvitation());
3822 $newObj->setInvitationMode($this->getInvitationMode());
3823 $newObj->setAnonymize($this->getAnonymize());
3824 $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
3825 $newObj->setTemplate($this->getTemplate());
3826 $newObj->setPoolUsage($this->getPoolUsage());
3827 $newObj->setViewOwnResults($this->hasViewOwnResults());
3828 $newObj->setMailOwnResults($this->hasMailOwnResults());
3829 $newObj->setMailConfirmation($this->hasMailConfirmation());
3830 $newObj->setAnonymousUserList($this->hasAnonymousUserList());
3831
3832 // #12661
3833 if ($this->get360Mode()) {
3834 $newObj->setMode(ilObjSurvey::MODE_360);
3835 $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
3836 $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
3837 $newObj->set360SelfRaters($this->get360SelfRaters());
3838 $newObj->set360Results($this->get360Results());
3839 $newObj->setSkillService($this->getSkillService());
3840 }
3841 //svy mode self eval: skills + view results
3842 if ($svy_type == ilObjSurvey::MODE_SELF_EVAL) {
3843 $newObj->setMode(ilObjSurvey::MODE_SELF_EVAL);
3844 $newObj->setSkillService($this->getSkillService());
3845 $newObj->setSelfEvaluationResults($this->getSelfEvaluationResults());
3846 }
3847
3848 // reminder/notification
3849 $newObj->setReminderStatus($this->getReminderStatus());
3850 $newObj->setReminderStart($this->getReminderStart());
3851 $newObj->setReminderEnd($this->getReminderEnd());
3852 $newObj->setReminderFrequency($this->getReminderFrequency());
3853 $newObj->setReminderTarget($this->getReminderTarget());
3854 $newObj->setReminderTemplate($this->getReminderTemplate());
3855 // reminder_last_sent must not be copied!
3856 $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
3857 $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
3858 $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
3859
3860 $newObj->setMailNotification($this->getMailNotification());
3861 $newObj->setMailAddresses($this->getMailAddresses());
3862 $newObj->setMailParticipantData($this->getMailParticipantData());
3863
3864 $question_pointer = array();
3865 // clone the questions
3866 $mapping = array();
3867 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3868
3869 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->setObjId($newObj->getId());
3876 $question->saveToDb($original_id);
3877 $newObj->questions[$key] = $question->getId();
3878 $question_pointer[$question_id] = $question->getId();
3879 $mapping[$question_id] = $question->getId();
3880 }
3881 }
3882
3883 //copy online status if object is not the root copy object
3884 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
3885
3886 if (!$cp_options->isRootNode($this->getRefId())) {
3887 $newObj->setOfflineStatus($this->getOfflineStatus());
3888 }
3889
3890 $newObj->saveToDb();
3891 $newObj->cloneTextblocks($mapping);
3892
3893 // #14929
3894 if (($svy_type == ilObjSurvey::MODE_360 || $svy_type == ilObjSurvey::MODE_SELF_EVAL) &&
3895 $this->getSkillService()) {
3896 include_once "./Modules/Survey/classes/class.ilSurveySkill.php";
3897 $src_skills = new ilSurveySkill($this);
3898 $tgt_skills = new ilSurveySkill($newObj);
3899
3900 foreach ($mapping as $src_qst_id => $tgt_qst_id) {
3901 $qst_skill = $src_skills->getSkillForQuestion($src_qst_id);
3902 if ($qst_skill) {
3903 $tgt_skills->addQuestionSkillAssignment($tgt_qst_id, $qst_skill["base_skill_id"], $qst_skill["tref_id"]);
3904 }
3905 }
3906 }
3907
3908 // clone the questionblocks
3909 $questionblocks = array();
3910 $questionblock_questions = array();
3911 $result = $ilDB->queryF(
3912 "SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
3913 array('integer'),
3914 array($this->getSurveyId())
3915 );
3916 if ($result->numRows() > 0) {
3917 while ($row = $ilDB->fetchAssoc($result)) {
3918 array_push($questionblock_questions, $row);
3919 $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
3920 }
3921 }
3922 // create new questionblocks
3923 foreach ($questionblocks as $key => $value) {
3924 $questionblock = self::_getQuestionblock($key);
3925 $questionblock_id = self::_addQuestionblock($questionblock["title"], $questionblock["owner_fi"], $questionblock["show_questiontext"], $questionblock["show_blocktitle"]);
3926 $questionblocks[$key] = $questionblock_id;
3927 }
3928 // create new questionblock questions
3929 foreach ($questionblock_questions as $key => $value) {
3930 if ($questionblocks[$value["questionblock_fi"]] &&
3931 $question_pointer[$value["question_fi"]]) {
3932 $next_id = $ilDB->nextId('svy_qblk_qst');
3933 $affectedRows = $ilDB->manipulateF(
3934 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) " .
3935 "VALUES (%s, %s, %s, %s)",
3936 array('integer','integer','integer','integer'),
3937 array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
3938 );
3939 }
3940 }
3941
3942 // clone the constraints
3943 $constraints = self::_getConstraints($this->getSurveyId());
3944 $newConstraints = array();
3945 foreach ($constraints as $key => $constraint) {
3946 if ($question_pointer[$constraint["for_question"]] &&
3947 $question_pointer[$constraint["question"]]) {
3948 if (!array_key_exists($constraint['id'], $newConstraints)) {
3949 $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
3950 $newConstraints[$constraint['id']] = $constraint_id;
3951 }
3952 $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
3953 }
3954 }
3955
3956 // #16210 - clone LP settings
3957 include_once('./Services/Tracking/classes/class.ilLPObjSettings.php');
3958 $obj_settings = new ilLPObjSettings($this->getId());
3959 $obj_settings->cloneSettings($newObj->getId());
3960 unset($obj_settings);
3961
3962 return $newObj;
3963 }
3964
3965 public function getTextblock($question_id)
3966 {
3967 $ilDB = $this->db;
3968 $result = $ilDB->queryF(
3969 "SELECT * FROM svy_svy_qst WHERE question_fi = %s",
3970 array('integer'),
3971 array($question_id)
3972 );
3973 if ($result->numRows()) {
3974 $row = $ilDB->fetchAssoc($result);
3975 return $row["heading"];
3976 } else {
3977 return "";
3978 }
3979 }
3980
3986 public function cloneTextblocks($mapping)
3987 {
3988 foreach ($mapping as $original_id => $new_id) {
3989 $textblock = $this->getTextblock($original_id);
3990 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
3991 $this->saveHeading(ilUtil::stripSlashes($textblock, true, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
3992 }
3993 }
3994
4002 public function createExportDirectory()
4003 {
4004 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
4005 ilUtil::makeDir($svy_data_dir);
4006 if (!is_writable($svy_data_dir)) {
4007 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4008 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
4009 }
4010
4011 // create learning module directory (data_dir/lm_data/lm_<id>)
4012 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
4013 ilUtil::makeDir($svy_dir);
4014 if (!@is_dir($svy_dir)) {
4015 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4016 throw new ilSurveyException("Creation of Survey Directory failed.");
4017 }
4018 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
4019 $export_dir = $svy_dir . "/export";
4020 ilUtil::makeDir($export_dir);
4021 if (!@is_dir($export_dir)) {
4022 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4023 throw new ilSurveyException("Creation of Export Directory failed.");
4024 }
4025 }
4026
4030 public function getExportDirectory()
4031 {
4032 $export_dir = ilUtil::getDataDir() . "/svy_data" . "/svy_" . $this->getId() . "/export";
4033
4034 return $export_dir;
4035 }
4036
4044 public function createImportDirectory()
4045 {
4046 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
4047 ilUtil::makeDir($svy_data_dir);
4048
4049 if (!is_writable($svy_data_dir)) {
4050 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4051 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
4052 }
4053
4054 // create test directory (data_dir/svy_data/svy_<id>)
4055 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
4056 ilUtil::makeDir($svy_dir);
4057 if (!@is_dir($svy_dir)) {
4058 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4059 throw new ilSurveyException("Creation of Survey Directory failed.");
4060 }
4061
4062 // create import subdirectory (data_dir/svy_data/svy_<id>/import)
4063 $import_dir = $svy_dir . "/import";
4064 ilUtil::makeDir($import_dir);
4065 if (!@is_dir($import_dir)) {
4066 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4067 throw new ilSurveyException("Creation of Import Directory failed.");
4068 }
4069 }
4070
4074 public function getImportDirectory()
4075 {
4076 $import_dir = ilUtil::getDataDir() . "/svy_data" .
4077 "/svy_" . $this->getId() . "/import";
4078 if (!is_dir($import_dir)) {
4079 ilUtil::makeDirParents($import_dir);
4080 }
4081 if (@is_dir($import_dir)) {
4082 return $import_dir;
4083 } else {
4084 return false;
4085 }
4086 }
4087
4088 public function saveHeading($heading = "", $insertbefore)
4089 {
4090 $ilDB = $this->db;
4091 if ($heading) {
4092 $affectedRows = $ilDB->manipulateF(
4093 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4094 array('text','integer','integer'),
4095 array($heading, $this->getSurveyId(), $insertbefore)
4096 );
4097 } else {
4098 $affectedRows = $ilDB->manipulateF(
4099 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4100 array('text','integer','integer'),
4101 array(null, $this->getSurveyId(), $insertbefore)
4102 );
4103 }
4104 }
4105
4106 public function isAnonymousKey($key)
4107 {
4108 $ilDB = $this->db;
4109
4110 $result = $ilDB->queryF(
4111 "SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
4112 array('text','integer'),
4113 array($key, $this->getSurveyId())
4114 );
4115 return ($result->numRows() == 1) ? true : false;
4116 }
4117
4118 public function bindSurveyCodeToUser($user_id, $code)
4119 {
4120 $ilDB = $this->db;
4121
4122 if ($user_id == ANONYMOUS_USER_ID) {
4123 return;
4124 }
4125
4126 if ($this->checkSurveyCode($code)) {
4127 $ilDB->manipulate("UPDATE svy_anonymous" .
4128 " SET user_key = " . $ilDB->quote(md5($user_id), "text") .
4129 " WHERE survey_key = " . $ilDB->quote($code, "text"));
4130 }
4131 }
4132
4134 {
4135 $ilDB = $this->db;
4136
4137 $result = $ilDB->queryF(
4138 "SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
4139 array('text','integer'),
4140 array($key, $this->getSurveyId())
4141 );
4142 return ($result->numRows() == 1) ? true : false;
4143 }
4144
4145 public function checkSurveyCode($code)
4146 {
4147 if ($this->isAnonymousKey($code)) {
4148 if ($this->isSurveyStarted("", $code) == 1) {
4149 return false;
4150 } else {
4151 return true;
4152 }
4153 } else {
4154 return false;
4155 }
4156 }
4157
4165 public function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
4166 {
4167 $ilDB = $this->db;
4169 $lng = $this->lng;
4170
4171 include_once "./Services/Link/classes/class.ilLink.php";
4172
4173 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4174 " FROM svy_anonymous" .
4175 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4176 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
4177 " AND svy_anonymous.user_key IS NULL";
4178
4179 if ($a_codes) {
4180 $sql .= " AND " . $ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
4181 } elseif ($a_ids) {
4182 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
4183 }
4184
4185 $export = array();
4186
4187 // #14905
4188 $titles = array();
4189 $titles[] = '"' . $lng->txt("survey_code") . '"';
4190 $titles[] = '"' . $lng->txt("email") . '"';
4191 $titles[] = '"' . $lng->txt("lastname") . '"';
4192 $titles[] = '"' . $lng->txt("firstname") . '"';
4193 $titles[] = '"' . $lng->txt("create_date") . '"';
4194 $titles[] = '"' . $lng->txt("used") . '"';
4195 $titles[] = '"' . $lng->txt("mail_sent_short") . '"';
4196 $titles[] = '"' . $lng->txt("survey_code_url") . '"';
4197 $export[] = implode(";", $titles);
4198
4199 $result = $ilDB->query($sql);
4200 $default_lang = $ilUser->getPref("survey_code_language");
4201 while ($row = $ilDB->fetchAssoc($result)) {
4202 $item = array();
4203 $item[] = $row["survey_key"];
4204
4205 if ($row["externaldata"]) {
4206 $ext = unserialize($row["externaldata"]);
4207 $item[] = $ext["email"];
4208 $item[] = $ext["lastname"];
4209 $item[] = $ext["firstname"];
4210 } else {
4211 $item[] = "";
4212 $item[] = "";
4213 $item[] = "";
4214 }
4215
4216 // No relative (today, tomorrow...) dates in export.
4217 $date = new ilDateTime($row['tstamp'], IL_CAL_UNIX);
4218 $item[] = $date->get(IL_CAL_DATETIME);
4219
4220 $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4221 $item[] = ($row["sent"]) ? 1 : 0;
4222
4223 $params = array("accesscode" => $row["survey_key"]);
4224 if ($default_lang) {
4225 $params["lang"] = $default_lang;
4226 }
4227 $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4228
4229 $export[] = '"' . implode('";"', $item) . '"';
4230 }
4231 return implode("\n", $export);
4232 }
4233
4241 public function getSurveyCodesTableData(array $ids = null, $lang = null)
4242 {
4243 $ilDB = $this->db;
4244
4245 include_once "./Services/Link/classes/class.ilLink.php";
4246
4247 $codes = array();
4248
4249 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4250 " FROM svy_anonymous" .
4251 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4252 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") /*.
4253 " AND svy_anonymous.user_key IS NULL" */; // #15860
4254
4255 if ($ids) {
4256 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4257 }
4258
4259 $sql .= " ORDER BY tstamp, survey_key ASC";
4260 $result = $ilDB->query($sql);
4261 if ($result->numRows() > 0) {
4262 while ($row = $ilDB->fetchAssoc($result)) {
4263 $href = "";
4264 $used = false;
4265 if ($this->isSurveyCodeUsed($row["survey_key"])) {
4266 $used = true;
4267 } else {
4268 $params = array("accesscode" => $row["survey_key"]);
4269 if ($lang) {
4270 $params["lang"] = $lang;
4271 }
4272 $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4273 }
4274
4275
4276 $item = array(
4277 'id' => $row["anonymous_id"],
4278 'code' => $row["survey_key"],
4279 'date' => $row["tstamp"],
4280 'used' => $used,
4281 'sent' => $row['sent'],
4282 'href' => $href,
4283 'email' => '',
4284 'last_name' => '',
4285 'first_name' => ''
4286 );
4287
4288 if ($row["externaldata"]) {
4289 $ext = unserialize($row["externaldata"]);
4290 $item['email'] = $ext['email'];
4291 $item['last_name'] = $ext['lastname'];
4292 $item['first_name'] = $ext['firstname'];
4293 }
4294
4295 array_push($codes, $item);
4296 }
4297 }
4298 return $codes;
4299 }
4300
4301 public function isSurveyCodeUsed($code)
4302 {
4303 $ilDB = $this->db;
4304 $result = $ilDB->queryF(
4305 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4306 array('integer','text'),
4307 array($this->getSurveyId(), $code)
4308 );
4309 return ($result->numRows() > 0) ? true : false;
4310 }
4311
4312 public function isSurveyCodeUnique($code)
4313 {
4314 $ilDB = $this->db;
4315 $result = $ilDB->queryF(
4316 "SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4317 array('integer','text'),
4318 array($this->getSurveyId(), $code)
4319 );
4320 return ($result->numRows() > 0) ? false : true;
4321 }
4322
4323 public function createSurveyCodes($nrOfCodes)
4324 {
4325 $ilDB = $this->db;
4326
4327 $res = array();
4328
4329 for ($i = 0; $i < $nrOfCodes; $i++) {
4330 $next_id = $ilDB->nextId('svy_anonymous');
4331 $ilDB->manipulateF(
4332 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) " .
4333 "VALUES (%s, %s, %s, %s)",
4334 array('integer','text','integer','integer'),
4335 array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4336 );
4337 $res[] = $next_id;
4338 }
4339
4340 return $res;
4341 }
4342
4343 public function importSurveyCode($a_anonymize_key, $a_created, $a_data)
4344 {
4345 $ilDB = $this->db;
4346
4347 $next_id = $ilDB->nextId('svy_anonymous');
4348 $ilDB->manipulateF(
4349 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4350 "VALUES (%s, %s, %s, %s, %s)",
4351 array('integer','text','integer','text','integer'),
4352 array($next_id, $a_anonymize_key, $this->getSurveyId(), serialize($a_data), $a_created)
4353 );
4354 }
4355
4357 {
4358 $ilDB = $this->db;
4359
4360 $ids = array();
4361 foreach ($data as $dataset) {
4362 $anonymize_key = $this->createNewAccessCode();
4363 $next_id = $ilDB->nextId('svy_anonymous');
4364 $affectedRows = $ilDB->manipulateF(
4365 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4366 "VALUES (%s, %s, %s, %s, %s)",
4367 array('integer','text','integer','text','integer'),
4368 array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
4369 );
4370 $ids[] = $next_id;
4371 }
4372 return $ids;
4373 }
4374
4375 public function sendCodes($not_sent, $subject, $message, $lang)
4376 {
4377 global $DIC;
4378 /*
4379 * 0 = all
4380 * 1 = not sent
4381 * 2 = finished
4382 * 3 = not finished
4383 */
4384 $check_finished = ($not_sent > 1);
4385
4386 include_once "./Services/Mail/classes/class.ilMail.php";
4387 include_once "./Services/Link/classes/class.ilLink.php";
4388
4389 $mail = new ilMail(ANONYMOUS_USER_ID);
4390 $recipients = $this->getExternalCodeRecipients($check_finished);
4391 foreach ($recipients as $data) {
4392 if ($data['email'] && $data['code']) {
4393 $do_send = false;
4394 switch ((int) $not_sent) {
4395 case 1:
4396 $do_send = !(bool) $data['sent'];
4397 break;
4398
4399 case 2:
4400 $do_send = $data['finished'];
4401 break;
4402
4403 case 3:
4404 $do_send = !$data['finished'];
4405 break;
4406
4407 default:
4408 $do_send = true;
4409 break;
4410 }
4411 if ($do_send) {
4412 // build text
4413 $messagetext = $message;
4415 $this->getRefId(),
4416 "svy",
4417 array(
4418 "accesscode" => $data["code"],
4419 "lang" => $lang
4420 )
4421 );
4422 $messagetext = str_replace('[url]', $url, $messagetext);
4423 foreach ($data as $key => $value) {
4424 $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
4425 }
4426
4427 // send mail
4428 $mail->sendMail(
4429 $data['email'], // to
4430 "", // cc
4431 "", // bcc
4432 $subject, // subject
4433 $messagetext, // message
4434 array(), // attachments
4435 array('normal') // type
4436 );
4437 }
4438 }
4439 }
4440
4441 $ilDB = $this->db;
4442 $ilDB->manipulateF(
4443 "UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
4444 array('integer','integer'),
4445 array(1, $this->getSurveyId())
4446 );
4447 }
4448
4449 public function getExternalCodeRecipients($a_check_finished = false)
4450 {
4451 $ilDB = $this->db;
4452 $result = $ilDB->queryF(
4453 "SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
4454 array('integer'),
4455 array($this->getSurveyId())
4456 );
4457 $res = array();
4458 while ($row = $ilDB->fetchAssoc($result)) {
4459 if (!$row['externaldata']) {
4460 continue;
4461 }
4462
4463 $externaldata = unserialize($row['externaldata']);
4464 if (!$externaldata['email']) {
4465 continue;
4466 }
4467
4468 $externaldata['code'] = $row['code'];
4469 $externaldata['sent'] = $row['sent'];
4470
4471 if ($a_check_finished) {
4472 #23294
4473 //$externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
4474 $externaldata['finished'] = $this->isSurveyFinishedByCode($row['code']);
4475 }
4476
4477 array_push($res, $externaldata);
4478 }
4479 return $res;
4480 }
4481
4487 public function isSurveyFinishedByCode($a_code)
4488 {
4489 $result = $this->db->queryF(
4490 "SELECT state FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4491 array('integer','text'),
4492 array($this->getSurveyId(), $a_code)
4493 );
4494
4495 $row = $this->db->fetchAssoc($result);
4496
4497 return $row['state'];
4498 }
4499
4505 public function deleteSurveyCode($survey_code)
4506 {
4507 $ilDB = $this->db;
4508
4509 if (strlen($survey_code) > 0) {
4510 $affectedRows = $ilDB->manipulateF(
4511 "DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4512 array('integer', 'text'),
4513 array($this->getSurveyId(), $survey_code)
4514 );
4515 }
4516 }
4517
4524 public function getUserAccessCode($user_id)
4525 {
4526 $ilDB = $this->db;
4527 $access_code = "";
4528 $result = $ilDB->queryF(
4529 "SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
4530 array('integer','text'),
4531 array($this->getSurveyId(), md5($user_id))
4532 );
4533 if ($result->numRows()) {
4534 $row = $ilDB->fetchAssoc($result);
4535 $access_code = $row["survey_key"];
4536 }
4537 return $access_code;
4538 }
4539
4546 public function saveUserAccessCode($user_id, $access_code)
4547 {
4548 $ilDB = $this->db;
4549
4550 // not really sure what to do about ANONYMOUS_USER_ID
4551
4552 $next_id = $ilDB->nextId('svy_anonymous');
4553 $affectedRows = $ilDB->manipulateF(
4554 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) " .
4555 "VALUES (%s, %s, %s, %s, %s)",
4556 array('integer','text', 'integer', 'text', 'integer'),
4557 array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
4558 );
4559 }
4560
4566 public function createNewAccessCode()
4567 {
4568 // create a 5 character code
4569 $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4570 mt_srand();
4571 $code = "";
4572 for ($i = 1; $i <= 5; $i++) {
4573 $index = mt_rand(0, strlen($codestring) - 1);
4574 $code .= substr($codestring, $index, 1);
4575 }
4576 // verify it against the database
4577 while (!$this->isSurveyCodeUnique($code)) {
4578 $code = $this->createNewAccessCode();
4579 }
4580 return $code;
4581 }
4582
4583 public function getLastAccess($finished_id)
4584 {
4585 $ilDB = $this->db;
4586
4587 $result = $ilDB->queryF(
4588 "SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
4589 array('integer'),
4590 array($finished_id)
4591 );
4592 if ($result->numRows()) {
4593 $row = $ilDB->fetchAssoc($result);
4594 return $row["tstamp"];
4595 } else {
4596 $result = $ilDB->queryF(
4597 "SELECT tstamp FROM svy_finished WHERE finished_id = %s",
4598 array('integer'),
4599 array($finished_id)
4600 );
4601 if ($result->numRows()) {
4602 $row = $ilDB->fetchAssoc($result);
4603 return $row["tstamp"];
4604 }
4605 }
4606 return "";
4607 }
4608
4615 public function prepareTextareaOutput($txt_output)
4616 {
4617 return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
4618 }
4619
4627 public function isHTML($a_text)
4628 {
4629 if (preg_match("/<[^>]*?>/", $a_text)) {
4630 return true;
4631 } else {
4632 return false;
4633 }
4634 }
4635
4644 public function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = true, $add_mobs = true, $attribs = null)
4645 {
4646 include_once "./Services/RTE/classes/class.ilRTE.php";
4647 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
4648
4649 $a_xml_writer->xmlStartTag("material", $attribs);
4650 $attrs = array(
4651 "type" => "text/plain"
4652 );
4653 if ($this->isHTML($a_material)) {
4654 $attrs["type"] = "text/xhtml";
4655 }
4656 $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
4657 $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
4658
4659 if ($add_mobs) {
4660 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
4661 foreach ($mobs as $mob) {
4662 $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
4663 if (strpos($mattext, $mob_id) !== false) {
4664 $mob_obj = new ilObjMediaObject($mob);
4665 $imgattrs = array(
4666 "label" => $mob_id,
4667 "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
4668 "type" => "svy:html",
4669 "id" => $this->getId()
4670 );
4671 $a_xml_writer->xmlElement("matimage", $imgattrs, null);
4672 }
4673 }
4674 }
4675 if ($close_material_tag) {
4676 $a_xml_writer->xmlEndTag("material");
4677 }
4678 }
4679
4688 public function canExportSurveyCode()
4689 {
4690 if ($this->getAnonymize() != self::ANONYMIZE_OFF) {
4691 if ($this->surveyCodeSecurity == false) {
4692 return true;
4693 }
4694 }
4695 return false;
4696 }
4697
4705 public function processPrintoutput2FO($print_output)
4706 {
4707 if (extension_loaded("tidy")) {
4708 $config = array(
4709 "indent" => false,
4710 "output-xml" => true,
4711 "numeric-entities" => true
4712 );
4713 $tidy = new tidy();
4714 $tidy->parseString($print_output, $config, 'utf8');
4715 $tidy->cleanRepair();
4716 $print_output = tidy_get_output($tidy);
4717 $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
4718 } else {
4719 $print_output = str_replace("&nbsp;", "&#160;", $print_output);
4720 $print_output = str_replace("&otimes;", "X", $print_output);
4721
4722 // #17680 - metric questions use &#160; in print view
4723 $print_output = str_replace("&gt;", "~|gt|~", $print_output); // see #21550
4724 $print_output = str_replace("&lt;", "~|lt|~", $print_output);
4725 $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
4726 $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
4727 $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
4728 $print_output = str_replace("~|gt|~", "&gt;", $print_output);
4729 $print_output = str_replace("~|lt|~", "&lt;", $print_output);
4730 }
4731 $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
4732
4733 // additional font support
4734 $xsl = str_replace(
4735 'font-family="Helvetica, unifont"',
4736 'font-family="' . $GLOBALS['ilSetting']->get('rpc_pdf_font', 'Helvetica, unifont') . '"',
4737 $xsl
4738 );
4739 $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
4740 $xh = xslt_create();
4741 $params = array();
4742 try {
4743 $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
4744 } catch (Exception $e) {
4745 $this->log->error("Print XSLT failed:");
4746 $this->log->error("Content: " . $print_output);
4747 $this->log->error("Xsl: " . $xsl);
4748 throw ($e);
4749 }
4750 xslt_error($xh);
4751 xslt_free($xh);
4752
4753 return $output;
4754 }
4755
4762 public function deliverPDFfromFO($fo)
4763 {
4765
4766 $fo_file = ilUtil::ilTempnam() . ".fo";
4767 $fp = fopen($fo_file, "w");
4768 fwrite($fp, $fo);
4769 fclose($fp);
4770
4771 include_once './Services/WebServices/RPC/classes/class.ilRpcClientFactory.php';
4772 try {
4773 $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
4774 ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
4775 return true;
4776 } catch (Exception $e) {
4777 $ilLog->write(__METHOD__ . ': ' . $e->getMessage());
4778 return false;
4779 }
4780 }
4781
4788 public function isPluginActive($a_pname)
4789 {
4790 $ilPluginAdmin = $this->plugin_admin;
4791 if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname)) {
4792 return true;
4793 } else {
4794 return false;
4795 }
4796 }
4797
4803 public function setSurveyId($survey_id)
4804 {
4805 $this->survey_id = $survey_id;
4806 }
4807
4814 public function &getUserData($ids)
4815 {
4816 $ilDB = $this->db;
4817
4818 if (!is_array($ids) || count($ids) == 0) {
4819 return array();
4820 }
4821
4822 $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
4823 $result_array = array();
4824 while ($row = $ilDB->fetchAssoc($result)) {
4825 $result_array[$row["usr_id"]] = $row;
4826 }
4827 return $result_array;
4828 }
4829
4830 public function getMailNotification()
4831 {
4833 }
4834
4835 public function setMailNotification($a_notification)
4836 {
4837 $this->mailnotification = ($a_notification) ? true : false;
4838 }
4839
4840 public function getMailAddresses()
4841 {
4842 return $this->mailaddresses;
4843 }
4844
4845 public function setMailAddresses($a_addresses)
4846 {
4847 $this->mailaddresses = $a_addresses;
4848 }
4849
4850 public function getMailParticipantData()
4851 {
4853 }
4854
4855 public function setMailParticipantData($a_data)
4856 {
4857 $this->mailparticipantdata = $a_data;
4858 }
4859
4860 public function setStartTime($finished_id, $first_question)
4861 {
4862 $ilDB = $this->db;
4863 $time = time();
4864 //primary for table svy_times
4865 $id = $ilDB->nextId('svy_times');
4866 $_SESSION['svy_entered_page'] = $time;
4867 $affectedRows = $ilDB->manipulateF(
4868 "INSERT INTO svy_times (id, finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s,%s)",
4869 array('integer','integer', 'integer', 'integer', 'integer'),
4870 array($id, $finished_id, $time, null, $first_question)
4871 );
4872 }
4873
4874 public function setEndTime($finished_id)
4875 {
4876 $ilDB = $this->db;
4877 $time = time();
4878 $affectedRows = $ilDB->manipulateF(
4879 "UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
4880 array('integer', 'integer', 'integer'),
4881 array($time, $finished_id, $_SESSION['svy_entered_page'])
4882 );
4883 unset($_SESSION['svy_entered_page']);
4884 }
4885
4886 public function getWorkingtimeForParticipant($finished_id)
4887 {
4888 $ilDB = $this->db;
4889
4890 $result = $ilDB->queryF(
4891 "SELECT * FROM svy_times WHERE finished_fi = %s",
4892 array('integer'),
4893 array($finished_id)
4894 );
4895 $total = 0;
4896 while ($row = $ilDB->fetchAssoc($result)) {
4897 if ($row['left_page'] > 0 && $row['entered_page'] > 0) {
4898 $total += $row['left_page'] - $row['entered_page'];
4899 }
4900 }
4901 return $total;
4902 }
4903
4904 public function setTemplate($template_id)
4905 {
4906 $this->template_id = (int) $template_id;
4907 }
4908
4909 public function getTemplate()
4910 {
4911 return $this->template_id;
4912 }
4913
4914 public function updateOrder(array $a_order)
4915 {
4916 if (sizeof($this->questions) == sizeof($a_order)) {
4917 $this->questions = array_flip($a_order);
4918 $this->saveQuestionsToDB();
4919 }
4920 }
4921
4922 public function getPoolUsage()
4923 {
4924 return $this->pool_usage;
4925 }
4926
4927 public function setPoolUsage($a_value)
4928 {
4929 $this->pool_usage = (bool) $a_value;
4930 }
4931
4937 public function isPoolActive()
4938 {
4939 $use_pool = (bool) $this->getPoolUsage();
4940 $template_settings = $this->getTemplate();
4941 if ($template_settings) {
4942 include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
4943 $template_settings = new ilSettingsTemplate($template_settings);
4944 $template_settings = $template_settings->getSettings();
4945 $template_settings = $template_settings["use_pool"];
4946 if ($template_settings && $template_settings["hide"]) {
4947 $use_pool = (bool) $template_settings["value"];
4948 }
4949 }
4950 return $use_pool;
4951 }
4952
4959 {
4960 if (!$template_id) {
4961 return;
4962 }
4963
4964 include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
4966 $template_settings = $template->getSettings();
4967 //ilUtil::dumpVar($template_settings); exit;
4968 if ($template_settings) {
4969 if ($template_settings["show_question_titles"] !== null) {
4970 if ($template_settings["show_question_titles"]["value"]) {
4971 $this->setShowQuestionTitles(true);
4972 } else {
4973 $this->setShowQuestionTitles(false);
4974 }
4975 }
4976
4977 if ($template_settings["use_pool"] !== null) {
4978 if ($template_settings["use_pool"]["value"]) {
4979 $this->setPoolUsage(true);
4980 } else {
4981 $this->setPoolUsage(false);
4982 }
4983 }
4984
4985
4986 /* see #0021719
4987 if($template_settings["anonymization_options"]["value"])
4988 {
4989 $anon_map = array('personalized' => self::ANONYMIZE_OFF,
4990 'anonymize_with_code' => self::ANONYMIZE_ON,
4991 'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
4992 $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
4993 }*/
4994
4995 // see #0021719 and ilObjectSurveyGUI::savePropertiesObject
4996 $this->setEvaluationAccess($template_settings["evaluation_access"]["value"]);
4997 $codes = (bool) $template_settings["acc_codes"]["value"];
4998 $anon = (bool) $template_settings["anonymization_options"]["value"];
4999 if (!$anon) {
5000 if (!$codes) {
5002 } else {
5004 }
5005 } else {
5006 if ($codes) {
5008 } else {
5010 }
5011
5012 $this->setAnonymousUserList($_POST["anon_list"]);
5013 }
5014
5015
5016
5017 /* other settings: not needed here
5018 * - enabled_end_date
5019 * - enabled_start_date
5020 * - rte_switch
5021 */
5022 }
5023
5024 $this->setTemplate($template_id);
5025 $this->saveToDb();
5026 }
5027
5028 public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
5029 {
5030 $ilDB = $this->db;
5031
5032 $a_email = trim($a_email);
5033
5034 // :TODO:
5035 if (($a_email && !ilUtil::is_email($a_email)) || $a_email == "") {
5036 return false;
5037 }
5038
5039 $data = array("email" => $a_email,
5040 "lastname" => trim($a_last_name),
5041 "firstname" => trim($a_first_name));
5042
5043 $fields = array(
5044 "externaldata" => array("text", serialize($data)),
5045 "sent" => array("integer", $a_sent)
5046 );
5047
5048 $ilDB->update(
5049 "svy_anonymous",
5050 $fields,
5051 array("anonymous_id" => array("integer", $a_id))
5052 );
5053
5054 return true;
5055 }
5056
5057
5058 //
5059 // 360°
5060 //
5061
5062 public function get360Mode()
5063 {
5064 if ($this->getMode() == ilObjSurvey::MODE_360) {
5065 return true;
5066 }
5067 return false;
5068 }
5069
5070 public function set360SelfEvaluation($a_value)
5071 {
5072 $this->mode_360_self_eval = (bool) $a_value;
5073 }
5074
5075 public function get360SelfEvaluation()
5076 {
5077 return (bool) $this->mode_360_self_eval;
5078 }
5079
5080 public function set360SelfAppraisee($a_value)
5081 {
5082 $this->mode_360_self_appr = (bool) $a_value;
5083 }
5084
5085 public function get360SelfAppraisee()
5086 {
5087 return (bool) $this->mode_360_self_appr;
5088 }
5089
5090 public function set360SelfRaters($a_value)
5091 {
5092 $this->mode_360_self_rate = (bool) $a_value;
5093 }
5094
5095 public function get360SelfRaters()
5096 {
5097 return (bool) $this->mode_360_self_rate;
5098 }
5099
5100 public function set360Results($a_value)
5101 {
5102 $this->mode_360_results = (int) $a_value;
5103 }
5104
5105 public function get360Results()
5106 {
5107 return (int) $this->mode_360_results;
5108 }
5109
5110 public function addAppraisee($a_user_id)
5111 {
5112 global $DIC;
5113
5114 $ilDB = $DIC->database();
5115 $access = $DIC->access();
5116
5117 if (!$this->isAppraisee($a_user_id) &&
5118 $a_user_id != ANONYMOUS_USER_ID) {
5119 $fields = array(
5120 "obj_id" => array("integer", $this->getSurveyId()),
5121 "user_id" => array("integer", $a_user_id)
5122 );
5123 $ilDB->insert("svy_360_appr", $fields);
5124
5125 // send notification and add to desktop
5126 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
5127 $this->sendAppraiseeNotification($a_user_id);
5128 $type = ilObject::_lookupType($this->getRefId(), true);
5129 ilObjUser::_addDesktopItem($a_user_id, $this->getRefId(), $type);
5130 }
5131 }
5132 }
5133
5139 public function sendAppraiseeNotification($a_user_id)
5140 {
5141 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5142 $ntf = new ilSystemNotification();
5143 $ntf->setLangModules(array("svy", "survey"));
5144 $ntf->setRefId($this->getRefId());
5145 $ntf->setGotoLangId('url');
5146
5147 // user specific language
5148 $lng = $ntf->getUserLanguage($a_user_id);
5149
5150 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_mail");
5151 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
5152
5153 // #10044
5154 $mail = new ilMail(ANONYMOUS_USER_ID);
5155 //$mail->enableSOAP(false); // #10410
5156 $mail->sendMail(
5157 ilObjUser::_lookupLogin($a_user_id),
5158 null,
5159 null,
5160 $subject,
5161 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5162 null,
5163 array("system")
5164 );
5165 }
5166
5172 public function sendAppraiseeCloseNotification($a_user_id)
5173 {
5174 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5175 $ntf = new ilSystemNotification();
5176 $ntf->setLangModules(array("svy", "survey"));
5177 $ntf->setRefId($this->getRefId());
5178 $ntf->setGotoLangId('url');
5179
5180 // user specific language
5181 $lng = $ntf->getUserLanguage($a_user_id);
5182
5183 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_close_mail");
5184 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
5185
5186 // #10044
5187 $mail = new ilMail(ANONYMOUS_USER_ID);
5188 //$mail->enableSOAP(false); // #10410
5189 $mail->sendMail(
5190 ilObjUser::_lookupLogin($a_user_id),
5191 null,
5192 null,
5193 $subject,
5194 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5195 null,
5196 array("system")
5197 );
5198 }
5199
5205 public function sendRaterNotification($a_user_id, $a_appraisee_id)
5206 {
5207 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5208 $ntf = new ilSystemNotification();
5209 $ntf->setLangModules(array("svy", "survey"));
5210 $ntf->setRefId($this->getRefId());
5211 $ntf->setGotoLangId('url');
5212
5213 // user specific language
5214 $lng = $ntf->getUserLanguage($a_user_id);
5215
5216 $ntf->setIntroductionLangId("svy_user_added_360_rater_mail");
5217 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5218 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($a_appraisee_id, false, false, "", true));
5219
5220 // #10044
5221 $mail = new ilMail(ANONYMOUS_USER_ID);
5222 //$mail->enableSOAP(false); // #10410
5223 $mail->sendMail(
5224 ilObjUser::_lookupLogin($a_user_id),
5225 null,
5226 null,
5227 $subject,
5228 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5229 null,
5230 array("system")
5231 );
5232 }
5233
5234 public function isAppraisee($a_user_id)
5235 {
5236 $ilDB = $this->db;
5237
5238 $set = $ilDB->query("SELECT user_id" .
5239 " FROM svy_360_appr" .
5240 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5241 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5242 return (bool) $ilDB->numRows($set);
5243 }
5244
5245 public function isAppraiseeClosed($a_user_id)
5246 {
5247 $ilDB = $this->db;
5248
5249 $set = $ilDB->query("SELECT has_closed" .
5250 " FROM svy_360_appr" .
5251 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5252 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5253 $row = $ilDB->fetchAssoc($set);
5254 return $row["has_closed"];
5255 }
5256
5257 public function deleteAppraisee($a_user_id)
5258 {
5259 $ilDB = $this->db;
5260
5261 $ilDB->manipulate("DELETE FROM svy_360_appr" .
5262 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5263 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5264
5265 $set = $ilDB->query("SELECT user_id" .
5266 " FROM svy_360_rater" .
5267 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5268 " AND appr_id = " . $ilDB->quote($a_user_id, "integer"));
5269 while ($row = $ilDB->fetchAssoc($set)) {
5270 $this->deleteRater($a_user_id, $row["user_id"]);
5271 }
5272 // appraisee will not be part of raters table
5273 if ($this->get360SelfEvaluation()) {
5274 $this->deleteRater($a_user_id, $a_user_id);
5275 }
5276 }
5277
5278 public function getAppraiseesData()
5279 {
5280 $ilDB = $this->db;
5281
5282 $res = array();
5283
5284 $set = $ilDB->query("SELECT * FROM svy_360_appr" .
5285 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5286 while ($row = $ilDB->fetchAssoc($set)) {
5287 $name = ilObjUser::_lookupName($row["user_id"]);
5288 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5289 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5290 $res[$row["user_id"]] = $name;
5291
5292 $finished = 0;
5293 $raters = $this->getRatersData($row["user_id"]);
5294 foreach ($raters as $rater) {
5295 if ($rater["finished"]) {
5296 $finished++;
5297 }
5298 }
5299 $res[$row["user_id"]]["finished"] = $finished . "/" . sizeof($raters);
5300 $res[$row["user_id"]]["closed"] = $row["has_closed"];
5301 }
5302
5303 return $res;
5304 }
5305
5306 public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5307 {
5308 global $DIC;
5309
5310 $ilDB = $DIC->database();
5311 $access = $DIC->access();
5312
5313 if ($this->isAppraisee($a_appraisee_id) &&
5314 !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id)) {
5315 $fields = array(
5316 "obj_id" => array("integer", $this->getSurveyId()),
5317 "appr_id" => array("integer", $a_appraisee_id),
5318 "user_id" => array("integer", $a_user_id),
5319 "anonymous_id" => array("integer", $a_anonymous_id)
5320 );
5321 $ilDB->insert("svy_360_rater", $fields);
5322
5323 // send notification and add to desktop
5324 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
5325 $this->sendRaterNotification($a_user_id, $a_appraisee_id);
5326 $type = ilObject::_lookupType($this->getRefId(), true);
5327 ilObjUser::_addDesktopItem($a_user_id, $this->getRefId(), $type);
5328 }
5329 }
5330 }
5331
5332 public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5333 {
5334 $ilDB = $this->db;
5335
5336 // user is rater if already appraisee and active self-evaluation
5337 if ($this->isAppraisee($a_user_id) &&
5338 $this->get360SelfEvaluation() &&
5339 (!$a_appraisee_id || $a_appraisee_id == $a_user_id)) {
5340 return true;
5341 }
5342
5343 // :TODO: should we get rid of code as well?
5344
5345 $sql = "SELECT user_id" .
5346 " FROM svy_360_rater" .
5347 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5348 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5349 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5350 if ($a_appraisee_id) {
5351 $sql .= " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer");
5352 }
5353 $set = $ilDB->query($sql);
5354 return (bool) $ilDB->numRows($set);
5355 }
5356
5357 public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5358 {
5359 $ilDB = $this->db;
5360
5361 $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5362 if ($finished_id) {
5363 $this->removeSelectedSurveyResults(array($finished_id));
5364 }
5365
5366 $ilDB->manipulate("DELETE FROM svy_360_rater" .
5367 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5368 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5369 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5370 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5371 }
5372
5373 public function getRatersData($a_appraisee_id)
5374 {
5375 $ilDB = $this->db;
5376
5377 $res = $anonymous_ids = array();
5378
5379 $set = $ilDB->query("SELECT * FROM svy_360_rater" .
5380 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5381 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer"));
5382 while ($row = $ilDB->fetchAssoc($set)) {
5383 if ($row["anonymous_id"]) {
5384 $res["a" . $row["anonymous_id"]] = array(
5385 "lastname" => "unknown code " . $row["anonymous_id"],
5386 "sent" => $row["mail_sent"],
5387 "finished" => null
5388 );
5389 $anonymous_ids[] = $row["anonymous_id"];
5390 } else {
5391 $name = ilObjUser::_lookupName($row["user_id"]);
5392 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5393 $name["user_id"] = "u" . $name["user_id"];
5394 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5395 $name["sent"] = $row["mail_sent"];
5396 $name["finished"] = (bool) $this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
5397 $res["u" . $row["user_id"]] = $name;
5398 }
5399 }
5400
5401 if (sizeof($anonymous_ids)) {
5402 $data = $this->getSurveyCodesTableData($anonymous_ids);
5403 foreach ($data as $item) {
5404 if (isset($res["a" . $item["id"]])) {
5405 $res["a" . $item["id"]] = array(
5406 "user_id" => "a" . $item["id"],
5407 "lastname" => $item["last_name"],
5408 "firstname" => $item["first_name"],
5409 "name" => $item["last_name"] . ", " . $item["first_name"],
5410 "login" => "",
5411 "email" => $item["email"],
5412 "code" => $item["code"],
5413 "href" => $item["href"],
5414 "sent" => $res["a" . $item["id"]]["sent"],
5415 "finished" => (bool) $this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
5416 );
5417 }
5418 }
5419 }
5420
5421 return $res;
5422 }
5423
5424 public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
5425 {
5426 $ilDB = $this->db;
5427
5428 $res = array();
5429
5430 $sql = "SELECT appr_id FROM svy_360_rater" .
5431 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer");
5432
5433 if ($a_user_id) {
5434 $sql .= " AND user_id = " . $ilDB->quote($a_user_id, "integer");
5435 } else {
5436 $sql .= " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5437 }
5438
5439 $set = $ilDB->query($sql);
5440 while ($row = $ilDB->fetchAssoc($set)) {
5441 $res[] = $row["appr_id"];
5442 }
5443
5444 // user may evaluate himself if already appraisee
5445 if ($this->get360SelfEvaluation() &&
5446 $this->isAppraisee($a_user_id) &&
5447 !in_array($a_user_id, $res)) {
5448 $res[] = $a_user_id;
5449 }
5450
5451 return $res;
5452 }
5453
5454 public function getAnonymousIdByCode($a_code)
5455 {
5456 $ilDB = $this->db;
5457
5458 $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous" .
5459 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5460 " AND survey_key = " . $ilDB->quote($a_code, "text"));
5461 $res = $ilDB->fetchAssoc($set);
5462 return $res["anonymous_id"];
5463 }
5464
5465 public function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
5466 {
5467 $ilDB = $this->db;
5468
5469 $sql = "SELECT * FROM svy_finished" .
5470 " WHERE survey_fi =" . $ilDB->quote($this->getSurveyId(), "integer") .
5471 " AND appr_id = " . $ilDB->quote($appr_id, "integer");
5472 if ($user_id) {
5473 $sql .= " AND user_fi = " . $ilDB->quote($user_id, "integer");
5474 } else {
5475 $sql .= " AND anonymous_id = " . $ilDB->quote($anonymous_code, "text");
5476 }
5477 $result = $ilDB->query($sql);
5478 if ($result->numRows() == 0) {
5479 return false;
5480 } else {
5481 $row = $ilDB->fetchAssoc($result);
5482 return (int) $row["state"];
5483 }
5484 }
5485
5486 public function getUserSurveyExecutionStatus($a_code = null)
5487 {
5489 $ilDB = $this->db;
5490
5491 $user_id = $ilUser->getId();
5492
5493 // code is obligatory?
5494 if (!$this->isAccessibleWithoutCode()) {
5495 if (!$a_code) {
5496 // registered raters do not need code
5497 if ($this->get360Mode() &&
5498 $user_id != ANONYMOUS_USER_ID &&
5499 $this->isRater(0, $user_id)) {
5500 // auto-generate code
5501 $a_code = $this->createNewAccessCode();
5502 $this->saveUserAccessCode($user_id, $a_code);
5503 } else {
5504 return null;
5505 }
5506 }
5507 } elseif ($user_id == ANONYMOUS_USER_ID ||
5508 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS) {
5509 if (!$a_code) {
5510 // auto-generate code
5511 $a_code = $this->createNewAccessCode();
5512 $this->saveUserAccessCode($user_id, $a_code);
5513 }
5514 } else {
5515 $a_code = null;
5516 }
5517
5518 $res = array();
5519
5520 $sql = "SELECT * FROM svy_finished" .
5521 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
5522 // if proper user id is given, use it or current code
5523 if ($user_id != ANONYMOUS_USER_ID) {
5524 $sql .= " AND (user_fi = " . $ilDB->quote($user_id, "integer") .
5525 " OR anonymous_id = " . $ilDB->quote($a_code, "text") . ")";
5526 }
5527 // use anonymous code to find finished id(s)
5528 else {
5529 $sql .= " AND anonymous_id = " . $ilDB->quote($a_code, "text");
5530 }
5531 $set = $ilDB->query($sql);
5532 while ($row = $ilDB->fetchAssoc($set)) {
5533 $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
5534 "user_id" => $row["user_fi"],
5535 "code" => $row["anonymous_id"],
5536 "finished" => (bool) $row["state"]);
5537 }
5538
5539 return array("code" => $a_code, "runs" => $res);
5540 }
5541
5542 public function findCodeForUser($a_user_id)
5543 {
5544 $ilDB = $this->db;
5545
5546 if ($a_user_id != ANONYMOUS_USER_ID) {
5547 $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf" .
5548 " WHERE sf.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5549 " AND sf.user_fi = " . $ilDB->quote($a_user_id, "integer"));
5550 $a_code = $ilDB->fetchAssoc($set);
5551 return $a_code["anonymous_id"];
5552 }
5553 }
5554
5555 public function isUnusedCode($a_code, $a_user_id)
5556 {
5557 $ilDB = $this->db;
5558
5559 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
5560 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5561 " AND anonymous_id = " . $ilDB->quote($a_code, "text"));
5562 $user_id = $ilDB->fetchAssoc($set);
5563 $user_id = $user_id["user_fi"];
5564
5565 if ($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID)) {
5566 return false;
5567 }
5568 return true;
5569 }
5570
5571 public function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
5572 {
5573 $ilDB = $this->db;
5574
5575 $res = array();
5576
5577 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5578 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5579 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer"));
5580 while ($row = $ilDB->fetchAssoc($set)) {
5581 if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id) {
5582 continue;
5583 }
5584 $res[] = $row["finished_id"];
5585 }
5586
5587 return $res;
5588 }
5589
5597 public function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
5598 {
5599 $ilDB = $this->db;
5600
5601 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5602 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5603 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer") .
5604 " AND user_fi = " . $ilDB->quote($a_rat_id, "integer"));
5605 $row = $ilDB->fetchAssoc($set);
5606 return $row["finished_id"];
5607 }
5608
5609
5610 // 360° using competence/skill service
5611
5617 public function setSkillService($a_val)
5618 {
5619 $this->mode_skill_service = $a_val;
5620 }
5621
5627 public function getSkillService()
5628 {
5630 }
5631
5632 public function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
5633 {
5634 $ilDB = $this->db;
5635
5636 if (!$a_tstamp) {
5637 $a_tstamp = time();
5638 }
5639
5640 $ilDB->manipulate("UPDATE svy_360_rater" .
5641 " SET mail_sent = " . $ilDB->quote($a_tstamp, "integer") .
5642 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5643 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5644 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5645 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5646 }
5647
5648 public function closeAppraisee($a_user_id)
5649 {
5650 global $DIC;
5651
5652 $ilDB = $DIC->database();
5653 $user = $DIC->user();
5654
5655 // close the appraisee
5656 $ilDB->manipulate("UPDATE svy_360_appr" .
5657 " SET has_closed = " . $ilDB->quote(time(), "integer") .
5658 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5659 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5660
5661 // write competences
5662 include_once("./Services/Skill/classes/class.ilSkillManagementSettings.php");
5663 $skmg_set = new ilSkillManagementSettings();
5664 if ($this->getSkillService() && $skmg_set->isActivated()) {
5665 include_once("./Modules/Survey/classes/class.ilSurveySkill.php");
5666 $sskill = new ilSurveySkill($this);
5667 $sskill->writeAppraiseeSkills($a_user_id);
5668 }
5669
5670 // send notification
5671 if ($user->getId() != $a_user_id) {
5672 $this->sendAppraiseeCloseNotification($a_user_id);
5673 }
5674 }
5675
5676 public function openAllAppraisees()
5677 {
5678 $ilDB = $this->db;
5679
5680 $ilDB->manipulate("UPDATE svy_360_appr" .
5681 " SET has_closed = " . $ilDB->quote(null, "integer") .
5682 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5683 }
5684
5685 public static function validateExternalRaterCode($a_ref_id, $a_code)
5686 {
5687 if (!isset($_SESSION["360_extrtr"][$a_ref_id])) {
5688 $svy = new self($a_ref_id);
5689 $svy->loadFromDB();
5690
5691 if ($svy->canStartSurvey(null, true) &&
5692 $svy->get360Mode() &&
5693 $svy->isAnonymousKey($a_code)) {
5694 $anonymous_id = $svy->getAnonymousIdByCode($a_code);
5695 if ($anonymous_id) {
5696 if (sizeof($svy->getAppraiseesToRate(null, $anonymous_id))) {
5697 $_SESSION["360_extrtr"][$a_ref_id] = true;
5698 return true;
5699 }
5700 }
5701 }
5702
5703 $_SESSION["360_extrtr"][$a_ref_id] = false;
5704 return false;
5705 }
5706
5707 return $_SESSION["360_extrtr"][$a_ref_id];
5708 }
5709
5710
5711 //
5712 // reminder/notification
5713 //
5714
5715 public function getReminderStatus()
5716 {
5717 return (bool) $this->reminder_status;
5718 }
5719
5720 public function setReminderStatus($a_value)
5721 {
5722 $this->reminder_status = (bool) $a_value;
5723 }
5724
5725 public function getReminderStart()
5726 {
5727 return $this->reminder_start;
5728 }
5729
5730 public function setReminderStart(ilDate $a_value = null)
5731 {
5732 $this->reminder_start = $a_value;
5733 }
5734
5735 public function getReminderEnd()
5736 {
5737 return $this->reminder_end;
5738 }
5739
5740 public function setReminderEnd(ilDate $a_value = null)
5741 {
5742 $this->reminder_end = $a_value;
5743 }
5744
5745 public function getReminderFrequency()
5746 {
5748 }
5749
5750 public function setReminderFrequency($a_value)
5751 {
5752 $this->reminder_frequency = (int) $a_value;
5753 }
5754
5755 public function getReminderTarget()
5756 {
5758 }
5759
5760 public function setReminderTarget($a_value)
5761 {
5762 $this->reminder_target = (int) $a_value;
5763 }
5764
5765 public function getReminderLastSent()
5766 {
5768 }
5769
5770 public function setReminderLastSent($a_value)
5771 {
5772 $this->reminder_last_sent = $a_value;
5773 }
5774
5779 public function getReminderTemplate($selectDefault = false)
5780 {
5781 if ($selectDefault) {
5782 $defaultTemplateId = 0;
5783 $this->getReminderMailTemplates($defaultTemplateId);
5784
5785 if ($defaultTemplateId > 0) {
5786 return $defaultTemplateId;
5787 }
5788 }
5789
5790 return $this->reminder_tmpl;
5791 }
5792
5793 public function setReminderTemplate($a_value)
5794 {
5795 $this->reminder_tmpl = $a_value;
5796 }
5797
5799 {
5800 return (bool) $this->tutor_ntf_status;
5801 }
5802
5803 public function setTutorNotificationStatus($a_value)
5804 {
5805 $this->tutor_ntf_status = (bool) $a_value;
5806 }
5807
5809 {
5811 }
5812
5813 public function setTutorNotificationRecipients(array $a_value)
5814 {
5815 $this->tutor_ntf_recipients = $a_value;
5816 }
5817
5819 {
5821 }
5822
5823 public function setTutorNotificationTarget($a_value)
5824 {
5825 $this->tutor_ntf_target = (int) $a_value;
5826 }
5827
5828 protected function checkTutorNotification()
5829 {
5830 $ilDB = $this->db;
5831
5832 if ($this->getTutorNotificationStatus()) {
5833 $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
5834 if ($user_ids) {
5835 $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished" .
5836 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5837 " AND state = " . $ilDB->quote(1, "integer") .
5838 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
5839 $row = $ilDB->fetchAssoc($set);
5840 if ($row["numall"] == sizeof($user_ids)) {
5841 $this->sendTutorNotification();
5842 }
5843 }
5844 }
5845 }
5846
5853 public function sent360Reminders()
5854 {
5855 global $DIC;
5856
5857 $access = $DIC->access();
5858
5859 // collect all open ratings
5860 $rater_ids = array();
5861 foreach ($this->getAppraiseesData() as $app) {
5862 $this->log->debug("Handle appraisee " . $app['user_id']);
5863
5864 if (!$this->isAppraiseeClosed($app['user_id'])) {
5865 $this->log->debug("Check self evaluation, self: " . $this->get360SelfAppraisee() . ", target: " . $this->getReminderTarget());
5866
5867 // self evaluation?
5868 if ($this->get360SelfEvaluation() &&
5870 $this->log->debug("...1");
5871 // did user already finished self evaluation?
5872 if (!$this->is360SurveyStarted($app['user_id'], $app['user_id'])) {
5873 $this->log->debug("...2");
5874 if (!is_array($rater_ids[$app['user_id']])) {
5875 $rater_ids[$app['user_id']] = array();
5876 }
5877 if (!in_array($app["user_id"], $rater_ids[$app['user_id']])) {
5878 $rater_ids[$app['user_id']][] = $app["user_id"];
5879 }
5880 }
5881 }
5882
5883 $this->log->debug("Check raters.");
5884
5885 // should raters be notified?
5887 foreach ($this->getRatersData($app['user_id']) as $rater) {
5888 // is rater not anonymous and did not rate yet?
5889 if (!$rater["anonymous_id"] && !$rater["finished"]) {
5890 if (!is_array($rater_ids[$rater["user_id"]])) {
5891 $rater_ids[$rater["user_id"]] = array();
5892 }
5893 if (!in_array($app["user_id"], $rater_ids[$rater["user_id"]])) {
5894 $rater_ids[$rater["user_id"]][] = $app["user_id"];
5895 }
5896 }
5897 }
5898 }
5899 }
5900 }
5901
5902 $this->log->debug("Found raters:" . count($rater_ids));
5903
5904 foreach ($rater_ids as $id => $app) {
5905 if ($access->checkAccessOfUser($id, "read", "", $this->getRefId())) {
5906 $this->send360ReminderToUser($id, $app);
5907 }
5908 }
5909 }
5910
5916 public function send360ReminderToUser($a_user_id, $a_appraisee_ids)
5917 {
5918 $this->log->debug("Send mail to:" . $a_user_id);
5919
5920 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
5921 $ntf = new ilSystemNotification();
5922 $ntf->setLangModules(array("svy", "survey"));
5923 $ntf->setRefId($this->getRefId());
5924 $ntf->setGotoLangId('url');
5925
5926 // user specific language
5927 $lng = $ntf->getUserLanguage($a_user_id);
5928
5929 $ntf->setIntroductionLangId("svy_user_added_360_rater_reminder_mail");
5930 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5931
5932 foreach ($a_appraisee_ids as $appraisee_id) {
5933 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($appraisee_id, false, false, "", true));
5934 }
5935
5936 // #10044
5937 $mail = new ilMail(ANONYMOUS_USER_ID);
5938 $mail->enableSOAP(false); // #10410
5939 $mail->sendMail(
5940 ilObjUser::_lookupLogin($a_user_id),
5941 null,
5942 null,
5943 $subject,
5944 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5945 null,
5946 array("system")
5947 );
5948 }
5949
5950
5951 public function getNotificationTargetUserIds($a_use_invited)
5952 {
5954
5955 if ((bool) $a_use_invited) {
5956 $user_ids = $this->getInvitedUsers();
5957 } else {
5958 $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
5959 if ($parent_grp_ref_id) {
5960 include_once "Modules/Group/classes/class.ilGroupParticipants.php";
5961 $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
5962 $user_ids = $part->getMembers();
5963 } else {
5964 $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
5965 if ($parent_crs_ref_id) {
5966 include_once "Modules/Course/classes/class.ilCourseParticipants.php";
5967 $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
5968 $user_ids = $part->getMembers();
5969 }
5970 }
5971 }
5972 return $user_ids;
5973 }
5974
5975 protected function sendTutorNotification()
5976 {
5977 include_once "./Services/Mail/classes/class.ilMail.php";
5978 include_once "./Services/User/classes/class.ilObjUser.php";
5979 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
5980 include_once "./Services/User/classes/class.ilUserUtil.php";
5981 include_once "./Services/Link/classes/class.ilLink.php";
5982 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
5983
5984 foreach ($this->getTutorNotificationRecipients() as $user_id) {
5985 // use language of recipient to compose message
5986 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
5987 $ulng->loadLanguageModule('survey');
5988
5989 $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
5990 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
5991
5992 $message .= $ulng->txt('survey_notification_tutor_body') . ":\n\n";
5993 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
5994 $message .= "\n" . $ulng->txt('survey_notification_tutor_link') . ": " . $link;
5995
5996 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
5997 $mail_obj->appendInstallationSignature(true);
5998 $mail_obj->sendMail(
5999 ilObjUser::_lookupLogin($user_id),
6000 "",
6001 "",
6002 $subject,
6003 $message,
6004 array(),
6005 array("system")
6006 );
6007 }
6008 }
6009
6010 public function checkReminder()
6011 {
6012 $ilDB = $this->db;
6013 $ilAccess = $this->access;
6014
6015 $now = time();
6016 $now_with_format = date("YmdHis", $now);
6017 $today = date("Y-m-d");
6018
6019 $this->log->debug("Check status and dates.");
6020
6021 // object settings / participation period
6022 if (
6023 $this->getOfflineStatus() ||
6024 !$this->getReminderStatus() ||
6025 ($this->getStartDate() && $now_with_format < $this->getStartDate()) ||
6026 ($this->getEndDate() && $now_with_format > $this->getEndDate())) {
6027 return false;
6028 }
6029
6030 // reminder period
6031 $start = $this->getReminderStart();
6032 if ($start) {
6033 $start = $start->get(IL_CAL_DATE);
6034 }
6035 $end = $this->getReminderEnd();
6036 if ($end) {
6037 $end = $end->get(IL_CAL_DATE);
6038 }
6039 if ($today < $start ||
6040 ($end && $today > $end)) {
6041 return false;
6042 }
6043
6044 $this->log->debug("Check access period.");
6045
6046 // object access period
6047 include_once "Services/Object/classes/class.ilObjectActivation.php";
6048 $item_data = ilObjectActivation::getItem($this->getRefId());
6049 if ($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
6050 ($now < $item_data["timing_start"] ||
6051 $now > $item_data["timing_end"])) {
6052 return false;
6053 }
6054
6055 $this->log->debug("Check frequency.");
6056
6057 // check frequency
6058 $cut = new ilDate($today, IL_CAL_DATE);
6059 $cut->increment(IL_CAL_DAY, $this->getReminderFrequency() * -1);
6060 if (!$this->getReminderLastSent() ||
6061 $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10)) {
6062 $missing_ids = array();
6063
6064 if (!$this->get360Mode()) {
6065 $this->log->debug("Entering survey mode.");
6066
6067 // #16871
6068 $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
6069 if ($user_ids) {
6070 // gather participants who already finished
6071 $finished_ids = array();
6072 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
6073 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
6074 " AND state = " . $ilDB->quote(1, "text") .
6075 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
6076 while ($row = $ilDB->fetchAssoc($set)) {
6077 $finished_ids[] = $row["user_fi"];
6078 }
6079
6080 // some users missing out?
6081 $missing_ids = array_diff($user_ids, $finished_ids);
6082 if ($missing_ids) {
6083 foreach ($missing_ids as $idx => $user_id) {
6084 // should be able to participate
6085 if (!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId())) {
6086 unset($missing_ids[$idx]);
6087 }
6088 }
6089 }
6090 if ($missing_ids) {
6091 $this->sentReminder($missing_ids);
6092 }
6093 }
6094 } else {
6095 $this->log->debug("Entering 360 mode.");
6096
6097 $this->sent360Reminders();
6098 }
6099
6100
6101 $this->setReminderLastSent($today);
6102 $this->saveToDb();
6103
6104 return sizeof($missing_ids);
6105 }
6106
6107 return false;
6108 }
6109
6110 protected function sentReminder(array $a_recipient_ids)
6111 {
6112 global $DIC;
6113
6114 // use mail template
6115 if ($this->getReminderTemplate() &&
6116 array_key_exists($this->getReminderTemplate(), $this->getReminderMailTemplates())) {
6118 $templateService = $DIC['mail.texttemplates.service'];
6119 $tmpl = $templateService->loadTemplateForId((int) $this->getReminderTemplate());
6120
6121 $tmpl_params = array(
6122 "ref_id" => $this->getRefId(),
6123 "ts" => time()
6124 );
6125 } else {
6126 $tmpl = null;
6127
6128 include_once "./Services/Link/classes/class.ilLink.php";
6129 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6130
6131 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6132 }
6133
6134 foreach ($a_recipient_ids as $user_id) {
6135 if ($tmpl) {
6136 $subject = $tmpl->getSubject();
6137 $message = $this->sentReminderPlaceholders($tmpl->getMessage(), $user_id, $tmpl_params);
6138 }
6139 // use lng
6140 else {
6141 // use language of recipient to compose message
6142 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6143 $ulng->loadLanguageModule('survey');
6144
6145 $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
6146 $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
6147
6148 $message .= $ulng->txt('survey_reminder_body') . ":\n\n";
6149 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
6150 $message .= "\n" . $ulng->txt('survey_reminder_link') . ": " . $link;
6151 }
6152
6153 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6154 $mail_obj->appendInstallationSignature(true);
6155 $mail_obj->sendMail(
6156 ilObjUser::_lookupLogin($user_id),
6157 "",
6158 "",
6159 $subject,
6160 $message,
6161 array(),
6162 array("system")
6163 );
6164 }
6165 }
6166
6167 public function setActivationStartDate($starting_time = null)
6168 {
6169 $this->activation_starting_time = $starting_time;
6170 }
6171
6172 public function setActivationEndDate($ending_time = null)
6173 {
6174 $this->activation_ending_time = $ending_time;
6175 }
6176
6177 public function getActivationStartDate()
6178 {
6179 return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : null;
6180 }
6181
6182 public function getActivationEndDate()
6183 {
6184 return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : null;
6185 }
6186
6187 public function setViewOwnResults($a_value)
6188 {
6189 $this->view_own_results = (bool) $a_value;
6190 }
6191
6192 public function hasViewOwnResults()
6193 {
6195 }
6196
6197 public function setMailOwnResults($a_value)
6198 {
6199 $this->mail_own_results = (bool) $a_value;
6200 }
6201
6202 public function hasMailOwnResults()
6203 {
6205 }
6206
6207 public function setMailConfirmation($a_value)
6208 {
6209 $this->mail_confirmation = (bool) $a_value;
6210 }
6211
6212 public function hasMailConfirmation()
6213 {
6215 }
6216
6217 public function setAnonymousUserList($a_value)
6218 {
6219 $this->anon_user_list = (bool) $a_value;
6220 }
6221
6222 public function hasAnonymousUserList()
6223 {
6224 return $this->anon_user_list;
6225 }
6226
6227 public static function getSurveySkippedValue()
6228 {
6229 global $DIC;
6230
6231 $lng = $DIC->language();
6232
6233 // #13541
6234
6235 include_once "./Services/Administration/classes/class.ilSetting.php";
6236 $surveySetting = new ilSetting("survey");
6237 if (!$surveySetting->get("skipped_is_custom", false)) {
6238 return $lng->txt("skipped");
6239 } else {
6240 return $surveySetting->get("skipped_custom_value", "");
6241 }
6242 }
6243
6248 public function getReminderMailTemplates(&$defaultTemplateId = null)
6249 {
6250 global $DIC;
6251
6252 $res = array();
6253
6255 $templateService = $DIC['mail.texttemplates.service'];
6256 foreach ($templateService->loadTemplatesForContextId((string) ilSurveyMailTemplateReminderContext::ID) as $tmpl) {
6257 $res[$tmpl->getTplId()] = $tmpl->getTitle();
6258 if (null !== $defaultTemplateId && $tmpl->isDefault()) {
6259 $defaultTemplateId = $tmpl->getTplId();
6260 }
6261 }
6262
6263 return $res;
6264 }
6265
6266 protected function sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
6267 {
6268 // see ilMail::replacePlaceholders()
6269 try {
6271
6272 $user = new \ilObjUser($a_user_id);
6273
6274 $processor = new \ilMailTemplatePlaceholderResolver($context, $a_message);
6275 $a_message = $processor->resolve($user, $a_context_params);
6276 } catch (\Exception $e) {
6277 ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
6278 }
6279
6280 return $a_message;
6281 }
6282
6283 public function setMode($a_value)
6284 {
6285 $this->mode = $a_value;
6286 }
6287
6288 public function getMode()
6289 {
6290 return $this->mode;
6291 }
6292
6293 public function setSelfEvaluationResults($a_value)
6294 {
6295 $this->mode_self_eval_results = $a_value;
6296 }
6297
6299 {
6301 }
6302} // END class.ilObjSurvey
$result
user()
Definition: user.php:4
$size
Definition: RandomTest.php:84
$total
Definition: Utf8Test.php:87
$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, $include_seconds=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.
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)
const RESULTS_SELF_EVAL_NONE
getSkillService()
Get skill service.
deleteAppraisee($a_user_id)
deleteSurveyCode($survey_code)
Deletes a given survey access code.
getExportDirectory()
get export directory of survey
removeConstraintsConcerningQuestion($question_id)
Remove constraints concerning a question with a given question_id.
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.
update($a_upload=false)
update object data
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)
setSkillService($a_val)
Set skill service.
deleteAllUserData($reset_LP=true)
Deletes all user data of a survey.
__construct($a_id=0, $a_call_by_reference=true)
Constructor @access public.
sendNotificationMail($a_user_id, $a_anonymize_id, $a_appr_id)
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)
getReminderTemplate($selectDefault=false)
getQuestionGUI($questiontype, $question_id)
Returns a question gui object to a given questiontype and question id.
createMetaData()
Create meta data entry.
setSelfEvaluationResults($a_value)
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)
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
const RESULTS_SELF_EVAL_ALL
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)
const NOTIFICATION_PARENT_COURSE
setMailConfirmation($a_value)
const EVALUATION_ACCESS_ALL
closeAppraisee($a_user_id)
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.
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)
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.
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)
const RESULTS_SELF_EVAL_OWN
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.
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.
createExportDirectory()
creates data directory for export files (data_dir/svy_data/svy_<id>/export, depending on data directo...
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...
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 getUserIdsByEmail($a_email)
STATIC METHOD get all user_ids of an email address.
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)
setOfflineStatus($a_status)
Set offline status.
update()
update object in db
static _lookupTitle($a_id)
lookup object title
deleteMetaData()
delete meta data entry
updateMetaData()
update meta data entry
getOfflineStatus()
Get offline status.
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)
Returns a unique and non existing Path for e temporary file or 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.
$template
$key
Definition: croninfo.php:18
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
$i
Definition: disco.tpl.php:19
$messages
Definition: en.php:5
$y
Definition: example_007.php:83
$h
$code
Definition: example_050.php:99
const INVITATION_ON
const INVITATION_OFF
xslt_error(&$proc)
xslt_free(&$proc)
xslt_create()
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
$config
Definition: bootstrap.php:15
$time
Definition: cron.php:21
$index
Definition: metadata.php:60
catch(Exception $e) $message
$files
Definition: metarefresh.php:49
$row
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.
update($pash, $contents, Config $config)
$url
$s
Definition: pwgen.php:45
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
global $ilDB
$mobs
$ilUser
Definition: imgupload.php:18
$start
Definition: bench.php:8
$data
Definition: bench.php:6
$context
Definition: webdav.php:25
$text
Definition: errorreport.php:18
$rows
Definition: xhr_table.php:10