ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilObjSurvey.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5use \ILIAS\Survey\Participants;
6
12class ilObjSurvey extends ilObject
13{
17 protected $svy_log;
18
22 protected $user;
23
27 protected $access;
28
32 protected $plugin_admin;
33
37
38
39 const ANONYMIZE_OFF = 0; // personalized, no codes
40 const ANONYMIZE_ON = 1; // anonymized, codes
41 const ANONYMIZE_FREEACCESS = 2; // anonymized, no codes
42 const ANONYMIZE_CODE_ALL = 3; // personalized, codes
43
46
47 // constants to define the print view values.
48 const PRINT_HIDE_LABELS = 1; // Show only the titles in "print" and "PDF Export"
49 const PRINT_SHOW_LABELS = 3; // Show titles and labels in "print" and "PDF Export"
50
54 protected $calculate_sum_score = false;
55
62 public $survey_id;
63
70 public $author;
71
78
84 public $outro;
85
86
93
100
106 public $end_date;
107
114
115
121
127
134
140
144 protected $log;
145
149
150 // 360°
151 protected $mode_360_self_eval; // [bool]
152 protected $mode_360_self_appr; // [bool]
153 protected $mode_360_self_rate; // [bool]
154 protected $mode_360_results; // [int]
155 protected $mode_skill_service; // [bool]
156
160
161 // reminder/notification
162 protected $reminder_status; // [bool]
163 protected $reminder_start; // [ilDate]
164 protected $reminder_end; // [ilDate]
165 protected $reminder_frequency; // [int]
166 protected $reminder_target; // [int]
167 protected $reminder_last_sent; // [bool]
168 protected $reminder_tmpl; // [int]
169 protected $tutor_ntf_status; // [bool]
170 protected $tutor_ntf_recipients; // [array]
171 protected $tutor_ntf_target; // [int]
172 protected $tutor_res_status; // [bool]
173 protected $tutor_res_recipients; // [array]
174
175 protected $view_own_results; // [bool]
176 protected $mail_own_results; // [bool]
177 protected $mail_confirmation; // [bool]
178
179 protected $anon_user_list; // [bool]
180
186
187 protected $mode; //[int]
188 protected $mode_self_eval_results; //[int]
189
190 //MODE TYPES
191 const MODE_STANDARD = 0;
192 const MODE_360 = 1;
193 const MODE_SELF_EVAL = 2;
194
195 //self evaluation only access to results
199
200
205
212 public function __construct($a_id = 0, $a_call_by_reference = true)
213 {
214 global $DIC;
215
216 $this->user = $DIC->user();
217 $this->lng = $DIC->language();
218 $this->db = $DIC->database();
219 $this->access = $DIC->access();
220 $this->plugin_admin = $DIC["ilPluginAdmin"];
221 $this->tree = $DIC->repositoryTree();
222 $ilUser = $DIC->user();
223 $lng = $DIC->language();
224
225 $this->type = "svy";
226 $this->survey_id = -1;
227 $this->introduction = "";
228 $this->outro = $lng->txt("survey_finished");
229 $this->author = $ilUser->getFullname();
230 $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
231 $this->questions = array();
232 $this->anonymize = self::ANONYMIZE_OFF;
233 $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
234 $this->surveyCodeSecurity = true;
235 $this->template_id = null;
236 $this->pool_usage = true;
237 $this->mode = self::MODE_STANDARD;
238 $this->mode_self_eval_results = self::RESULTS_SELF_EVAL_OWN;
239
240 $this->invitation_manager = new Participants\InvitationsManager();
241
242 parent::__construct($a_id, $a_call_by_reference);
243 $this->svy_log = ilLoggerFactory::getLogger("svy");
244 }
245
249 public function create($a_upload = false)
250 {
251 parent::create();
252 if (!$a_upload) {
253 $this->createMetaData();
254 }
255 $this->setOfflineStatus(true);
256 $this->update($a_upload);
257 }
258
264 public function createMetaData()
265 {
266 parent::createMetaData();
267 $this->saveAuthorToMetadata();
268 }
269
276 public function update($a_upload = false)
277 {
278 if (!$a_upload) {
279 $this->updateMetaData();
280 }
281
282 if (!parent::update()) {
283 return false;
284 }
285
286 // put here object specific stuff
287
288 return true;
289 }
290
291 public function createReference()
292 {
293 $result = parent::createReference();
294 $this->saveToDb();
295 return $result;
296 }
297
302 public function read()
303 {
304 parent::read();
305 $this->loadFromDb();
306 }
307
314 public function addQuestion($question_id)
315 {
316 array_push($this->questions, $question_id);
317 }
318
325 public function delete()
326 {
327 if ($this->countReferences() == 1) {
328 $this->deleteMetaData();
329
330 // Delete all survey questions, constraints and materials
331 foreach ($this->questions as $question_id) {
332 $this->removeQuestion($question_id);
333 }
334 $this->deleteSurveyRecord();
335
337 }
338
339 $remove = parent::delete();
340
341 // always call parent delete function first!!
342 if (!$remove) {
343 return false;
344 }
345 return true;
346 }
347
353 public function deleteSurveyRecord()
354 {
356
357 $affectedRows = $ilDB->manipulateF(
358 "DELETE FROM svy_svy WHERE survey_id = %s",
359 array('integer'),
360 array($this->getSurveyId())
361 );
362
363 $result = $ilDB->queryF(
364 "SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
365 array('integer'),
366 array($this->getSurveyId())
367 );
368 $questionblocks = array();
369 while ($row = $ilDB->fetchAssoc($result)) {
370 array_push($questionblocks, $row["questionblock_fi"]);
371 }
372 if (count($questionblocks)) {
373 $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
374 }
375 $affectedRows = $ilDB->manipulateF(
376 "DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
377 array('integer'),
378 array($this->getSurveyId())
379 );
380 $this->deleteAllUserData(false);
381
382 $affectedRows = $ilDB->manipulateF(
383 "DELETE FROM svy_anonymous WHERE survey_fi = %s",
384 array('integer'),
385 array($this->getSurveyId())
386 );
387
388 // delete export files
389 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
390 $directory = $svy_data_dir . "/svy_" . $this->getId();
391 if (is_dir($directory)) {
392 ilUtil::delDir($directory);
393 }
394
395 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
396 // remaining usages are not in text anymore -> delete them
397 // and media objects (note: delete method of ilObjMediaObject
398 // checks whether object is used in another context; if yes,
399 // the object is not deleted!)
400 foreach ($mobs as $mob) {
401 ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
402 $mob_obj = new ilObjMediaObject($mob);
403 $mob_obj->delete();
404 }
405 }
406
413 public function deleteAllUserData($reset_LP = true)
414 {
416
417 $result = $ilDB->queryF(
418 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
419 array('integer'),
420 array($this->getSurveyId())
421 );
422 $active_array = array();
423 while ($row = $ilDB->fetchAssoc($result)) {
424 array_push($active_array, $row["finished_id"]);
425 }
426
427 $affectedRows = $ilDB->manipulateF(
428 "DELETE FROM svy_finished WHERE survey_fi = %s",
429 array('integer'),
430 array($this->getSurveyId())
431 );
432
433 foreach ($active_array as $active_fi) {
434 $affectedRows = $ilDB->manipulateF(
435 "DELETE FROM svy_answer WHERE active_fi = %s",
436 array('integer'),
437 array($active_fi)
438 );
439 $affectedRows = $ilDB->manipulateF(
440 "DELETE FROM svy_times WHERE finished_fi = %s",
441 array('integer'),
442 array($active_fi)
443 );
444 }
445
446 if ($reset_LP) {
447 $lp_obj = ilObjectLP::getInstance($this->getId());
448 $lp_obj->resetLPDataForCompleteObject();
449 }
450 }
451
457 public function removeSelectedSurveyResults($finished_ids)
458 {
460
461 $user_ids = array();
462
463 foreach ($finished_ids as $finished_id) {
464 $result = $ilDB->queryF(
465 "SELECT finished_id, user_fi FROM svy_finished WHERE finished_id = %s",
466 array('integer'),
467 array($finished_id)
468 );
469 $row = $ilDB->fetchAssoc($result);
470
471 if ($row["user_fi"]) {
472 $user_ids[] = (int) $row["user_fi"];
473 }
474
475 $affectedRows = $ilDB->manipulateF(
476 "DELETE FROM svy_answer WHERE active_fi = %s",
477 array('integer'),
478 array($row["finished_id"])
479 );
480
481 $affectedRows = $ilDB->manipulateF(
482 "DELETE FROM svy_finished WHERE finished_id = %s",
483 array('integer'),
484 array($finished_id)
485 );
486
487 $affectedRows = $ilDB->manipulateF(
488 "DELETE FROM svy_times WHERE finished_fi = %s",
489 array('integer'),
490 array($row["finished_id"])
491 );
492 }
493
494 if (sizeof($user_ids)) {
495 $lp_obj = ilObjectLP::getInstance($this->getId());
496 $lp_obj->resetLPDataForUserIds($user_ids);
497 }
498 }
499
500 public function &getSurveyParticipants($finished_ids = null, $force_non_anonymous = false, $include_invites = false)
501 {
503
504 $sql = "SELECT * FROM svy_finished" .
505 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
506 if ($finished_ids) {
507 $sql .= " AND " . $ilDB->in("finished_id", $finished_ids, "", "integer");
508 }
509
510 $result = $ilDB->query($sql);
511 $participants = array();
512 if ($result->numRows() > 0) {
513 while ($row = $ilDB->fetchAssoc($result)) {
514 $userdata = $this->getUserDataFromActiveId($row["finished_id"], $force_non_anonymous);
515 $userdata["finished"] = (bool) $row["state"];
516 $userdata["finished_tstamp"] = $row["tstamp"];
517 $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
518 }
519 }
520 $participant_ids = array_column($participants, "usr_id");
521 if ($include_invites) {
522 foreach ($this->invitation_manager->getAllForSurvey($this->getSurveyId()) as $usr_id) {
523 if (!in_array($usr_id, $participant_ids)) {
524 $name = ilObjUser::_lookupName($usr_id);
525 $participants[$name["lastname"] . "," . $name["firstname"] . $usr_id] = [
526 "fullname" => ilObjUser::_lookupFullname($usr_id),
527 "sortname" => $name["lastname"] . "," . $name["firstname"],
528 "fistname" => $name["firstname"],
529 "lastname" => $name["lastname"],
530 "login" => $name["login"],
531 "gender" => "",
532 "usr_id" => $usr_id,
533 "finished" => false,
534 "finished_tstamp" => 0,
535 "invited" => true
536 ];
537 }
538 }
539 }
540
541 return $participants;
542 }
543
550 public function isComplete()
551 {
552 if (($this->getTitle()) and (count($this->questions))) {
553 return 1;
554 } else {
555 return 0;
556 }
557 }
558
564 public function saveCompletionStatus()
565 {
567
568 $complete = 0;
569 if ($this->isComplete()) {
570 $complete = 1;
571 }
572 if ($this->getSurveyId() > 0) {
573 $affectedRows = $ilDB->manipulateF(
574 "UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
575 array('text','integer','integer'),
576 array($this->isComplete(), time(), $this->getSurveyId())
577 );
578 }
579 }
580
588 public function duplicateQuestionForSurvey($question_id, $a_force = false)
589 {
591
592 $questiontype = $this->getQuestionType($question_id);
593 $question_gui = $this->getQuestionGUI($questiontype, $question_id);
594
595 // check if question is a pool question at all, if not do nothing
596 if ($this->getId() == $question_gui->object->getObjId() && !$a_force) {
597 return $question_id;
598 }
599
600 $duplicate_id = $question_gui->object->duplicate(true, "", "", "", $this->getId());
601 return $duplicate_id;
602 }
603
609 public function insertQuestion($question_id)
610 {
612
613 $this->svy_log->debug("insert question, id:" . $question_id);
614
615 if (!SurveyQuestion::_isComplete($question_id)) {
616 $this->svy_log->debug("question is not complete");
617 return false;
618 } else {
619 // get maximum sequence index in test
620 // @todo: refactor this
621 $result = $ilDB->queryF(
622 "SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
623 array('integer'),
624 array($this->getSurveyId())
625 );
626 $sequence = $result->numRows();
627 $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
628 $this->svy_log->debug("duplicate, id: " . $question_id . ", duplicate id: " . $duplicate_id);
629
630 // check if question is not already in the survey, see #22018
631 if ($this->isQuestionInSurvey($duplicate_id)) {
632 return false;
633 }
634
635 $next_id = $ilDB->nextId('svy_svy_qst');
636 $affectedRows = $ilDB->manipulateF(
637 "INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
638 array('integer', 'integer', 'integer', 'integer', 'integer'),
639 array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
640 );
641
642 $this->svy_log->debug("added entry to svy_svy_qst, id: " . $next_id . ", question id: " . $duplicate_id . ", sequence: " . $sequence);
643
644 $this->loadQuestionsFromDb();
645 return true;
646 }
647 }
648
655 public function isQuestionInSurvey($a_question_fi)
656 {
657 global $DIC;
658 //return false;
659 $ilDB = $DIC->database();
660
661 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
662 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
663 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
664 if ($rec = $ilDB->fetchAssoc($set)) {
665 return true;
666 }
667 return false;
668 }
669
670
671
677 public function insertQuestionblock($questionblock_id)
678 {
680 $result = $ilDB->queryF(
681 "SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle," .
682 " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst" .
683 " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi" .
684 " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi" .
685 " AND svy_qblk.questionblock_id = %s" .
686 " ORDER BY svy_svy_qst.sequence",
687 array('integer'),
688 array($questionblock_id)
689 );
690 $questions = array();
691 $show_questiontext = 0;
692 $show_blocktitle = 0;
693 while ($row = $ilDB->fetchAssoc($result)) {
694 $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
695 array_push($questions, $duplicate_id);
696 $title = $row["title"];
697 $show_questiontext = $row["show_questiontext"];
698 $show_blocktitle = $row["show_blocktitle"];
699 }
700 $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
701 }
702
703 public function saveUserSettings($usr_id, $key, $title, $value)
704 {
706
707 $next_id = $ilDB->nextId('svy_settings');
708 $affectedRows = $ilDB->insert("svy_settings", array(
709 "settings_id" => array("integer", $next_id),
710 "usr_id" => array("integer", $usr_id),
711 "keyword" => array("text", $key),
712 "title" => array("text", $title),
713 "value" => array("clob", $value)
714 ));
715 }
716
717 public function deleteUserSettings($id)
718 {
720
721 $affectedRows = $ilDB->manipulateF(
722 "DELETE FROM svy_settings WHERE settings_id = %s",
723 array('integer'),
724 array($id)
725 );
726 return $affectedRows;
727 }
728
729 public function getUserSettings($usr_id, $key)
730 {
732
733 $result = $ilDB->queryF(
734 "SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
735 array('integer', 'text'),
736 array($usr_id, $key)
737 );
738 $found = array();
739 if ($result->numRows()) {
740 while ($row = $ilDB->fetchAssoc($result)) {
741 $found[$row['settings_id']] = $row;
742 }
743 }
744 return $found;
745 }
746
752 public function saveToDb()
753 {
755
756 // date handling
757 $rmd_start = $this->getReminderStart();
758 if (is_object($rmd_start)) {
759 $rmd_start = $rmd_start->get(IL_CAL_DATE);
760 }
761 $rmd_end = $this->getReminderEnd();
762 if (is_object($rmd_end)) {
763 $rmd_end = $rmd_end->get(IL_CAL_DATE);
764 }
765
766 if ($this->getSurveyId() < 1) {
767 $next_id = $ilDB->nextId('svy_svy');
768 $affectedRows = $ilDB->insert("svy_svy", array(
769 "survey_id" => array("integer", $next_id),
770 "obj_fi" => array("integer", $this->getId()),
771 "author" => array("text", $this->getAuthor()),
772 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
773 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
774 "startdate" => array("text", $this->getStartDate()),
775 "enddate" => array("text", $this->getEndDate()),
776 "evaluation_access" => array("text", $this->getEvaluationAccess()),
777 "complete" => array("text", $this->isComplete()),
778 "created" => array("integer", time()),
779 "anonymize" => array("text", $this->getAnonymize()),
780 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
781 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
782 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
783 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
784 "tstamp" => array("integer", time()),
785 "template_id" => array("integer", $this->getTemplate()),
786 "pool_usage" => array("integer", $this->getPoolUsage()),
787 // Mode type
788 "mode" => array("integer", $this->getMode()),
789 // 360°
790 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
791 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
792 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
793 "mode_360_results" => array("integer", $this->get360Results()),
794 // competences
795 "mode_skill_service" => array("integer", (int) $this->getSkillService()),
796 // Self Evaluation Only
797 "mode_self_eval_results" => array("integer", ilObjSurvey::RESULTS_SELF_EVAL_OWN),
798 // reminder/notification
799 "reminder_status" => array("integer", (int) $this->getReminderStatus()),
800 "reminder_start" => array("datetime", $rmd_start),
801 "reminder_end" => array("datetime", $rmd_end),
802 "reminder_frequency" => array("integer", (int) $this->getReminderFrequency()),
803 "reminder_target" => array("integer", (int) $this->getReminderTarget()),
804 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
805 "reminder_tmpl" => array("text", $this->getReminderTemplate(true)),
806 "tutor_ntf_status" => array("integer", (int) $this->getTutorNotificationStatus()),
807 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
808 "tutor_ntf_target" => array("integer", (int) $this->getTutorNotificationTarget()),
809 "own_results_view" => array("integer", $this->hasViewOwnResults()),
810 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
811 "tutor_res_status" => array("integer", (int) $this->getTutorResultsStatus()),
812 "tutor_res_reci" => array("text", implode(";", (array) $this->getTutorResultsRecipients())),
813 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
814 "anon_user_list" => array("integer", $this->hasAnonymousUserList()),
815 "calculate_sum_score" => array("integer", $this->getCalculateSumScore())
816 ));
817 $this->setSurveyId($next_id);
818 } else {
819 $affectedRows = $ilDB->update("svy_svy", array(
820 "author" => array("text", $this->getAuthor()),
821 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
822 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
823 "startdate" => array("text", $this->getStartDate()),
824 "enddate" => array("text", $this->getEndDate()),
825 "evaluation_access" => array("text", $this->getEvaluationAccess()),
826 "complete" => array("text", $this->isComplete()),
827 "anonymize" => array("text", $this->getAnonymize()),
828 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
829 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
830 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
831 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
832 "tstamp" => array("integer", time()),
833 "template_id" => array("integer", $this->getTemplate()),
834 "pool_usage" => array("integer", $this->getPoolUsage()),
835 //MODE TYPE
836 "mode" => array("integer", $this->getMode()),
837 // 360°
838 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
839 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
840 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
841 "mode_360_results" => array("integer", $this->get360Results()),
842 // Competences
843 "mode_skill_service" => array("integer", (int) $this->getSkillService()),
844 // Self Evaluation Only
845 "mode_self_eval_results" => array("integer", $this->getSelfEvaluationResults()),
846 // reminder/notification
847 "reminder_status" => array("integer", $this->getReminderStatus()),
848 "reminder_start" => array("datetime", $rmd_start),
849 "reminder_end" => array("datetime", $rmd_end),
850 "reminder_frequency" => array("integer", $this->getReminderFrequency()),
851 "reminder_target" => array("integer", $this->getReminderTarget()),
852 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
853 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
854 "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
855 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
856 "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget()),
857 "own_results_view" => array("integer", $this->hasViewOwnResults()),
858 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
859 "tutor_res_status" => array("integer", (int) $this->getTutorResultsStatus()),
860 "tutor_res_reci" => array("text", implode(";", (array) $this->getTutorResultsRecipients())),
861 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
862 "anon_user_list" => array("integer", $this->hasAnonymousUserList()),
863 "calculate_sum_score" => array("integer", $this->getCalculateSumScore())
864 ), array(
865 "survey_id" => array("integer", $this->getSurveyId())
866 ));
867 }
868 if ($affectedRows) {
869 // save questions to db
870 $this->saveQuestionsToDb();
871 }
872
873 // moved activation to ilObjectActivation
874 if ($this->ref_id) {
875 ilObjectActivation::getItem($this->ref_id);
876
877 $item = new ilObjectActivation;
878 if (!$this->isActivationLimited()) {
880 } else {
881 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
882 $item->setTimingStart($this->getActivationStartDate());
883 $item->setTimingEnd($this->getActivationEndDate());
884 $item->toggleVisible($this->getActivationVisibility());
885 }
886
887 $item->update($this->ref_id);
888 }
889 }
890
897 public function saveQuestionsToDb()
898 {
900
901 $this->svy_log->debug("save questions");
902
903 // gather old questions state
904 $old_questions = array();
905 $result = $ilDB->queryF(
906 "SELECT survey_question_id,question_fi,sequence" .
907 " FROM svy_svy_qst WHERE survey_fi = %s",
908 array('integer'),
909 array($this->getSurveyId())
910 );
911 while ($row = $ilDB->fetchAssoc($result)) {
912 $old_questions[$row["question_fi"]] = $row; // problem, as soon as duplicates exist, they will be hidden here
913 }
914
915 // #15231 - diff with current questions state
916 $insert = $update = $delete = array();
917 foreach ($this->questions as $seq => $fi) {
918 if (!array_key_exists($fi, $old_questions)) { // really new fi IDs
919 $insert[] = $fi; // this should be ok, should not create duplicates here
920 } elseif ($old_questions[$fi]["sequence"] != $seq) { // we are updating one of the duplicates (if any)
921 $update[$fi] = $old_questions[$fi]["survey_question_id"];
922 }
923 // keep track of still relevant questions
924 unset($old_questions[$fi]); // deleting old question, if they are not in current array
925 }
926
927 // delete obsolete question relations
928 if (sizeof($old_questions)) {
929 $del_ids = array();
930 foreach ($old_questions as $fi => $old) {
931 $del_ids[] = $old["survey_question_id"];
932 }
933 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
934 " WHERE " . $ilDB->in("survey_question_id", $del_ids, "", "integer"));
935 $this->svy_log->debug("delete: " . $q);
936 }
937 unset($old_questions);
938
939 // create/update question relations
940 foreach ($this->questions as $seq => $fi) {
941 if (in_array($fi, $insert)) {
942 // check if question is not already in the survey, see #22018
943 if (!$this->isQuestionInSurvey($fi)) {
944 $next_id = $ilDB->nextId('svy_svy_qst');
945 $ilDB->manipulateF(
946 "INSERT INTO svy_svy_qst" .
947 " (survey_question_id, survey_fi, question_fi, heading, sequence, tstamp)" .
948 " VALUES (%s, %s, %s, %s, %s, %s)",
949 array('integer', 'integer', 'integer', 'text', 'integer', 'integer'),
950 array($next_id, $this->getSurveyId(), $fi, null, $seq, time())
951 );
952 $this->svy_log->debug("insert svy_svy_qst, id:" . $next_id . ", fi: " . $fi . ", seq:" . $seq);
953 }
954 } elseif (array_key_exists($fi, $update)) {
955 $ilDB->manipulate("UPDATE svy_svy_qst" .
956 " SET sequence = " . $ilDB->quote($seq, "integer") .
957 ", tstamp = " . $ilDB->quote(time(), "integer") .
958 " WHERE survey_question_id = " . $ilDB->quote($update[$fi], "integer"));
959 $this->svy_log->debug("update svy_svy_qst, id:" . $update[$fi] . ", fi: " . $fi . ", seq:" . $seq);
960 }
961 }
962 }
963
971 public function getAnonymousId($id)
972 {
974 $result = $ilDB->queryF(
975 "SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
976 array('text'),
977 array($id)
978 );
979 if ($result->numRows()) {
980 $row = $ilDB->fetchAssoc($result);
981 return $row["anonymous_id"];
982 } else {
983 return "";
984 }
985 }
986
993 public function getQuestionGUI($questiontype, $question_id)
994 {
995 return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
996 }
997
1005 public function getQuestionType($question_id)
1006 {
1007 $ilDB = $this->db;
1008 if ($question_id < 1) {
1009 return -1;
1010 }
1011 $result = $ilDB->queryF(
1012 "SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
1013 "svy_question.questiontype_fi = svy_qtype.questiontype_id",
1014 array('integer'),
1015 array($question_id)
1016 );
1017 if ($result->numRows() == 1) {
1018 $data = $ilDB->fetchAssoc($result);
1019 return $data["type_tag"];
1020 } else {
1021 return "";
1022 }
1023 }
1024
1031 public function getSurveyId()
1032 {
1033 return $this->survey_id;
1034 }
1035
1039 public function setAnonymize($a_anonymize)
1040 {
1041 switch ($a_anonymize) {
1043 case self::ANONYMIZE_ON:
1046 $this->anonymize = $a_anonymize;
1047 break;
1048 default:
1049 $this->anonymize = self::ANONYMIZE_OFF;
1050 break;
1051 }
1052 }
1053
1059 public function getAnonymize()
1060 {
1061 return ($this->anonymize) ? $this->anonymize : 0;
1062 }
1063
1068 public function setCalculateSumScore(bool $a_val)
1069 {
1070 $this->calculate_sum_score = $a_val;
1071 }
1072
1077 public function getCalculateSumScore() : bool
1078 {
1080 }
1081
1087 public function isAccessibleWithoutCode()
1088 {
1089 return ($this->getAnonymize() == self::ANONYMIZE_OFF ||
1090 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1091 }
1092
1098 public function hasAnonymizedResults()
1099 {
1100 return ($this->getAnonymize() == self::ANONYMIZE_ON ||
1101 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1102 }
1103
1109 public function loadFromDb()
1110 {
1111 $ilDB = $this->db;
1112 $result = $ilDB->queryF(
1113 "SELECT * FROM svy_svy WHERE obj_fi = %s",
1114 array('integer'),
1115 array($this->getId())
1116 );
1117 if ($result->numRows() == 1) {
1118 $data = $ilDB->fetchAssoc($result);
1119 $this->setSurveyId($data["survey_id"]);
1120 $this->setAuthor($data["author"]);
1121 $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1122 if (strcmp($data["outro"], "survey_finished") == 0) {
1123 $this->setOutro($this->lng->txt("survey_finished"));
1124 } else {
1126 }
1127 $this->setShowQuestionTitles($data["show_question_titles"]);
1128 $this->setStartDate($data["startdate"]);
1129 $this->setEndDate($data["enddate"]);
1130 $this->setAnonymize($data["anonymize"]);
1131 $this->setEvaluationAccess($data["evaluation_access"]);
1132 $this->loadQuestionsFromDb();
1133 $this->setMailNotification($data['mailnotification']);
1134 $this->setMailAddresses($data['mailaddresses']);
1135 $this->setMailParticipantData($data['mailparticipantdata']);
1136 $this->setTemplate($data['template_id']);
1137 $this->setPoolUsage($data['pool_usage']);
1138 // Mode
1139 $this->setMode($data['mode']);
1140 // 360°
1141 $this->set360SelfEvaluation($data['mode_360_self_eval']);
1142 $this->set360SelfRaters($data['mode_360_self_rate']);
1143 $this->set360SelfAppraisee($data['mode_360_self_appr']);
1144 $this->set360Results($data['mode_360_results']);
1145 // Mode self evaluated
1146 $this->setSelfEvaluationResults($data['mode_self_eval_results']);
1147 // Competences
1148 $this->setSkillService($data['mode_skill_service']);
1149 // reminder/notification
1150 $this->setReminderStatus($data["reminder_status"]);
1151 $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1152 $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1153 $this->setReminderFrequency($data["reminder_frequency"]);
1154 $this->setReminderTarget($data["reminder_target"]);
1155 $this->setReminderLastSent($data["reminder_last_sent"]);
1156 $this->setReminderTemplate($data["reminder_tmpl"]);
1157 $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1158 $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1159 $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1160 $this->setTutorResultsStatus($data["tutor_res_status"]);
1161 $this->setTutorResultsRecipients(explode(";", $data["tutor_res_reci"]));
1162
1163 $this->setViewOwnResults($data["own_results_view"]);
1164 $this->setMailOwnResults($data["own_results_mail"]);
1165 $this->setMailConfirmation($data["confirmation_mail"]);
1166 $this->setCalculateSumScore($data["calculate_sum_score"]);
1167
1168 $this->setAnonymousUserList($data["anon_user_list"]);
1169 }
1170
1171 // moved activation to ilObjectActivation
1172 if ($this->ref_id) {
1173 $activation = ilObjectActivation::getItem($this->ref_id);
1174 switch ($activation["timing_type"]) {
1176 $this->setActivationLimited(true);
1177 $this->setActivationStartDate($activation["timing_start"]);
1178 $this->setActivationEndDate($activation["timing_end"]);
1179 $this->setActivationVisibility($activation["visible"]);
1180 break;
1181
1182 default:
1183 $this->setActivationLimited(false);
1184 break;
1185 }
1186 }
1187 }
1188
1195 public function loadQuestionsFromDb()
1196 {
1197 $ilDB = $this->db;
1198 $this->questions = array();
1199 $result = $ilDB->queryF(
1200 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1201 array('integer'),
1202 array($this->getSurveyId())
1203 );
1204 while ($data = $ilDB->fetchAssoc($result)) {
1205 $this->questions[$data["sequence"]] = $data["question_fi"];
1206 }
1207 }
1208
1212 public function fixSequenceStructure()
1213 {
1214 global $DIC;
1215
1216 $ilDB = $DIC->database();
1217 //return;
1218 // we keep all survey question ids with their lowest sequence
1219 $result = $ilDB->queryF(
1220 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1221 array('integer'),
1222 array($this->getSurveyId())
1223 );
1224
1225 // step 1: find duplicates -> $to_delete_ids
1226 $fis = array();
1227 $to_delete_ids = array();
1228 while ($data = $ilDB->fetchAssoc($result)) {
1229 if (in_array($data["question_fi"], $fis)) { // found a duplicate
1230 $to_delete_ids[] = $data["survey_question_id"];
1231 } else {
1232 $fis[] = $data["question_fi"];
1233 }
1234 }
1235
1236 // step 2: we delete the duplicates
1237 if (count($to_delete_ids) > 0) {
1238 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
1239 " WHERE " . $ilDB->in("survey_question_id", $to_delete_ids, false, "integer") .
1240 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1241 $this->svy_log->debug("delete: " . $q);
1242
1243 $ilDB->manipulate($q = "DELETE FROM svy_qblk_qst " .
1244 " WHERE " . $ilDB->in("question_fi", $fis, true, "integer") .
1245 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1246 $this->svy_log->debug("delete: " . $q);
1247 }
1248
1249 // step 3: we fix the sequence
1250 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
1251 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") . " ORDER BY sequence");
1252 $seq = 0;
1253 while ($rec = $ilDB->fetchAssoc($set)) {
1254 $ilDB->manipulate(
1255 $q = "UPDATE svy_svy_qst SET " .
1256 " sequence = " . $ilDB->quote($seq++, "integer") .
1257 " WHERE survey_question_id = " . $ilDB->quote($rec["survey_question_id"], "integer")
1258 );
1259 $this->svy_log->debug("update: " . $q);
1260 }
1261 }
1262
1263
1271 public function setAuthor($author = "")
1272 {
1273 $this->author = $author;
1274 }
1275
1285 public function saveAuthorToMetadata($a_author = "")
1286 {
1287 $md = new ilMD($this->getId(), 0, $this->getType());
1288 $md_life = &$md->getLifecycle();
1289 if (!$md_life) {
1290 if (strlen($a_author) == 0) {
1292 $a_author = $ilUser->getFullname();
1293 }
1294
1295 $md_life = &$md->addLifecycle();
1296 $md_life->save();
1297 $con = &$md_life->addContribute();
1298 $con->setRole("Author");
1299 $con->save();
1300 $ent = &$con->addEntity();
1301 $ent->setEntity($a_author);
1302 $ent->save();
1303 }
1304 }
1305
1313 public function getAuthor()
1314 {
1315 $author = array();
1316 $md = new ilMD($this->getId(), 0, $this->getType());
1317 $md_life = &$md->getLifecycle();
1318 if ($md_life) {
1319 $ids = &$md_life->getContributeIds();
1320 foreach ($ids as $id) {
1321 $md_cont = &$md_life->getContribute($id);
1322 if (strcmp($md_cont->getRole(), "Author") == 0) {
1323 $entids = &$md_cont->getEntityIds();
1324 foreach ($entids as $entid) {
1325 $md_ent = &$md_cont->getEntity($entid);
1326 array_push($author, $md_ent->getEntity());
1327 }
1328 }
1329 }
1330 }
1331 return join(",", $author);
1332 }
1333
1340 public function getShowQuestionTitles()
1341 {
1342 return ($this->display_question_titles) ? 1 : 0;
1343 }
1344
1351 public function setShowQuestionTitles($a_show)
1352 {
1353 $this->display_question_titles = ($a_show) ? 1 : 0;
1354 }
1355
1362 public function showQuestionTitles()
1363 {
1364 $this->display_question_titles = 1;
1365 }
1366
1373 public function hideQuestionTitles()
1374 {
1375 $this->display_question_titles = 0;
1376 }
1377
1384 public function setIntroduction($introduction = "")
1385 {
1386 $this->introduction = $introduction;
1387 }
1388
1395 public function setOutro($outro = "")
1396 {
1397 $this->outro = $outro;
1398 }
1399
1400
1408 public function getStartDate()
1409 {
1410 return (strlen($this->start_date)) ? $this->start_date : null;
1411 }
1412
1419 public function canStartSurvey($anonymous_id = null, $a_no_rbac = false)
1420 {
1421 $ilAccess = $this->access;
1422
1423 $result = true;
1424 $messages = array();
1425 $edit_settings = false;
1426 // check start date
1427 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches)) {
1428 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1429 $now = time();
1430 if ($now < $epoch_time) {
1431 array_push($messages, $this->lng->txt('start_date_not_reached') . ' (' .
1433 $result = false;
1434 $edit_settings = true;
1435 }
1436 }
1437 // check end date
1438 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches)) {
1439 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1440 $now = time();
1441 if ($now > $epoch_time) {
1442 array_push($messages, $this->lng->txt('end_date_reached') . ' (' .
1444 $result = false;
1445 $edit_settings = true;
1446 }
1447 }
1448
1449 // check online status
1450 if ($this->getOfflineStatus()) {
1451 array_push($messages, $this->lng->txt("survey_is_offline"));
1452 $result = false;
1453 $edit_settings = true;
1454 }
1455 // check rbac permissions
1456 if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id)) {
1457 array_push($messages, $this->lng->txt("cannot_participate_survey"));
1458 $result = false;
1459 }
1460 /*
1461 // 2. check previous access
1462 if (!$result["error"])
1463 {
1464 $ilUser = $this->user;
1465 $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1466 if ($survey_started === 1)
1467 {
1468 array_push($messages, $this->lng->txt("already_completed_survey"));
1469 $result = FALSE;
1470 }
1471 }
1472 */
1473 return array(
1474 "result" => $result,
1475 "messages" => $messages,
1476 "edit_settings" => $edit_settings
1477 );
1478 }
1479
1487 public function setStartDate($start_date = "")
1488 {
1489 $this->start_date = $start_date;
1490 }
1491
1500 public function setStartDateAndTime($start_date = "", $start_time)
1501 {
1502 $y = '';
1503 $m = '';
1504 $d = '';
1505 $h = '';
1506 $i = '';
1507 $s = '';
1508 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches)) {
1509 $y = $matches[1];
1510 $m = $matches[2];
1511 $d = $matches[3];
1512 }
1513 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches)) {
1514 $h = $matches[1];
1515 $i = $matches[2];
1516 $s = $matches[3];
1517 }
1518 $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1519 }
1520
1528 public function getEndDate()
1529 {
1530 return (strlen($this->end_date)) ? $this->end_date : null;
1531 }
1532
1540 public function setEndDate($end_date = "")
1541 {
1542 $this->end_date = $end_date;
1543 }
1544
1553 public function setEndDateAndTime($end_date = "", $end_time)
1554 {
1555 $y = '';
1556 $m = '';
1557 $d = '';
1558 $h = '';
1559 $i = '';
1560 $s = '';
1561 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches)) {
1562 $y = $matches[1];
1563 $m = $matches[2];
1564 $d = $matches[3];
1565 }
1566 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches)) {
1567 $h = $matches[1];
1568 $i = $matches[2];
1569 $s = $matches[3];
1570 }
1571 $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1572 }
1573
1581 public function getEvaluationAccess()
1582 {
1583 return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1584 }
1585
1593 public function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1594 {
1595 $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1596 }
1597
1598 public function setActivationVisibility($a_value)
1599 {
1600 $this->activation_visibility = (bool) $a_value;
1601 }
1602
1603 public function getActivationVisibility()
1604 {
1606 }
1607
1608 public function isActivationLimited()
1609 {
1610 return (bool) $this->activation_limited;
1611 }
1612
1613 public function setActivationLimited($a_value)
1614 {
1615 $this->activation_limited = (bool) $a_value;
1616 }
1617
1625 public function getIntroduction()
1626 {
1627 return (strlen($this->introduction)) ? $this->introduction : null;
1628 }
1629
1637 public function getOutro()
1638 {
1639 return (strlen($this->outro)) ? $this->outro : null;
1640 }
1641
1648 public function &getExistingQuestions()
1649 {
1650 $ilDB = $this->db;
1651 $existing_questions = array();
1652 $result = $ilDB->queryF(
1653 "SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1654 "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1655 array('integer'),
1656 array($this->getSurveyId())
1657 );
1658 while ($data = $ilDB->fetchAssoc($result)) {
1659 if ($data["original_id"]) {
1660 array_push($existing_questions, $data["original_id"]);
1661 }
1662 }
1663 return $existing_questions;
1664 }
1665
1672 public function &getQuestionpoolTitles($could_be_offline = false, $showPath = false)
1673 {
1674 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = true, $could_be_offline, $showPath);
1675 }
1676
1685 public function moveQuestions($move_questions, $target_index, $insert_mode)
1686 {
1687 $this->svy_log->debug("move_questions: " . print_r($move_questions, true) .
1688 ", target_index: " . $target_index . ", insert_mode: " . $insert_mode);
1689 $array_pos = array_search($target_index, $this->questions);
1690 if ($insert_mode == 0) {
1691 $part1 = array_slice($this->questions, 0, $array_pos);
1692 $part2 = array_slice($this->questions, $array_pos);
1693 } elseif ($insert_mode == 1) {
1694 $part1 = array_slice($this->questions, 0, $array_pos + 1);
1695 $part2 = array_slice($this->questions, $array_pos + 1);
1696 }
1697 $found = 0;
1698 foreach ($move_questions as $question_id) {
1699 if (!(array_search($question_id, $part1) === false)) {
1700 unset($part1[array_search($question_id, $part1)]);
1701 $found++;
1702 }
1703 if (!(array_search($question_id, $part2) === false)) {
1704 unset($part2[array_search($question_id, $part2)]);
1705 $found++;
1706 }
1707 }
1708 // sanity check: do not move questions if they have not be found in the array
1709 if ($found != count($move_questions)) {
1710 return;
1711 }
1712 $part1 = array_values($part1);
1713 $part2 = array_values($part2);
1714 $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1715 foreach ($move_questions as $question_id) {
1716 $constraints = $this->getConstraints($question_id);
1717 foreach ($constraints as $idx => $constraint) {
1718 foreach ($part2 as $next_question_id) {
1719 if ($constraint["question"] == $next_question_id) {
1720 // constraint concerning a question that follows -> delete constraint
1721 $this->deleteConstraint($constraint["id"]);
1722 }
1723 }
1724 }
1725 }
1726 $this->saveQuestionsToDb();
1727 }
1728
1735 public function removeQuestion($question_id)
1736 {
1737 $question = self::_instanciateQuestion($question_id);
1738 #20610 if no question found, do nothing.
1739 if ($question) {
1740 $question->delete($question_id);
1741 $this->removeConstraintsConcerningQuestion($question_id);
1742 }
1743 }
1744
1751 public function removeConstraintsConcerningQuestion($question_id)
1752 {
1753 $ilDB = $this->db;
1754 $result = $ilDB->queryF(
1755 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1756 array('integer','integer'),
1757 array($question_id, $this->getSurveyId())
1758 );
1759 if ($result->numRows() > 0) {
1760 $remove_constraints = array();
1761 while ($row = $ilDB->fetchAssoc($result)) {
1762 array_push($remove_constraints, $row["constraint_fi"]);
1763 }
1764 $affectedRows = $ilDB->manipulateF(
1765 "DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1766 array('integer','integer'),
1767 array($question_id, $this->getSurveyId())
1768 );
1769 foreach ($remove_constraints as $key => $constraint_id) {
1770 $affectedRows = $ilDB->manipulateF(
1771 "DELETE FROM svy_constraint WHERE constraint_id = %s",
1772 array('integer'),
1773 array($constraint_id)
1774 );
1775 }
1776 }
1777 }
1778
1786 public function removeQuestions($remove_questions, $remove_questionblocks)
1787 {
1788 $ilDB = $this->db;
1789
1790 $block_sizes = array();
1791 foreach ($this->getSurveyQuestions() as $question_id => $data) {
1792 if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks)) {
1793 unset($this->questions[array_search($question_id, $this->questions)]);
1794 $this->removeQuestion($question_id);
1795 } elseif ($data["questionblock_id"]) {
1796 $block_sizes[$data["questionblock_id"]]++;
1797 }
1798 }
1799
1800 // blocks with just 1 question need to be deleted
1801 foreach ($block_sizes as $block_id => $size) {
1802 if ($size < 2) {
1803 $remove_questionblocks[] = $block_id;
1804 }
1805 }
1806
1807 foreach (array_unique($remove_questionblocks) as $questionblock_id) {
1808 $affectedRows = $ilDB->manipulateF(
1809 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1810 array('integer'),
1811 array($questionblock_id)
1812 );
1813 $affectedRows = $ilDB->manipulateF(
1814 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1815 array('integer','integer'),
1816 array($questionblock_id, $this->getSurveyId())
1817 );
1818 }
1819
1820 $this->questions = array_values($this->questions);
1821 $this->saveQuestionsToDb();
1822 }
1823
1830 public function unfoldQuestionblocks($questionblocks)
1831 {
1832 $ilDB = $this->db;
1833 foreach ($questionblocks as $index) {
1834 $affectedRows = $ilDB->manipulateF(
1835 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1836 array('integer'),
1837 array($index)
1838 );
1839 $affectedRows = $ilDB->manipulateF(
1840 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1841 array('integer','integer'),
1842 array($index, $this->getSurveyId())
1843 );
1844 }
1845 }
1846
1847 public function removeQuestionFromBlock($question_id, $questionblock_id)
1848 {
1849 $ilDB = $this->db;
1850
1851 $affectedRows = $ilDB->manipulateF(
1852 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
1853 array('integer','integer','integer'),
1854 array($questionblock_id, $this->getSurveyId(), $question_id)
1855 );
1856 }
1857
1858 public function addQuestionToBlock($question_id, $questionblock_id)
1859 {
1860 $ilDB = $this->db;
1861
1862 // see #22018
1863 if (!$this->isQuestionInAnyBlock($question_id)) {
1864 $next_id = $ilDB->nextId('svy_qblk_qst');
1865 $affectedRows = $ilDB->manipulateF(
1866 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
1867 "question_fi) VALUES (%s, %s, %s, %s)",
1868 array('integer', 'integer', 'integer', 'integer'),
1869 array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
1870 );
1871
1872 $this->deleteConstraints($question_id); // #13713
1873 }
1874 }
1875
1882 public function isQuestionInAnyBlock($a_question_fi)
1883 {
1884 global $DIC;
1885
1886 $ilDB = $DIC->database();
1887
1888 $set = $ilDB->query("SELECT * FROM svy_qblk_qst " .
1889 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
1890 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
1891 if ($rec = $ilDB->fetchAssoc($set)) {
1892 return true;
1893 }
1894 return false;
1895 }
1896
1897
1904 public function &getQuestionblockQuestions($questionblock_id)
1905 {
1906 $ilDB = $this->db;
1907 $titles = array();
1908 $result = $ilDB->queryF(
1909 "SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM " .
1910 "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
1911 "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
1912 array('integer'),
1913 array($questionblock_id)
1914 );
1915 $survey_id = "";
1916 while ($row = $ilDB->fetchAssoc($result)) {
1917 $titles[$row["question_fi"]] = $row["title"];
1918 $survey_id = $row["survey_fi"];
1919 }
1920 $result = $ilDB->queryF(
1921 "SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1922 array('integer'),
1923 array($survey_id)
1924 );
1925 $resultarray = array();
1926 $counter = 1;
1927 while ($row = $ilDB->fetchAssoc($result)) {
1928 if (array_key_exists($row["question_fi"], $titles)) {
1929 $resultarray[$counter++] = $titles[$row["question_fi"]];
1930 }
1931 }
1932 return $resultarray;
1933 }
1934
1941 public function &getQuestionblockQuestionIds($questionblock_id)
1942 {
1943 $ilDB = $this->db;
1944
1945 // we need a correct order here, see #22011
1946 $result = $ilDB->queryF(
1947 "SELECT a.question_fi FROM svy_qblk_qst a JOIN svy_svy_qst b ON (a.question_fi = b.question_fi) " .
1948 " WHERE a.questionblock_fi = %s ORDER BY b.sequence",
1949 array("integer"),
1950 array($questionblock_id)
1951 );
1952 $ids = array();
1953 if ($result->numRows()) {
1954 while ($data = $ilDB->fetchAssoc($result)) {
1955 if (!in_array($data['question_fi'], $ids)) { // no duplicates, see #22018
1956 array_push($ids, $data['question_fi']);
1957 }
1958 }
1959 }
1960
1961 return $ids;
1962 }
1963
1971 public static function _getQuestionblock($questionblock_id)
1972 {
1973 global $DIC;
1974
1975 $ilDB = $DIC->database();
1976 $result = $ilDB->queryF(
1977 "SELECT * FROM svy_qblk WHERE questionblock_id = %s",
1978 array('integer'),
1979 array($questionblock_id)
1980 );
1981 $row = $ilDB->fetchAssoc($result);
1982 return $row;
1983 }
1984
1993 public static function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false, $compress_view = false)
1994 {
1995 global $DIC;
1996
1997 $ilDB = $DIC->database();
1998 $next_id = $ilDB->nextId('svy_qblk');
1999 $ilDB->manipulateF(
2000 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
2001 " show_blocktitle, owner_fi, tstamp, compress_view) " .
2002 "VALUES (%s, %s, %s, %s, %s, %s, %s)",
2003 array('integer','text','integer','integer','integer','integer','integer'),
2004 array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time(),$compress_view)
2005 );
2006 return $next_id;
2007 }
2008
2016 public function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions, $compress_view = false)
2017 {
2018 $ilDB = $this->db;
2019
2020 // if the selected questions are not in a continous selection, move all questions of the
2021 // questionblock at the position of the first selected question
2022 $this->moveQuestions($questions, $questions[0], 0);
2023
2024 // now save the question block
2026 $next_id = $ilDB->nextId('svy_qblk');
2027 $affectedRows = $ilDB->manipulateF(
2028 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
2029 " show_blocktitle, owner_fi, tstamp, compress_view) VALUES (%s, %s, %s, %s, %s, %s, %s)",
2030 array('integer','text','text','text','integer','integer','integer'),
2031 array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time(), $compress_view)
2032 );
2033 if ($affectedRows) {
2034 $questionblock_id = $next_id;
2035 foreach ($questions as $index) {
2036 if (!$this->isQuestionInAnyBlock($index)) {
2037 $next_id = $ilDB->nextId('svy_qblk_qst'); // #22018
2038 $affectedRows = $ilDB->manipulateF(
2039 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2040 "question_fi) VALUES (%s, %s, %s, %s)",
2041 array('integer', 'integer', 'integer', 'integer'),
2042 array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2043 );
2044 $this->deleteConstraints($index);
2045 }
2046 }
2047 }
2048 }
2049
2057 public function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle, $compress_view = false)
2058 {
2059 $ilDB = $this->db;
2060 $affectedRows = $ilDB->manipulateF(
2061 "UPDATE svy_qblk SET title = %s, show_questiontext = %s," .
2062 " show_blocktitle = %s, compress_view = %s WHERE questionblock_id = %s",
2063 array('text','text','text','integer', 'integer'),
2064 array($title, $show_questiontext, $show_blocktitle, $compress_view, $questionblock_id)
2065 );
2066 }
2067
2074 public function deleteConstraints($question_id)
2075 {
2076 $ilDB = $this->db;
2077 $result = $ilDB->queryF(
2078 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2079 array('integer','integer'),
2080 array($question_id, $this->getSurveyId())
2081 );
2082 $constraints = array();
2083 while ($row = $ilDB->fetchAssoc($result)) {
2084 array_push($constraints, $row["constraint_fi"]);
2085 }
2086 foreach ($constraints as $constraint_id) {
2087 $this->deleteConstraint($constraint_id);
2088 }
2089 }
2090
2098 public function deleteConstraint($constraint_id)
2099 {
2100 $ilDB = $this->db;
2101 $affectedRows = $ilDB->manipulateF(
2102 "DELETE FROM svy_constraint WHERE constraint_id = %s",
2103 array('integer'),
2104 array($constraint_id)
2105 );
2106 $affectedRows = $ilDB->manipulateF(
2107 "DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2108 array('integer'),
2109 array($constraint_id)
2110 );
2111 }
2112
2118 public function &getSurveyQuestions($with_answers = false)
2119 {
2120 $ilDB = $this->db;
2121 // get questionblocks
2122 $all_questions = array();
2123 $result = $ilDB->queryF(
2124 "SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, " .
2125 "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2126 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2127 "ORDER BY svy_svy_qst.sequence",
2128 array('integer'),
2129 array($this->getSurveyId())
2130 );
2131 while ($row = $ilDB->fetchAssoc($result)) {
2132 $add = true;
2133 if ($row["plugin"]) {
2134 if (!$this->isPluginActive($row["type_tag"])) {
2135 $add = false;
2136 }
2137 }
2138 if ($add) {
2139 $question = self::_instanciateQuestion($row["question_id"]);
2140 $questionrow = $question->getQuestionDataArray($row["question_id"]);
2141 foreach ($row as $key => $value) {
2142 $questionrow[$key] = $value;
2143 }
2144 $all_questions[$row["question_id"]] = $questionrow;
2145 $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2146 $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2147 }
2148 }
2149 // get all questionblocks
2150 $questionblocks = array();
2151 if (count($all_questions)) {
2152 $result = $ilDB->queryF(
2153 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2154 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2155 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2156 array('integer'),
2157 array($this->getSurveyId())
2158 );
2159 while ($row = $ilDB->fetchAssoc($result)) {
2160 $questionblocks[$row['question_fi']] = $row;
2161 }
2162 }
2163
2164 foreach ($all_questions as $question_id => $row) {
2165 $constraints = $this->getConstraints($question_id);
2166 if (isset($questionblocks[$question_id])) {
2167 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2168 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2169 $all_questions[$question_id]["constraints"] = $constraints;
2170 } else {
2171 $all_questions[$question_id]["questionblock_title"] = "";
2172 $all_questions[$question_id]["questionblock_id"] = "";
2173 $all_questions[$question_id]["constraints"] = $constraints;
2174 }
2175 if ($with_answers) {
2176 $answers = array();
2177 $result = $ilDB->queryF(
2178 "SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2179 "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id " .
2180 "ORDER BY sequence ASC",
2181 array('integer'),
2182 array($question_id)
2183 );
2184 if ($result->numRows() > 0) {
2185 while ($data = $ilDB->fetchAssoc($result)) {
2186 array_push($answers, $data["title"]);
2187 }
2188 }
2189 $all_questions[$question_id]["answers"] = $answers;
2190 }
2191 }
2192 return $all_questions;
2193 }
2194
2201 public function setObligatoryStates($obligatory_questions)
2202 {
2203 $ilDB = $this->db;
2204 $result = $ilDB->queryF(
2205 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2206 array('integer'),
2207 array($this->getSurveyId())
2208 );
2209 if ($result->numRows()) {
2210 while ($row = $ilDB->fetchAssoc($result)) {
2211 if (!array_key_exists($row["question_fi"], $obligatory_questions)) {
2212 $obligatory_questions[$row["question_fi"]] = 0;
2213 }
2214 }
2215 }
2216
2217 // set the obligatory states in the database
2218 foreach ($obligatory_questions as $question_fi => $obligatory) {
2219 // #12420
2220 $ilDB->manipulate("UPDATE svy_question" .
2221 " SET obligatory = " . $ilDB->quote($obligatory, "integer") .
2222 " WHERE question_id = " . $ilDB->quote($question_fi, "integer"));
2223 }
2224 }
2225
2231 public function &getSurveyPages()
2232 {
2233 $ilDB = $this->db;
2234 // get questionblocks
2235 $all_questions = array();
2236 $result = $ilDB->queryF(
2237 "SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2238 "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2239 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2240 "ORDER BY svy_svy_qst.sequence",
2241 array('integer'),
2242 array($this->getSurveyId())
2243 );
2244 while ($row = $ilDB->fetchAssoc($result)) {
2245 $all_questions[$row["question_id"]] = $row;
2246 }
2247 // get all questionblocks
2248 $questionblocks = array();
2249 if (count($all_questions)) {
2250 $result = $ilDB->queryF(
2251 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst " .
2252 "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2253 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2254 array('integer'),
2255 array($this->getSurveyId())
2256 );
2257 while ($row = $ilDB->fetchAssoc($result)) {
2258 $questionblocks[$row['question_fi']] = $row;
2259 }
2260 }
2261
2262 $all_pages = array();
2263 $pageindex = -1;
2264 $currentblock = "";
2265 foreach ($all_questions as $question_id => $row) {
2266 $constraints = array();
2267 if (isset($questionblocks[$question_id])) {
2268 if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id'])) {
2269 $pageindex++;
2270 }
2271 $all_questions[$question_id]['page'] = $pageindex;
2272 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2273 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2274 $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2275 $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2276 $all_questions[$question_id]["questionblock_compress_view"] = $questionblocks[$question_id]['compress_view'];
2277 $currentblock = $questionblocks[$question_id]['questionblock_id'];
2278 $constraints = $this->getConstraints($question_id);
2279 $all_questions[$question_id]["constraints"] = $constraints;
2280 } else {
2281 $pageindex++;
2282 $all_questions[$question_id]['page'] = $pageindex;
2283 $all_questions[$question_id]["questionblock_title"] = "";
2284 $all_questions[$question_id]["questionblock_id"] = "";
2285 $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2286 $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2287 $all_questions[$question_id]["questionblock_compress_view"] = false;
2288 $currentblock = "";
2289 $constraints = $this->getConstraints($question_id);
2290 $all_questions[$question_id]["constraints"] = $constraints;
2291 }
2292 if (!isset($all_pages[$pageindex])) {
2293 $all_pages[$pageindex] = array();
2294 }
2295 array_push($all_pages[$pageindex], $all_questions[$question_id]);
2296 }
2297 // calculate position percentage for every page
2298 $max = count($all_pages);
2299 $counter = 1;
2300 foreach ($all_pages as $index => $block) {
2301 foreach ($block as $blockindex => $question) {
2302 $all_pages[$index][$blockindex]["position"] = $counter / $max;
2303 }
2304 $counter++;
2305 }
2306
2307 return $all_pages;
2308 }
2309
2318 public function getNextPage($active_page_question_id, $direction)
2319 {
2320 $foundpage = -1;
2321 $pages = &$this->getSurveyPages();
2322 if (strcmp($active_page_question_id, "") == 0) {
2323 return $pages[0];
2324 }
2325 foreach ($pages as $key => $question_array) {
2326 foreach ($question_array as $question) {
2327 if ($active_page_question_id == $question["question_id"]) {
2328 $foundpage = $key;
2329 }
2330 }
2331 }
2332 if ($foundpage == -1) {
2333 // error: page not found
2334 } else {
2335 $foundpage += $direction;
2336 if ($foundpage < 0) {
2337 return 0;
2338 }
2339 if ($foundpage >= count($pages)) {
2340 return 1;
2341 }
2342 return $pages[$foundpage];
2343 }
2344 }
2345
2352 public function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = false, $permission = "read")
2353 {
2354 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2355 }
2356
2362 public function getPrecondition($id)
2363 {
2364 $ilDB = $this->db;
2365
2366 $result_array = array();
2367 $result = $ilDB->queryF(
2368 "SELECT svy_constraint.*, svy_relation.*, svy_qst_constraint.question_fi ref_question_fi FROM svy_qst_constraint, svy_constraint, " .
2369 "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2370 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2371 array('integer'),
2372 array($id)
2373 );
2374 $pc = array();
2375 if ($result->numRows()) {
2376 $pc = $ilDB->fetchAssoc($result);
2377 }
2378 return $pc;
2379 }
2380
2386 public function getConstraints($question_id)
2387 {
2388 $ilDB = $this->db;
2389
2390 $result_array = array();
2391 $result = $ilDB->queryF(
2392 "SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation " .
2393 "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2394 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s " .
2395 "AND svy_qst_constraint.survey_fi = %s",
2396 array('integer','integer'),
2397 array($question_id, $this->getSurveyId())
2398 );
2399 while ($row = $ilDB->fetchAssoc($result)) {
2400 $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2401 SurveyQuestion::_includeClass($question_type);
2402 $question = new $question_type();
2403 $question->loadFromDb($row["question_fi"]);
2404 $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2405 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));
2406 }
2407 return $result_array;
2408 }
2409
2415 public static function _getConstraints($survey_id)
2416 {
2417 global $DIC;
2418
2419 $ilDB = $DIC->database();
2420 $result_array = array();
2421 $result = $ilDB->queryF(
2422 "SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* " .
2423 "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id " .
2424 "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2425 array('integer'),
2426 array($survey_id)
2427 );
2428 while ($row = $ilDB->fetchAssoc($result)) {
2429 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']));
2430 }
2431 return $result_array;
2432 }
2433
2434
2440 public function &getVariables($question_id)
2441 {
2442 $ilDB = $this->db;
2443
2444 $result_array = array();
2445 $result = $ilDB->queryF(
2446 "SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN " .
2447 "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s " .
2448 "ORDER BY svy_variable.sequence",
2449 array('integer'),
2450 array($question_id)
2451 );
2452 while ($row = $ilDB->fetchObject($result)) {
2453 $result_array[$row->sequence] = $row;
2454 }
2455 return $result_array;
2456 }
2457
2466 public function addConstraint($if_question_id, $relation, $value, $conjunction)
2467 {
2468 $ilDB = $this->db;
2469
2470 $next_id = $ilDB->nextId('svy_constraint');
2471 $affectedRows = $ilDB->manipulateF(
2472 "INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES " .
2473 "(%s, %s, %s, %s, %s)",
2474 array('integer','integer','integer','float', 'integer'),
2475 array($next_id, $if_question_id, $relation, $value, $conjunction)
2476 );
2477 if ($affectedRows) {
2478 return $next_id;
2479 } else {
2480 return null;
2481 }
2482 }
2483
2484
2491 public function addConstraintToQuestion($to_question_id, $constraint_id)
2492 {
2493 $ilDB = $this->db;
2494
2495 $next_id = $ilDB->nextId('svy_qst_constraint');
2496 $affectedRows = $ilDB->manipulateF(
2497 "INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, " .
2498 "constraint_fi) VALUES (%s, %s, %s, %s)",
2499 array('integer','integer','integer','integer'),
2500 array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2501 );
2502 }
2503
2514 public function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2515 {
2516 $ilDB = $this->db;
2517 $affectedRows = $ilDB->manipulateF(
2518 "UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s " .
2519 "WHERE constraint_id = %s",
2520 array('integer','integer','float','integer','integer'),
2521 array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2522 );
2523 }
2524
2525 public function updateConjunctionForQuestions($questions, $conjunction)
2526 {
2527 $ilDB = $this->db;
2528 foreach ($questions as $question_id) {
2529 $affectedRows = $ilDB->manipulateF(
2530 "UPDATE svy_constraint SET conjunction = %s " .
2531 "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2532 array('integer','integer'),
2533 array($conjunction, $question_id)
2534 );
2535 }
2536 }
2537
2543 public function getAllRelations($short_as_key = false)
2544 {
2545 $ilDB = $this->db;
2546
2547 // #7987
2548 $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2549 $custom_order = array_flip($custom_order);
2550
2551 $result_array = array();
2552 $result = $ilDB->query("SELECT * FROM svy_relation");
2553 while ($row = $ilDB->fetchAssoc($result)) {
2554 if ($short_as_key) {
2555 $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2556 } else {
2557 $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2558 }
2559 }
2560
2561 $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2562 foreach ($result_array as $idx => $item) {
2563 unset($result_array[$idx]["order"]);
2564 }
2565
2566 return $result_array;
2567 }
2568
2569
2570
2571
2579 public function deleteWorkingData($question_id, $active_id)
2580 {
2581 $ilDB = $this->db;
2582
2583 $affectedRows = $ilDB->manipulateF(
2584 "DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2585 array('integer','integer'),
2586 array($question_id, $active_id)
2587 );
2588 }
2589
2598 public function loadWorkingData($question_id, $active_id)
2599 {
2600 $ilDB = $this->db;
2601 $result_array = array();
2602 $result = $ilDB->queryF(
2603 "SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2604 array('integer','integer'),
2605 array($question_id, $active_id)
2606 );
2607 if ($result->numRows() >= 1) {
2608 while ($row = $ilDB->fetchAssoc($result)) {
2609 array_push($result_array, $row);
2610 }
2611 return $result_array;
2612 } else {
2613 return $result_array;
2614 }
2615 }
2616
2623 public function startSurvey($user_id, $anonymous_id, $appraisee_id)
2624 {
2625 $ilDB = $this->db;
2626
2627 if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) {
2628 return;
2629 }
2630
2631 if (strcmp($user_id, "") == 0) {
2632 if ($user_id == ANONYMOUS_USER_ID) {
2633 $user_id = 0;
2634 }
2635 }
2636 $next_id = $ilDB->nextId('svy_finished');
2637 $affectedRows = $ilDB->manipulateF(
2638 "INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) " .
2639 "VALUES (%s, %s, %s, %s, %s, %s, %s)",
2640 array('integer','integer','integer','text','text','integer','integer'),
2641 array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
2642 );
2643 return $next_id;
2644 }
2645
2652 public function finishSurvey($finished_id)
2653 {
2654 $ilDB = $this->db;
2655
2656 $ilDB->manipulateF(
2657 "UPDATE svy_finished SET state = %s, tstamp = %s" .
2658 " WHERE survey_fi = %s AND finished_id = %s",
2659 array('text','integer','integer','integer'),
2660 array(1, time(), $this->getSurveyId(), $finished_id)
2661 );
2662
2663 // self eval writes skills on finishing
2664 if ($this->getMode() == ilObjSurvey::MODE_SELF_EVAL) {
2665 $user = $this->getUserDataFromActiveId($finished_id);
2666 $sskill = new ilSurveySkill($this);
2667 $sskill->writeAndAddSelfEvalSkills($user['usr_id']);
2668 }
2669
2670 $this->checkTutorNotification();
2671 }
2672
2680 public function setPage($finished_id, $page_id)
2681 {
2682 $ilDB = $this->db;
2683
2684 $affectedRows = $ilDB->manipulateF(
2685 "UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
2686 array('integer','integer'),
2687 array(($page_id) ? $page_id : 0, $finished_id)
2688 );
2689 }
2690
2696 public function sendNotificationMail($a_user_id, $a_anonymize_id, $a_appr_id)
2697 {
2698 // #12755
2699 $placeholders = array(
2700 "FIRST_NAME" => "firstname",
2701 "LAST_NAME" => "lastname",
2702 "LOGIN" => "login",
2703 // old style
2704 "firstname" => "firstname"
2705 );
2706
2707 //mailaddresses is just text split by commas.
2708 //sendMail can send emails if it gets an user id or an email as first parameter.
2709 $recipients = preg_split('/,/', $this->mailaddresses);
2710 foreach ($recipients as $recipient) {
2711 // #11298
2712 $ntf = new ilSystemNotification();
2713 $ntf->setLangModules(array("survey"));
2714 $ntf->setRefId($this->getRefId());
2715 $ntf->setSubjectLangId('finished_mail_subject');
2716
2717 $messagetext = $this->mailparticipantdata;
2718 if (trim($messagetext)) {
2719 if (!$this->hasAnonymizedResults()) {
2720 $data = ilObjUser::_getUserData(array($a_user_id));
2721 $data = $data[0];
2722 }
2723 foreach ($placeholders as $key => $mapping) {
2724 if ($this->hasAnonymizedResults()) { // #16480
2725 $messagetext = str_replace('[' . $key . ']', '', $messagetext);
2726 } else {
2727 $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
2728 }
2729 }
2730 $ntf->setIntroductionDirect($messagetext);
2731 } else {
2732 $ntf->setIntroductionLangId('survey_notification_finished_introduction');
2733 }
2734
2735 // 360°? add appraisee data
2736 if ($a_appr_id) {
2737 $ntf->addAdditionalInfo(
2738 'survey_360_appraisee',
2740 );
2741 }
2742
2743 $active_id = $this->getActiveID($a_user_id, $a_anonymize_id, $a_appr_id);
2744 $ntf->addAdditionalInfo(
2745 'results',
2746 $this->getParticipantTextResults($active_id),
2747 true
2748 );
2749
2750 $ntf->setGotoLangId('survey_notification_tutor_link');
2751 $ntf->setReasonLangId('survey_notification_finished_reason');
2752
2753 if (is_numeric($recipient)) {
2754 $lng = $ntf->getUserLanguage($recipient);
2755 $ntf->sendMail(array($recipient), null, null);
2756 } else {
2757 $recipient = trim($recipient);
2758 $user_ids = ilObjUser::getUserIdsByEmail($recipient);
2759 if (empty($user_ids)) {
2760 $ntf->sendMail(array($recipient), null, null);
2761 } else {
2762 foreach ($user_ids as $user_id) {
2763 $lng = $ntf->getUserLanguage($user_id);
2764 $ntf->sendMail(array($user_id), null, null);
2765 }
2766 }
2767 }
2768 }
2769 }
2770
2771 protected function getParticipantTextResults($active_id)
2772 {
2773 $textresult = "";
2774 $userResults = &$this->getUserSpecificResults(array($active_id));
2775 $questions = &$this->getSurveyQuestions(true);
2776 $questioncounter = 1;
2777 foreach ($questions as $question_id => $question_data) {
2778 $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
2779 $found = $userResults[$question_id][$active_id];
2780 $text = "";
2781 if (is_array($found)) {
2782 $text = implode("\n", $found);
2783 } else {
2784 $text = $found;
2785 }
2786 if (strlen($text) == 0) {
2788 }
2789 $text = str_replace("<br />", "\n", $text);
2790 $textresult .= $text . "\n\n";
2791 }
2792 return $textresult;
2793 }
2794
2802 public function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
2803 {
2804 $ilDB = $this->db;
2805
2806 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2807 if ($anonymize_id) {
2808 $result = $ilDB->queryF(
2809 "SELECT * FROM svy_finished" .
2810 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2811 array('integer','text','integer'),
2812 array($this->getSurveyId(), $anonymize_id, $appr_id)
2813 );
2814 } else {
2815 $result = $ilDB->queryF(
2816 "SELECT * FROM svy_finished" .
2817 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2818 array('integer','integer','integer'),
2819 array($this->getSurveyId(), $user_id, $appr_id)
2820 );
2821 }
2822 if ($result->numRows() == 0) {
2823 return false;
2824 } else {
2825 $row = $ilDB->fetchAssoc($result);
2826 // yes, we are doing it this way
2827 $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
2828
2829 return (int) $row["state"];
2830 }
2831 }
2832
2840 public function getActiveID($user_id, $anonymize_id, $appr_id)
2841 {
2842 $ilDB = $this->db;
2843
2844 // see self::isSurveyStarted()
2845
2846 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2847 if ($anonymize_id) {
2848 $result = $ilDB->queryF(
2849 "SELECT finished_id FROM svy_finished" .
2850 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2851 array('integer','text','integer'),
2852 array($this->getSurveyId(), $anonymize_id, $appr_id)
2853 );
2854 } else {
2855 $result = $ilDB->queryF(
2856 "SELECT finished_id FROM svy_finished" .
2857 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2858 array('integer','integer','integer'),
2859 array($this->getSurveyId(), $user_id, $appr_id)
2860 );
2861 }
2862 if ($result->numRows() == 0) {
2863 return false;
2864 } else {
2865 $row = $ilDB->fetchAssoc($result);
2866 return $row["finished_id"];
2867 }
2868 }
2869
2877 public function getLastActivePage($active_id)
2878 {
2879 $ilDB = $this->db;
2880 $result = $ilDB->queryF(
2881 "SELECT lastpage FROM svy_finished WHERE finished_id = %s",
2882 array('integer'),
2883 array($active_id)
2884 );
2885 if ($result->numRows() == 0) {
2886 return "";
2887 } else {
2888 $row = $ilDB->fetchAssoc($result);
2889 return ($row["lastpage"]) ? $row["lastpage"] : '';
2890 }
2891 }
2892
2901 public function checkConstraint($constraint_data, $working_data)
2902 {
2903 if (!is_array($working_data) || count($working_data) == 0) {
2904 return 0;
2905 }
2906
2907 if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0)) {
2908 return 0;
2909 }
2910
2911 $found = false;
2912 foreach ($working_data as $data) {
2913 switch ($constraint_data["short"]) {
2914 case "<":
2915 if ($data["value"] < $constraint_data["value"]) {
2916 $found = true;
2917 }
2918 break;
2919
2920 case "<=":
2921 if ($data["value"] <= $constraint_data["value"]) {
2922 $found = true;
2923 }
2924 break;
2925
2926 case "=":
2927 if ($data["value"] == $constraint_data["value"]) {
2928 $found = true;
2929 }
2930 break;
2931
2932 case "<>":
2933 if ($data["value"] <> $constraint_data["value"]) {
2934 $found = true;
2935 }
2936 break;
2937
2938 case ">=":
2939 if ($data["value"] >= $constraint_data["value"]) {
2940 $found = true;
2941 }
2942 break;
2943
2944 case ">":
2945 if ($data["value"] > $constraint_data["value"]) {
2946 $found = true;
2947 }
2948 break;
2949 }
2950 if ($found) {
2951 break;
2952 }
2953 }
2954
2955 return (int) $found;
2956 }
2957
2958 public static function _hasDatasets($survey_id)
2959 {
2960 global $DIC;
2961
2962 $ilDB = $DIC->database();
2963
2964 $result = $ilDB->queryF(
2965 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
2966 array('integer'),
2967 array($survey_id)
2968 );
2969 return ($result->numRows()) ? true : false;
2970 }
2971
2978 public function &getSurveyFinishedIds()
2979 {
2980 $ilDB = $this->db;
2981 $ilLog = $this->svy_log;
2982
2983 $users = array();
2984 $result = $ilDB->queryF(
2985 "SELECT * FROM svy_finished WHERE survey_fi = %s",
2986 array('integer'),
2987 array($this->getSurveyId())
2988 );
2989 if ($result->numRows()) {
2990 while ($row = $ilDB->fetchAssoc($result)) {
2991 array_push($users, $row["finished_id"]);
2992 }
2993 }
2994 return $users;
2995 }
2996
3003 public function getUserSpecificResults($finished_ids)
3004 {
3005 $evaluation = array();
3006
3007 foreach (array_keys($this->getSurveyQuestions()) as $question_id) {
3008 // get question instance
3009 $question_type = SurveyQuestion::_getQuestionType($question_id);
3010 SurveyQuestion::_includeClass($question_type);
3011 $question = new $question_type();
3012 $question->loadFromDb($question_id);
3013
3014 $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($question_id, $finished_ids);
3015 $q_res = $q_eval->getResults();
3016
3017 $data = array();
3018 foreach ($finished_ids as $user_id) {
3019 $data[$user_id] = $q_eval->parseUserSpecificResults($q_res, $user_id);
3020 }
3021
3022 $evaluation[$question_id] = $data;
3023 }
3024
3025 return $evaluation;
3026 }
3027
3035 public function getUserDataFromActiveId($active_id, $force_non_anonymous = false)
3036 {
3037 $ilDB = $this->db;
3038
3039 $surveySetting = new ilSetting("survey");
3040 $use_anonymous_id = $surveySetting->get("use_anonymous_id");
3041 $result = $ilDB->queryF(
3042 "SELECT * FROM svy_finished WHERE finished_id = %s",
3043 array('integer'),
3044 array($active_id)
3045 );
3046 $row = array();
3047 $foundrows = $result->numRows();
3048 if ($foundrows) {
3049 $row = $ilDB->fetchAssoc($result);
3050 }
3051 $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3052 $userdata = array(
3053 "fullname" => $name,
3054 "sortname" => $name,
3055 "firstname" => "",
3056 "lastname" => "",
3057 "login" => "",
3058 "gender" => "",
3059 "active_id" => "$active_id"
3060 );
3061 if ($foundrows) {
3062 if (($row["user_fi"] > 0) &&
3063 (($row["user_fi"] != ANONYMOUS_USER_ID &&
3064 !$this->hasAnonymizedResults() &&
3065 !$this->get360Mode()) || // 360° uses ANONYMIZE_CODE_ALL which is wrong - see ilObjSurveyGUI::afterSave()
3066 (bool) $force_non_anonymous)) {
3067 if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0) {
3068 $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3069 } else {
3070 $user = new ilObjUser($row["user_fi"]);
3071 $userdata['usr_id'] = $row['user_fi'];
3072 $userdata["fullname"] = $user->getFullname();
3073 $gender = $user->getGender();
3074 if (strlen($gender) == 1) {
3075 $gender = $this->lng->txt("gender_$gender");
3076 }
3077 $userdata["gender"] = $gender;
3078 $userdata["firstname"] = $user->getFirstname();
3079 $userdata["lastname"] = $user->getLastname();
3080 $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3081 $userdata["login"] = $user->getLogin();
3082 }
3083 }
3084 }
3085 return $userdata;
3086 }
3087
3097 public function &getEvaluationByUser($questions, $active_id)
3098 {
3099 $ilDB = $this->db;
3100
3101 // collect all answers
3102 $answers = array();
3103 $result = $ilDB->queryF(
3104 "SELECT * FROM svy_answer WHERE active_fi = %s",
3105 array('integer'),
3106 array($active_id)
3107 );
3108 while ($row = $ilDB->fetchAssoc($result)) {
3109 if (!is_array($answers[$row["question_fi"]])) {
3110 $answers[$row["question_fi"]] = array();
3111 }
3112 array_push($answers[$row["question_fi"]], $row);
3113 }
3114 $userdata = $this->getUserDataFromActiveId($active_id);
3115 $resultset = array(
3116 "name" => $userdata["fullname"],
3117 "firstname" => $userdata["firstname"],
3118 "lastname" => $userdata["lastname"],
3119 "login" => $userdata["login"],
3120 "gender" => $userdata["gender"],
3121 "answers" => array()
3122 );
3123 foreach ($questions as $key => $question) {
3124 if (array_key_exists($key, $answers)) {
3125 $resultset["answers"][$key] = $answers[$key];
3126 } else {
3127 $resultset["answers"][$key] = array();
3128 }
3129 sort($resultset["answers"][$key]);
3130 }
3131 return $resultset;
3132 }
3133
3139 public function getQuestionsTable($arrFilter)
3140 {
3142 $ilDB = $this->db;
3143 $where = "";
3144 if (is_array($arrFilter)) {
3145 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3146 $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3147 }
3148 if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description'])) {
3149 $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3150 }
3151 if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author'])) {
3152 $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3153 }
3154 if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type'])) {
3155 $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3156 }
3157 if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl'])) {
3158 $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3159 }
3160 }
3161
3162 $spls = &$this->getAvailableQuestionpools($use_obj_id = true, $could_be_offline = false, $showPath = false);
3163 $forbidden = "";
3164 $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3165 $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3166 $existing = "";
3167 $existing_questions = &$this->getExistingQuestions();
3168 if (count($existing_questions)) {
3169 $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3170 }
3171
3173
3174 $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id" .
3175 " FROM svy_question, svy_qtype, object_reference" .
3176 " WHERE svy_question.original_id IS NULL" . $forbidden . $existing .
3177 " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0" .
3178 " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3179
3180 $rows = array();
3181 if ($query_result->numRows()) {
3182 while ($row = $ilDB->fetchAssoc($query_result)) {
3183 if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt'])) {
3184 if (!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt'])) {
3185 continue;
3186 }
3187 }
3188
3189 $row['ttype'] = $trans[$row['type_tag']];
3190 if ($row["plugin"]) {
3191 if ($this->isPluginActive($row["type_tag"])) {
3192 array_push($rows, $row);
3193 }
3194 } else {
3195 array_push($rows, $row);
3196 }
3197 }
3198 }
3199 return $rows;
3200 }
3201
3207 public function getQuestionblocksTable($arrFilter)
3208 {
3210 $ilDB = $this->db;
3211
3212 $where = "";
3213 if (is_array($arrFilter)) {
3214 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3215 $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3216 }
3217 }
3218
3219 $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE " .
3220 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi " .
3221 "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, " .
3222 "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3223 $rows = array();
3224 if ($query_result->numRows()) {
3225 $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3226 $surveytitles = array();
3227 foreach ($survey_ref_ids as $survey_ref_id) {
3228 $survey_id = ilObject::_lookupObjId($survey_ref_id);
3230 }
3231 while ($row = $ilDB->fetchAssoc($query_result)) {
3232 $questions_array = &$this->getQuestionblockQuestions($row["questionblock_id"]);
3233 $counter = 1;
3234 foreach ($questions_array as $key => $value) {
3235 $questions_array[$key] = "$counter. $value";
3236 $counter++;
3237 }
3238 if (strlen($surveytitles[$row["obj_fi"]])) { // only questionpools which are not in trash
3239 $rows[$row["questionblock_id"]] = array(
3240 "questionblock_id" => $row["questionblock_id"],
3241 "title" => $row["title"],
3242 "svy" => $surveytitles[$row["obj_fi"]],
3243 "contains" => join(", ", $questions_array),
3244 "owner" => $row["owner_fi"]
3245 );
3246 }
3247 }
3248 }
3249 return $rows;
3250 }
3251
3258 public function toXML()
3259 {
3260 $a_xml_writer = new ilXmlWriter;
3261 // set xml header
3262 $a_xml_writer->xmlHeader();
3263 $attrs = array(
3264 "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3265 "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3266 );
3267 $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3268 $attrs = array(
3269 "id" => $this->getSurveyId(),
3270 "title" => $this->getTitle()
3271 );
3272 $a_xml_writer->xmlStartTag("survey", $attrs);
3273
3274 $a_xml_writer->xmlElement("description", null, $this->getDescription());
3275 $a_xml_writer->xmlElement("author", null, $this->getAuthor());
3276 $a_xml_writer->xmlStartTag("objectives");
3277 $attrs = array(
3278 "label" => "introduction"
3279 );
3280 $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), true, true, $attrs);
3281 $attrs = array(
3282 "label" => "outro"
3283 );
3284 $this->addMaterialTag($a_xml_writer, $this->getOutro(), true, true, $attrs);
3285 $a_xml_writer->xmlEndTag("objectives");
3286
3287 if ($this->getAnonymize()) {
3288 $attribs = array("enabled" => "1");
3289 } else {
3290 $attribs = array("enabled" => "0");
3291 }
3292 $a_xml_writer->xmlElement("anonymisation", $attribs);
3293 $a_xml_writer->xmlStartTag("restrictions");
3294 if ($this->getAnonymize() == 2) {
3295 $attribs = array("type" => "free");
3296 } else {
3297 $attribs = array("type" => "restricted");
3298 }
3299 $a_xml_writer->xmlElement("access", $attribs);
3300 if ($this->getStartDate()) {
3301 $attrs = array("type" => "date");
3302 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3303 $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]));
3304 }
3305 if ($this->getEndDate()) {
3306 $attrs = array("type" => "date");
3307 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3308 $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]));
3309 }
3310 $a_xml_writer->xmlEndTag("restrictions");
3311
3312 // constraints
3313 $pages = &$this->getSurveyPages();
3314 $hasconstraints = false;
3315 foreach ($pages as $question_array) {
3316 foreach ($question_array as $question) {
3317 if (count($question["constraints"])) {
3318 $hasconstraints = true;
3319 }
3320 }
3321 }
3322
3323 if ($hasconstraints) {
3324 $a_xml_writer->xmlStartTag("constraints");
3325 foreach ($pages as $question_array) {
3326 foreach ($question_array as $question) {
3327 if (count($question["constraints"])) {
3328 // found constraints
3329 foreach ($question["constraints"] as $constraint) {
3330 $attribs = array(
3331 "sourceref" => $question["question_id"],
3332 "destref" => $constraint["question"],
3333 "relation" => $constraint["short"],
3334 "value" => $constraint["value"],
3335 "conjunction" => $constraint["conjunction"]
3336 );
3337 $a_xml_writer->xmlElement("constraint", $attribs);
3338 }
3339 }
3340 }
3341 }
3342 $a_xml_writer->xmlEndTag("constraints");
3343 }
3344
3345 // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
3346 $a_xml_writer->xmlStartTag("metadata");
3347
3348 $custom_properties = array();
3349 $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
3350 $custom_properties["status"] = !$this->getOfflineStatus();
3351 $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
3352 $custom_properties["pool_usage"] = (int) $this->getPoolUsage();
3353
3354 $custom_properties["own_results_view"] = (int) $this->hasViewOwnResults();
3355 $custom_properties["own_results_mail"] = (int) $this->hasMailOwnResults();
3356 $custom_properties["confirmation_mail"] = (int) $this->hasMailConfirmation();
3357
3358 $custom_properties["anon_user_list"] = (int) $this->hasAnonymousUserList();
3359 $custom_properties["mode"] = (int) $this->getMode();
3360 $custom_properties["mode_360_self_eval"] = (int) $this->get360SelfEvaluation();
3361 $custom_properties["mode_360_self_rate"] = (int) $this->get360SelfRaters();
3362 $custom_properties["mode_360_self_appr"] = (int) $this->get360SelfAppraisee();
3363 $custom_properties["mode_360_results"] = $this->get360Results();
3364 $custom_properties["mode_skill_service"] = (int) $this->getSkillService();
3365 $custom_properties["mode_self_eval_results"] = (int) $this->getSelfEvaluationResults();
3366
3367
3368 // :TODO: skills?
3369
3370 // reminder/tutor notification are (currently?) not exportable
3371
3372 foreach ($custom_properties as $label => $value) {
3373 $a_xml_writer->xmlStartTag("metadatafield");
3374 $a_xml_writer->xmlElement("fieldlabel", null, $label);
3375 $a_xml_writer->xmlElement("fieldentry", null, $value);
3376 $a_xml_writer->xmlEndTag("metadatafield");
3377 }
3378
3379 $a_xml_writer->xmlStartTag("metadatafield");
3380 $a_xml_writer->xmlElement("fieldlabel", null, "SCORM");
3381 $md = new ilMD($this->getId(), 0, $this->getType());
3382 $writer = new ilXmlWriter();
3383 $md->toXml($writer);
3384 $metadata = $writer->xmlDumpMem();
3385 $a_xml_writer->xmlElement("fieldentry", null, $metadata);
3386 $a_xml_writer->xmlEndTag("metadatafield");
3387
3388 $a_xml_writer->xmlEndTag("metadata");
3389 $a_xml_writer->xmlEndTag("survey");
3390
3391 $attribs = array("id" => $this->getId());
3392 $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
3393 // add questionblock descriptions
3394 foreach ($pages as $question_array) {
3395 if (count($question_array) > 1) {
3396 $attribs = array("id" => $question_array[0]["question_id"]);
3397 $attribs = array(
3398 "showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
3399 "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"],
3400 "compressView" => $question_array[0]["questionblock_compress_view"]
3401 );
3402 $a_xml_writer->xmlStartTag("questionblock", $attribs);
3403 if (strlen($question_array[0]["questionblock_title"])) {
3404 $a_xml_writer->xmlElement("questionblocktitle", null, $question_array[0]["questionblock_title"]);
3405 }
3406 }
3407 foreach ($question_array as $question) {
3408 if (strlen($question["heading"])) {
3409 $a_xml_writer->xmlElement("textblock", null, $question["heading"]);
3410 }
3411 $questionObject = self::_instanciateQuestion($question["question_id"]);
3412 //questionObject contains all the fields from the database. (loadFromDb)
3413 //we don't need the value from svy_qst_oblig table, we already have the values from svy_question table.
3414 //if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
3415 if ($questionObject !== false) {
3416 $questionObject->insertXML($a_xml_writer, false);
3417 }
3418 }
3419 if (count($question_array) > 1) {
3420 $a_xml_writer->xmlEndTag("questionblock");
3421 }
3422 }
3423
3424 $a_xml_writer->xmlEndTag("surveyquestions");
3425 $a_xml_writer->xmlEndTag("surveyobject");
3426 $xml = $a_xml_writer->xmlDumpMem(false);
3427 return $xml;
3428 }
3429
3437 public static function _instanciateQuestion($question_id)
3438 {
3439 if ($question_id < 1) {
3440 return false;
3441 }
3442 $question_type = SurveyQuestion::_getQuestionType($question_id);
3443 if (strlen($question_type) == 0) {
3444 return false;
3445 }
3446 SurveyQuestion::_includeClass($question_type);
3447 $question = new $question_type();
3448 $question->loadFromDb($question_id);
3449 return $question;
3450 }
3451
3458 public function locateImportFiles($a_dir)
3459 {
3460 if (!is_dir($a_dir) || is_int(strpos($a_dir, ".."))) {
3461 return;
3462 }
3463 $importDirectory = "";
3464 $xmlFile = "";
3465
3466 $current_dir = opendir($a_dir);
3467 $files = array();
3468 while ($entryname = readdir($current_dir)) {
3469 $files[] = $entryname;
3470 }
3471
3472 foreach ($files as $file) {
3473 if (is_dir($a_dir . "/" . $file) and ($file != "." and $file != "..")) {
3474 // found directory created by zip
3475 $importDirectory = $a_dir . "/" . $file;
3476 }
3477 }
3478 closedir($current_dir);
3479 if (strlen($importDirectory)) {
3480 // find the xml file
3481 $current_dir = opendir($importDirectory);
3482 $files = array();
3483 while ($entryname = readdir($current_dir)) {
3484 $files[] = $entryname;
3485 }
3486 foreach ($files as $file) {
3487 if (@is_file($importDirectory . "/" . $file) &&
3488 ($file != "." && $file != "..") &&
3489 (preg_match("/^[0-9]{10}__[0-9]+__(svy_)*[0-9]+\.[A-Za-z]{1,3}$/", $file) ||
3490 preg_match("/^[0-9]{10}__[0-9]+__(survey__)*[0-9]+\.[A-Za-z]{1,3}$/", $file))) {
3491 // found xml file
3492 $xmlFile = $importDirectory . "/" . $file;
3493 }
3494 }
3495 }
3496 return array("dir" => $importDirectory, "xml" => $xmlFile);
3497 }
3498
3507 public function importObject($file_info, $svy_qpl_id)
3508 {
3509 if ($svy_qpl_id < 1) {
3510 $svy_qpl_id = -1;
3511 }
3512 // check if file was uploaded
3513 $source = $file_info["tmp_name"];
3514 $error = "";
3515 if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK) {
3516 $error = $this->lng->txt("import_no_file_selected");
3517 }
3518 // check correct file type
3519 $isXml = false;
3520 $isZip = false;
3521 if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0)) {
3522 $this->svy_log->debug("isXML");
3523 $isXml = true;
3524 }
3525 // too many different mime-types, so we use the suffix
3526 $suffix = pathinfo($file_info["name"]);
3527 if (strcmp(strtolower($suffix["extension"]), "zip") == 0) {
3528 $this->svy_log->debug("isZip");
3529 $isZip = true;
3530 }
3531 if (!$isXml && !$isZip) {
3532 $error = $this->lng->txt("import_wrong_file_type");
3533 $this->svy_log->debug("Survey: Import error. Filetype was \"" . $file_info["type"] . "\"");
3534 }
3535 if (strlen($error) == 0) {
3536 // import file as a survey
3537 $import_dir = $this->getImportDirectory();
3538 $import_subdir = "";
3539 $importfile = "";
3540 if ($isZip) {
3541 $importfile = $import_dir . "/" . $file_info["name"];
3542 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3543 ilUtil::unzip($importfile);
3544 $found = $this->locateImportFiles($import_dir);
3545 if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0))) {
3546 $error = $this->lng->txt("wrong_import_file_structure");
3547 return $error;
3548 }
3549 $importfile = $found["xml"];
3550 $import_subdir = $found["dir"];
3551 } else {
3552 $importfile = tempnam($import_dir, "survey_import");
3553 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3554 }
3555
3556 $this->svy_log->debug("Import file = $importfile");
3557 $this->svy_log->debug("Import subdir = $import_subdir");
3558
3559 $fh = fopen($importfile, "r");
3560 if (!$fh) {
3561 $error = $this->lng->txt("import_error_opening_file");
3562 return $error;
3563 }
3564 $xml = fread($fh, filesize($importfile));
3565 $result = fclose($fh);
3566 if (!$result) {
3567 $error = $this->lng->txt("import_error_closing_file");
3568 return $error;
3569 }
3570
3571 unset($_SESSION["import_mob_xhtml"]);
3572 if (strpos($xml, "questestinterop")) {
3573 throw new ilInvalidSurveyImportFileException("Unsupported survey version (< 3.8) found.");
3574 } else {
3575 $this->svy_log->debug("survey id = " . $this->getId());
3576 $this->svy_log->debug("question pool id = " . $svy_qpl_id);
3577
3578 $imp = new ilImport();
3579 $config = $imp->getConfig("Modules/Survey");
3580 $config->setQuestionPoolID($svy_qpl_id);
3581 $imp->getMapping()->addMapping("Modules/Survey", "svy", 0, $this->getId());
3582 $imp->importFromDirectory($import_subdir, "svy", "Modules/Survey");
3583 $this->svy_log->debug("config(Modules/survey)->getQuestionPoolId =" . $config->getQuestionPoolID());
3584 return "";
3585
3586 //old code
3587 $import = new SurveyImportParser($svy_qpl_id, "", true);
3588 $import->setSurveyObject($this);
3589 $import->setXMLContent($xml);
3590 $import->startParsing();
3591 }
3592
3593 if (is_array($_SESSION["import_mob_xhtml"])) {
3594 foreach ($_SESSION["import_mob_xhtml"] as $mob) {
3595 $importfile = $import_subdir . "/" . $mob["uri"];
3596 if (file_exists($importfile)) {
3597 if (!$mob["type"]) {
3598 $mob["type"] = "svy:html";
3599 }
3600
3601 $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, false);
3602
3603 // survey mob
3604 if ($mob["type"] == "svy:html") {
3605 ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
3606 $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
3607 $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
3608 }
3609 // question mob
3610 elseif ($import->questions[$mob["id"]]) {
3611 $new_qid = $import->questions[$mob["id"]];
3612 ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
3613 $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
3614 $qtext = $new_question->getQuestiontext();
3615 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
3616 $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
3617 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
3618 $new_question->setQuestiontext($qtext);
3619 $new_question->saveToDb();
3620
3621 // also fix existing original in pool
3622 if ($new_question->getOriginalId()) {
3623 $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
3624 $pool_question->setQuestiontext($qtext);
3625 $pool_question->saveToDb();
3626 }
3627 }
3628 } else {
3629 $ilLog = $this->svy_log;
3630 $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
3631 }
3632 }
3635 $this->saveToDb();
3636 }
3637
3638 // delete import directory
3640 }
3641 return $error;
3642 }
3643
3652 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
3653 {
3654 $ilDB = $this->db;
3655
3656 $this->loadFromDb();
3657
3658 //survey mode
3659 $svy_type = $this->getMode();
3660
3661 // Copy settings
3662 $newObj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
3663 $this->cloneMetaData($newObj);
3664 $newObj->updateMetaData();
3665
3666 $newObj->setAuthor($this->getAuthor());
3667 $newObj->setIntroduction($this->getIntroduction());
3668 $newObj->setOutro($this->getOutro());
3669 $newObj->setEvaluationAccess($this->getEvaluationAccess());
3670 $newObj->setStartDate($this->getStartDate());
3671 $newObj->setEndDate($this->getEndDate());
3672 $newObj->setAnonymize($this->getAnonymize());
3673 $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
3674 $newObj->setTemplate($this->getTemplate());
3675 $newObj->setPoolUsage($this->getPoolUsage());
3676 $newObj->setViewOwnResults($this->hasViewOwnResults());
3677 $newObj->setMailOwnResults($this->hasMailOwnResults());
3678 $newObj->setMailConfirmation($this->hasMailConfirmation());
3679 $newObj->setAnonymousUserList($this->hasAnonymousUserList());
3680
3681 // #12661
3682 if ($this->get360Mode()) {
3683 $newObj->setMode(ilObjSurvey::MODE_360);
3684 $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
3685 $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
3686 $newObj->set360SelfRaters($this->get360SelfRaters());
3687 $newObj->set360Results($this->get360Results());
3688 $newObj->setSkillService($this->getSkillService());
3689 }
3690 //svy mode self eval: skills + view results
3691 if ($svy_type == ilObjSurvey::MODE_SELF_EVAL) {
3692 $newObj->setMode(ilObjSurvey::MODE_SELF_EVAL);
3693 $newObj->setSkillService($this->getSkillService());
3694 $newObj->setSelfEvaluationResults($this->getSelfEvaluationResults());
3695 }
3696
3697 // reminder/notification
3698 $newObj->setReminderStatus($this->getReminderStatus());
3699 $newObj->setReminderStart($this->getReminderStart());
3700 $newObj->setReminderEnd($this->getReminderEnd());
3701 $newObj->setReminderFrequency($this->getReminderFrequency());
3702 $newObj->setReminderTarget($this->getReminderTarget());
3703 $newObj->setReminderTemplate($this->getReminderTemplate());
3704 // reminder_last_sent must not be copied!
3705 $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
3706 $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
3707 $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
3708 $newObj->setTutorResultsStatus($this->getTutorResultsStatus());
3709 $newObj->setTutorResultsRecipients($this->getTutorResultsRecipients());
3710
3711 $newObj->setMailNotification($this->getMailNotification());
3712 $newObj->setMailAddresses($this->getMailAddresses());
3713 $newObj->setMailParticipantData($this->getMailParticipantData());
3714
3715 $question_pointer = array();
3716 // clone the questions
3717 $mapping = array();
3718
3719 foreach ($this->questions as $key => $question_id) {
3721 $question = self::_instanciateQuestion($question_id);
3722 if ($question) { // #10824
3723 $question->id = -1;
3724 $original_id = SurveyQuestion::_getOriginalId($question_id, false);
3725 $question->setObjId($newObj->getId());
3726 $question->saveToDb($original_id);
3727 $newObj->questions[$key] = $question->getId();
3728 $question_pointer[$question_id] = $question->getId();
3729 $mapping[$question_id] = $question->getId();
3730 }
3731 }
3732
3733 //copy online status if object is not the root copy object
3734 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
3735
3736 if (!$cp_options->isRootNode($this->getRefId())) {
3737 $newObj->setOfflineStatus($this->getOfflineStatus());
3738 }
3739
3740 $newObj->saveToDb();
3741 $newObj->cloneTextblocks($mapping);
3742
3743 // #14929
3744 if (($svy_type == ilObjSurvey::MODE_360 || $svy_type == ilObjSurvey::MODE_SELF_EVAL) &&
3745 $this->getSkillService()) {
3746 $src_skills = new ilSurveySkill($this);
3747 $tgt_skills = new ilSurveySkill($newObj);
3748
3749 foreach ($mapping as $src_qst_id => $tgt_qst_id) {
3750 $qst_skill = $src_skills->getSkillForQuestion($src_qst_id);
3751 if ($qst_skill) {
3752 $tgt_skills->addQuestionSkillAssignment($tgt_qst_id, $qst_skill["base_skill_id"], $qst_skill["tref_id"]);
3753 }
3754 }
3755
3756 $thresholds = new ilSurveySkillThresholds($this);
3757 $thresholds->cloneTo($newObj, $mapping);
3758 }
3759
3760 // clone the questionblocks
3761 $questionblocks = array();
3762 $questionblock_questions = array();
3763 $result = $ilDB->queryF(
3764 "SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
3765 array('integer'),
3766 array($this->getSurveyId())
3767 );
3768 if ($result->numRows() > 0) {
3769 while ($row = $ilDB->fetchAssoc($result)) {
3770 array_push($questionblock_questions, $row);
3771 $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
3772 }
3773 }
3774 // create new questionblocks
3775 foreach ($questionblocks as $key => $value) {
3776 $questionblock = self::_getQuestionblock($key);
3777 $questionblock_id = self::_addQuestionblock(
3778 $questionblock["title"],
3779 $questionblock["owner_fi"],
3780 $questionblock["show_questiontext"],
3781 $questionblock["show_blocktitle"],
3782 $questionblock["compress_view"]
3783 );
3784 $questionblocks[$key] = $questionblock_id;
3785 }
3786 // create new questionblock questions
3787 foreach ($questionblock_questions as $key => $value) {
3788 if ($questionblocks[$value["questionblock_fi"]] &&
3789 $question_pointer[$value["question_fi"]]) {
3790 $next_id = $ilDB->nextId('svy_qblk_qst');
3791 $affectedRows = $ilDB->manipulateF(
3792 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) " .
3793 "VALUES (%s, %s, %s, %s)",
3794 array('integer','integer','integer','integer'),
3795 array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
3796 );
3797 }
3798 }
3799
3800 // clone the constraints
3801 $constraints = self::_getConstraints($this->getSurveyId());
3802 $newConstraints = array();
3803 foreach ($constraints as $key => $constraint) {
3804 if ($question_pointer[$constraint["for_question"]] &&
3805 $question_pointer[$constraint["question"]]) {
3806 if (!array_key_exists($constraint['id'], $newConstraints)) {
3807 $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
3808 $newConstraints[$constraint['id']] = $constraint_id;
3809 }
3810 $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
3811 }
3812 }
3813
3814 // #16210 - clone LP settings
3815 $obj_settings = new ilLPObjSettings($this->getId());
3816 $obj_settings->cloneSettings($newObj->getId());
3817 unset($obj_settings);
3818
3819 return $newObj;
3820 }
3821
3822 public function getTextblock($question_id)
3823 {
3824 $ilDB = $this->db;
3825 $result = $ilDB->queryF(
3826 "SELECT * FROM svy_svy_qst WHERE question_fi = %s",
3827 array('integer'),
3828 array($question_id)
3829 );
3830 if ($result->numRows()) {
3831 $row = $ilDB->fetchAssoc($result);
3832 return $row["heading"];
3833 } else {
3834 return "";
3835 }
3836 }
3837
3843 public function cloneTextblocks($mapping)
3844 {
3845 foreach ($mapping as $original_id => $new_id) {
3846 $textblock = $this->getTextblock($original_id);
3847 $this->saveHeading(ilUtil::stripSlashes($textblock, true, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
3848 }
3849 }
3850
3858 public function createExportDirectory()
3859 {
3860 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
3861 ilUtil::makeDir($svy_data_dir);
3862 if (!is_writable($svy_data_dir)) {
3863 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
3864 }
3865
3866 // create learning module directory (data_dir/lm_data/lm_<id>)
3867 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
3868 ilUtil::makeDir($svy_dir);
3869 if (!@is_dir($svy_dir)) {
3870 throw new ilSurveyException("Creation of Survey Directory failed.");
3871 }
3872 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
3873 $export_dir = $svy_dir . "/export";
3874 ilUtil::makeDir($export_dir);
3875 if (!@is_dir($export_dir)) {
3876 throw new ilSurveyException("Creation of Export Directory failed.");
3877 }
3878 }
3879
3883 public function getExportDirectory()
3884 {
3885 $export_dir = ilUtil::getDataDir() . "/svy_data" . "/svy_" . $this->getId() . "/export";
3886
3887 return $export_dir;
3888 }
3889
3897 public function createImportDirectory()
3898 {
3899 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
3900 ilUtil::makeDir($svy_data_dir);
3901
3902 if (!is_writable($svy_data_dir)) {
3903 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
3904 }
3905
3906 // create test directory (data_dir/svy_data/svy_<id>)
3907 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
3908 ilUtil::makeDir($svy_dir);
3909 if (!@is_dir($svy_dir)) {
3910 throw new ilSurveyException("Creation of Survey Directory failed.");
3911 }
3912
3913 // create import subdirectory (data_dir/svy_data/svy_<id>/import)
3914 $import_dir = $svy_dir . "/import";
3915 ilUtil::makeDir($import_dir);
3916 if (!@is_dir($import_dir)) {
3917 throw new ilSurveyException("Creation of Import Directory failed.");
3918 }
3919 }
3920
3924 public function getImportDirectory()
3925 {
3926 $import_dir = ilUtil::getDataDir() . "/svy_data" .
3927 "/svy_" . $this->getId() . "/import";
3928 if (!is_dir($import_dir)) {
3929 ilUtil::makeDirParents($import_dir);
3930 }
3931 if (@is_dir($import_dir)) {
3932 return $import_dir;
3933 } else {
3934 return false;
3935 }
3936 }
3937
3938 public function saveHeading($heading = "", $insertbefore)
3939 {
3940 $ilDB = $this->db;
3941 if ($heading) {
3942 $affectedRows = $ilDB->manipulateF(
3943 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
3944 array('text','integer','integer'),
3945 array($heading, $this->getSurveyId(), $insertbefore)
3946 );
3947 } else {
3948 $affectedRows = $ilDB->manipulateF(
3949 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
3950 array('text','integer','integer'),
3951 array(null, $this->getSurveyId(), $insertbefore)
3952 );
3953 }
3954 }
3955
3956 public function isAnonymousKey($key)
3957 {
3958 $ilDB = $this->db;
3959
3960 $result = $ilDB->queryF(
3961 "SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
3962 array('text','integer'),
3963 array($key, $this->getSurveyId())
3964 );
3965 return ($result->numRows() == 1) ? true : false;
3966 }
3967
3968 public function bindSurveyCodeToUser($user_id, $code)
3969 {
3970 $ilDB = $this->db;
3971
3972 if ($user_id == ANONYMOUS_USER_ID) {
3973 return;
3974 }
3975
3976 if ($this->checkSurveyCode($code)) {
3977 $ilDB->manipulate("UPDATE svy_anonymous" .
3978 " SET user_key = " . $ilDB->quote(md5($user_id), "text") .
3979 " WHERE survey_key = " . $ilDB->quote($code, "text"));
3980 }
3981 }
3982
3983 public function isAnonymizedParticipant($key)
3984 {
3985 $ilDB = $this->db;
3986
3987 $result = $ilDB->queryF(
3988 "SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
3989 array('text','integer'),
3990 array($key, $this->getSurveyId())
3991 );
3992 return ($result->numRows() == 1) ? true : false;
3993 }
3994
3995 public function checkSurveyCode($code)
3996 {
3997 if ($this->isAnonymousKey($code)) {
3998 if ($this->isSurveyStarted("", $code) == 1) {
3999 return false;
4000 } else {
4001 return true;
4002 }
4003 } else {
4004 return false;
4005 }
4006 }
4007
4015 public function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
4016 {
4017 $ilDB = $this->db;
4019 $lng = $this->lng;
4020
4021 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4022 " FROM svy_anonymous" .
4023 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4024 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
4025 " AND svy_anonymous.user_key IS NULL";
4026
4027 if ($a_codes) {
4028 $sql .= " AND " . $ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
4029 } elseif ($a_ids) {
4030 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
4031 }
4032
4033 $export = array();
4034
4035 // #14905
4036 $titles = array();
4037 $titles[] = '"' . $lng->txt("survey_code") . '"';
4038 $titles[] = '"' . $lng->txt("email") . '"';
4039 $titles[] = '"' . $lng->txt("lastname") . '"';
4040 $titles[] = '"' . $lng->txt("firstname") . '"';
4041 $titles[] = '"' . $lng->txt("create_date") . '"';
4042 $titles[] = '"' . $lng->txt("used") . '"';
4043 $titles[] = '"' . $lng->txt("mail_sent_short") . '"';
4044 $titles[] = '"' . $lng->txt("survey_code_url") . '"';
4045 $export[] = implode(";", $titles);
4046
4047 $result = $ilDB->query($sql);
4048 $default_lang = $ilUser->getPref("survey_code_language");
4049 while ($row = $ilDB->fetchAssoc($result)) {
4050 $item = array();
4051 $item[] = $row["survey_key"];
4052
4053 if ($row["externaldata"]) {
4054 $ext = unserialize($row["externaldata"]);
4055 $item[] = $ext["email"];
4056 $item[] = $ext["lastname"];
4057 $item[] = $ext["firstname"];
4058 } else {
4059 $item[] = "";
4060 $item[] = "";
4061 $item[] = "";
4062 }
4063
4064 // No relative (today, tomorrow...) dates in export.
4065 $date = new ilDateTime($row['tstamp'], IL_CAL_UNIX);
4066 $item[] = $date->get(IL_CAL_DATETIME);
4067
4068 $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4069 $item[] = ($row["sent"]) ? 1 : 0;
4070
4071 $params = array("accesscode" => $row["survey_key"]);
4072 if ($default_lang) {
4073 $params["lang"] = $default_lang;
4074 }
4075 $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4076
4077 $export[] = '"' . implode('";"', $item) . '"';
4078 }
4079 return implode("\n", $export);
4080 }
4081
4089 public function getSurveyCodesTableData(array $ids = null, $lang = null)
4090 {
4091 $ilDB = $this->db;
4092
4093 $codes = array();
4094
4095 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4096 " FROM svy_anonymous" .
4097 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4098 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") /*.
4099 " AND svy_anonymous.user_key IS NULL" */; // #15860
4100
4101 if ($ids) {
4102 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4103 }
4104
4105 $sql .= " ORDER BY tstamp, survey_key ASC";
4106 $result = $ilDB->query($sql);
4107 if ($result->numRows() > 0) {
4108 while ($row = $ilDB->fetchAssoc($result)) {
4109 $href = "";
4110 $used = false;
4111 if ($this->isSurveyCodeUsed($row["survey_key"])) {
4112 $used = true;
4113 } else {
4114 $params = array("accesscode" => $row["survey_key"]);
4115 if ($lang) {
4116 $params["lang"] = $lang;
4117 }
4118 $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4119 }
4120
4121
4122 $item = array(
4123 'id' => $row["anonymous_id"],
4124 'code' => $row["survey_key"],
4125 'date' => $row["tstamp"],
4126 'used' => $used,
4127 'sent' => $row['sent'],
4128 'href' => $href,
4129 'email' => '',
4130 'last_name' => '',
4131 'first_name' => ''
4132 );
4133
4134 if ($row["externaldata"]) {
4135 $ext = unserialize($row["externaldata"]);
4136 $item['email'] = $ext['email'];
4137 $item['last_name'] = $ext['lastname'];
4138 $item['first_name'] = $ext['firstname'];
4139 }
4140
4141 array_push($codes, $item);
4142 }
4143 }
4144 return $codes;
4145 }
4146
4147 public function isSurveyCodeUsed($code)
4148 {
4149 $ilDB = $this->db;
4150 $result = $ilDB->queryF(
4151 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4152 array('integer','text'),
4153 array($this->getSurveyId(), $code)
4154 );
4155 return ($result->numRows() > 0) ? true : false;
4156 }
4157
4158 public function isSurveyCodeUnique($code)
4159 {
4160 $ilDB = $this->db;
4161 $result = $ilDB->queryF(
4162 "SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4163 array('integer','text'),
4164 array($this->getSurveyId(), $code)
4165 );
4166 return ($result->numRows() > 0) ? false : true;
4167 }
4168
4169 public function createSurveyCodes($nrOfCodes)
4170 {
4171 $ilDB = $this->db;
4172
4173 $res = array();
4174
4175 for ($i = 0; $i < $nrOfCodes; $i++) {
4176 $next_id = $ilDB->nextId('svy_anonymous');
4177 $ilDB->manipulateF(
4178 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) " .
4179 "VALUES (%s, %s, %s, %s)",
4180 array('integer','text','integer','integer'),
4181 array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4182 );
4183 $res[] = $next_id;
4184 }
4185
4186 return $res;
4187 }
4188
4189 public function importSurveyCode($a_anonymize_key, $a_created, $a_data)
4190 {
4191 $ilDB = $this->db;
4192
4193 $next_id = $ilDB->nextId('svy_anonymous');
4194 $ilDB->manipulateF(
4195 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4196 "VALUES (%s, %s, %s, %s, %s)",
4197 array('integer','text','integer','text','integer'),
4198 array($next_id, $a_anonymize_key, $this->getSurveyId(), serialize($a_data), $a_created)
4199 );
4200 }
4201
4203 {
4204 $ilDB = $this->db;
4205
4206 $ids = array();
4207 foreach ($data as $dataset) {
4208 $anonymize_key = $this->createNewAccessCode();
4209 $next_id = $ilDB->nextId('svy_anonymous');
4210 $affectedRows = $ilDB->manipulateF(
4211 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4212 "VALUES (%s, %s, %s, %s, %s)",
4213 array('integer','text','integer','text','integer'),
4214 array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
4215 );
4216 $ids[] = $next_id;
4217 }
4218 return $ids;
4219 }
4220
4221 public function sendCodes($not_sent, $subject, $message, $lang)
4222 {
4223 global $DIC;
4224 /*
4225 * 0 = all
4226 * 1 = not sent
4227 * 2 = finished
4228 * 3 = not finished
4229 */
4230 $check_finished = ($not_sent > 1);
4231
4232
4233 $mail = new ilMail(ANONYMOUS_USER_ID);
4234 $recipients = $this->getExternalCodeRecipients($check_finished);
4235 foreach ($recipients as $data) {
4236 if ($data['email'] && $data['code']) {
4237 $do_send = false;
4238 switch ((int) $not_sent) {
4239 case 1:
4240 $do_send = !(bool) $data['sent'];
4241 break;
4242
4243 case 2:
4244 $do_send = $data['finished'];
4245 break;
4246
4247 case 3:
4248 $do_send = !$data['finished'];
4249 break;
4250
4251 default:
4252 $do_send = true;
4253 break;
4254 }
4255 if ($do_send) {
4256 // build text
4257 $messagetext = $message;
4259 $this->getRefId(),
4260 "svy",
4261 array(
4262 "accesscode" => $data["code"],
4263 "lang" => $lang
4264 )
4265 );
4266 $messagetext = str_replace('[url]', $url, $messagetext);
4267 foreach ($data as $key => $value) {
4268 $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
4269 }
4270
4271 // send mail
4272 $mail->enqueue(
4273 $data['email'], // to
4274 "", // cc
4275 "", // bcc
4276 $subject, // subject
4277 $messagetext, // message
4278 array() // attachments
4279 );
4280 }
4281 }
4282 }
4283
4284 $ilDB = $this->db;
4285 $ilDB->manipulateF(
4286 "UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
4287 array('integer','integer'),
4288 array(1, $this->getSurveyId())
4289 );
4290 }
4291
4292 public function getExternalCodeRecipients($a_check_finished = false)
4293 {
4294 $ilDB = $this->db;
4295 $result = $ilDB->queryF(
4296 "SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
4297 array('integer'),
4298 array($this->getSurveyId())
4299 );
4300 $res = array();
4301 while ($row = $ilDB->fetchAssoc($result)) {
4302 if (!$row['externaldata']) {
4303 continue;
4304 }
4305
4306 $externaldata = unserialize($row['externaldata']);
4307 if (!$externaldata['email']) {
4308 continue;
4309 }
4310
4311 $externaldata['code'] = $row['code'];
4312 $externaldata['sent'] = $row['sent'];
4313
4314 if ($a_check_finished) {
4315 #23294
4316 //$externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
4317 $externaldata['finished'] = $this->isSurveyFinishedByCode($row['code']);
4318 }
4319
4320 array_push($res, $externaldata);
4321 }
4322 return $res;
4323 }
4324
4330 public function isSurveyFinishedByCode($a_code)
4331 {
4332 $result = $this->db->queryF(
4333 "SELECT state FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4334 array('integer','text'),
4335 array($this->getSurveyId(), $a_code)
4336 );
4337
4338 $row = $this->db->fetchAssoc($result);
4339
4340 return $row['state'];
4341 }
4342
4348 public function deleteSurveyCode($survey_code)
4349 {
4350 $ilDB = $this->db;
4351
4352 if (strlen($survey_code) > 0) {
4353 $affectedRows = $ilDB->manipulateF(
4354 "DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4355 array('integer', 'text'),
4356 array($this->getSurveyId(), $survey_code)
4357 );
4358 }
4359 }
4360
4367 public function getUserAccessCode($user_id)
4368 {
4369 $ilDB = $this->db;
4370 $access_code = "";
4371 $result = $ilDB->queryF(
4372 "SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
4373 array('integer','text'),
4374 array($this->getSurveyId(), md5($user_id))
4375 );
4376 if ($result->numRows()) {
4377 $row = $ilDB->fetchAssoc($result);
4378 $access_code = $row["survey_key"];
4379 }
4380 return $access_code;
4381 }
4382
4389 public function saveUserAccessCode($user_id, $access_code)
4390 {
4391 $ilDB = $this->db;
4392
4393 // not really sure what to do about ANONYMOUS_USER_ID
4394
4395 $next_id = $ilDB->nextId('svy_anonymous');
4396 $affectedRows = $ilDB->manipulateF(
4397 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) " .
4398 "VALUES (%s, %s, %s, %s, %s)",
4399 array('integer','text', 'integer', 'text', 'integer'),
4400 array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
4401 );
4402 }
4403
4409 public function createNewAccessCode()
4410 {
4411 // create a 5 character code
4412 $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4413 mt_srand();
4414 $code = "";
4415 for ($i = 1; $i <= 5; $i++) {
4416 $index = mt_rand(0, strlen($codestring) - 1);
4417 $code .= substr($codestring, $index, 1);
4418 }
4419 // verify it against the database
4420 while (!$this->isSurveyCodeUnique($code)) {
4421 $code = $this->createNewAccessCode();
4422 }
4423 return $code;
4424 }
4425
4426 public function getLastAccess($finished_id)
4427 {
4428 $ilDB = $this->db;
4429
4430 $result = $ilDB->queryF(
4431 "SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
4432 array('integer'),
4433 array($finished_id)
4434 );
4435 if ($result->numRows()) {
4436 $row = $ilDB->fetchAssoc($result);
4437 return $row["tstamp"];
4438 } else {
4439 $result = $ilDB->queryF(
4440 "SELECT tstamp FROM svy_finished WHERE finished_id = %s",
4441 array('integer'),
4442 array($finished_id)
4443 );
4444 if ($result->numRows()) {
4445 $row = $ilDB->fetchAssoc($result);
4446 return $row["tstamp"];
4447 }
4448 }
4449 return "";
4450 }
4451
4458 public function prepareTextareaOutput($txt_output)
4459 {
4460 return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
4461 }
4462
4470 public function isHTML($a_text)
4471 {
4472 if (preg_match("/<[^>]*?>/", $a_text)) {
4473 return true;
4474 } else {
4475 return false;
4476 }
4477 }
4478
4487 public function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = true, $add_mobs = true, $attribs = null)
4488 {
4489 $a_xml_writer->xmlStartTag("material", $attribs);
4490 $attrs = array(
4491 "type" => "text/plain"
4492 );
4493 if ($this->isHTML($a_material)) {
4494 $attrs["type"] = "text/xhtml";
4495 }
4496 $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
4497 $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
4498
4499 if ($add_mobs) {
4500 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
4501 foreach ($mobs as $mob) {
4502 $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
4503 if (strpos($mattext, $mob_id) !== false) {
4504 $mob_obj = new ilObjMediaObject($mob);
4505 $imgattrs = array(
4506 "label" => $mob_id,
4507 "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
4508 "type" => "svy:html",
4509 "id" => $this->getId()
4510 );
4511 $a_xml_writer->xmlElement("matimage", $imgattrs, null);
4512 }
4513 }
4514 }
4515 if ($close_material_tag) {
4516 $a_xml_writer->xmlEndTag("material");
4517 }
4518 }
4519
4528 public function canExportSurveyCode()
4529 {
4530 if ($this->getAnonymize() != self::ANONYMIZE_OFF) {
4531 if ($this->surveyCodeSecurity == false) {
4532 return true;
4533 }
4534 }
4535 return false;
4536 }
4537
4545 public function processPrintoutput2FO($print_output)
4546 {
4547 if (extension_loaded("tidy")) {
4548 $config = array(
4549 "indent" => false,
4550 "output-xml" => true,
4551 "numeric-entities" => true
4552 );
4553 $tidy = new tidy();
4554 $tidy->parseString($print_output, $config, 'utf8');
4555 $tidy->cleanRepair();
4556 $print_output = tidy_get_output($tidy);
4557 $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
4558 } else {
4559 $print_output = str_replace("&nbsp;", "&#160;", $print_output);
4560 $print_output = str_replace("&otimes;", "X", $print_output);
4561
4562 // #17680 - metric questions use &#160; in print view
4563 $print_output = str_replace("&gt;", "~|gt|~", $print_output); // see #21550
4564 $print_output = str_replace("&lt;", "~|lt|~", $print_output);
4565 $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
4566 $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
4567 $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
4568 $print_output = str_replace("~|gt|~", "&gt;", $print_output);
4569 $print_output = str_replace("~|lt|~", "&lt;", $print_output);
4570 }
4571 $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
4572
4573 // additional font support
4574 $xsl = str_replace(
4575 'font-family="Helvetica, unifont"',
4576 'font-family="' . $GLOBALS['ilSetting']->get('rpc_pdf_font', 'Helvetica, unifont') . '"',
4577 $xsl
4578 );
4579 $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
4580 $xh = xslt_create();
4581 $params = array();
4582 try {
4583 $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
4584 } catch (Exception $e) {
4585 $this->svy_log->error("Print XSLT failed:");
4586 $this->svy_log->error("Content: " . $print_output);
4587 $this->svy_log->error("Xsl: " . $xsl);
4588 throw ($e);
4589 }
4590 xslt_error($xh);
4591 xslt_free($xh);
4592
4593 return $output;
4594 }
4595
4602 public function deliverPDFfromFO($fo)
4603 {
4604 $ilLog = $this->svy_log;
4605
4606 $fo_file = ilUtil::ilTempnam() . ".fo";
4607 $fp = fopen($fo_file, "w");
4608 fwrite($fp, $fo);
4609 fclose($fp);
4610
4611 try {
4612 $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
4613 ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
4614 return true;
4615 } catch (Exception $e) {
4616 $ilLog->write(__METHOD__ . ': ' . $e->getMessage());
4617 return false;
4618 }
4619 }
4620
4627 public function isPluginActive($a_pname)
4628 {
4629 $ilPluginAdmin = $this->plugin_admin;
4630 if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname)) {
4631 return true;
4632 } else {
4633 return false;
4634 }
4635 }
4636
4642 public function setSurveyId($survey_id)
4643 {
4644 $this->survey_id = $survey_id;
4645 }
4646
4653 public function &getUserData($ids)
4654 {
4655 $ilDB = $this->db;
4656
4657 if (!is_array($ids) || count($ids) == 0) {
4658 return array();
4659 }
4660
4661 $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
4662 $result_array = array();
4663 while ($row = $ilDB->fetchAssoc($result)) {
4664 $result_array[$row["usr_id"]] = $row;
4665 }
4666 return $result_array;
4667 }
4668
4669 public function getMailNotification()
4670 {
4672 }
4673
4674 public function setMailNotification($a_notification)
4675 {
4676 $this->mailnotification = ($a_notification) ? true : false;
4677 }
4678
4679 public function getMailAddresses()
4680 {
4681 return $this->mailaddresses;
4682 }
4683
4684 public function setMailAddresses($a_addresses)
4685 {
4686 $this->mailaddresses = $a_addresses;
4687 }
4688
4689 public function getMailParticipantData()
4690 {
4692 }
4693
4694 public function setMailParticipantData($a_data)
4695 {
4696 $this->mailparticipantdata = $a_data;
4697 }
4698
4699 public function setStartTime($finished_id, $first_question)
4700 {
4701 $ilDB = $this->db;
4702 $time = time();
4703 //primary for table svy_times
4704 $id = $ilDB->nextId('svy_times');
4705 $_SESSION['svy_entered_page'] = $time;
4706 $affectedRows = $ilDB->manipulateF(
4707 "INSERT INTO svy_times (id, finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s,%s)",
4708 array('integer','integer', 'integer', 'integer', 'integer'),
4709 array($id, $finished_id, $time, null, $first_question)
4710 );
4711 }
4712
4713 public function setEndTime($finished_id)
4714 {
4715 $ilDB = $this->db;
4716 $time = time();
4717 $affectedRows = $ilDB->manipulateF(
4718 "UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
4719 array('integer', 'integer', 'integer'),
4720 array($time, $finished_id, $_SESSION['svy_entered_page'])
4721 );
4722 unset($_SESSION['svy_entered_page']);
4723 }
4724
4725 public function getWorkingtimeForParticipant($finished_id)
4726 {
4727 $ilDB = $this->db;
4728
4729 $result = $ilDB->queryF(
4730 "SELECT * FROM svy_times WHERE finished_fi = %s",
4731 array('integer'),
4732 array($finished_id)
4733 );
4734 $total = 0;
4735 while ($row = $ilDB->fetchAssoc($result)) {
4736 if ($row['left_page'] > 0 && $row['entered_page'] > 0) {
4737 $total += $row['left_page'] - $row['entered_page'];
4738 }
4739 }
4740 return $total;
4741 }
4742
4743 public function setTemplate($template_id)
4744 {
4745 $this->template_id = (int) $template_id;
4746 }
4747
4748 public function getTemplate()
4749 {
4750 return $this->template_id;
4751 }
4752
4753 public function updateOrder(array $a_order)
4754 {
4755 if (sizeof($this->questions) == sizeof($a_order)) {
4756 $this->questions = array_flip($a_order);
4757 $this->saveQuestionsToDB();
4758 }
4759 }
4760
4761 public function getPoolUsage()
4762 {
4763 return $this->pool_usage;
4764 }
4765
4766 public function setPoolUsage($a_value)
4767 {
4768 $this->pool_usage = (bool) $a_value;
4769 }
4770
4776 public function isPoolActive()
4777 {
4778 $use_pool = (bool) $this->getPoolUsage();
4779 $template_settings = $this->getTemplate();
4780 if ($template_settings) {
4781 $template_settings = new ilSettingsTemplate($template_settings);
4782 $template_settings = $template_settings->getSettings();
4783 $template_settings = $template_settings["use_pool"];
4784 if ($template_settings && $template_settings["hide"]) {
4785 $use_pool = (bool) $template_settings["value"];
4786 }
4787 }
4788 return $use_pool;
4789 }
4790
4797 {
4798 if (!$template_id) {
4799 return;
4800 }
4801
4802 $template = new ilSettingsTemplate($template_id);
4803 $template_settings = $template->getSettings();
4804 //ilUtil::dumpVar($template_settings); exit;
4805 if ($template_settings) {
4806 if ($template_settings["show_question_titles"] !== null) {
4807 if ($template_settings["show_question_titles"]["value"]) {
4808 $this->setShowQuestionTitles(true);
4809 } else {
4810 $this->setShowQuestionTitles(false);
4811 }
4812 }
4813
4814 if ($template_settings["use_pool"] !== null) {
4815 if ($template_settings["use_pool"]["value"]) {
4816 $this->setPoolUsage(true);
4817 } else {
4818 $this->setPoolUsage(false);
4819 }
4820 }
4821
4822
4823 /* see #0021719
4824 if($template_settings["anonymization_options"]["value"])
4825 {
4826 $anon_map = array('personalized' => self::ANONYMIZE_OFF,
4827 'anonymize_with_code' => self::ANONYMIZE_ON,
4828 'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
4829 $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
4830 }*/
4831
4832 // see #0021719 and ilObjectSurveyGUI::savePropertiesObject
4833 $this->setEvaluationAccess($template_settings["evaluation_access"]["value"]);
4834 $codes = (bool) $template_settings["acc_codes"]["value"];
4835 $anon = (bool) $template_settings["anonymization_options"]["value"];
4836 if (!$anon) {
4837 if (!$codes) {
4839 } else {
4841 }
4842 } else {
4843 if ($codes) {
4845 } else {
4847 }
4848
4849 $this->setAnonymousUserList($_POST["anon_list"]);
4850 }
4851
4852
4853
4854 /* other settings: not needed here
4855 * - enabled_end_date
4856 * - enabled_start_date
4857 * - rte_switch
4858 */
4859 }
4860
4861 $this->setTemplate($template_id);
4862 $this->saveToDb();
4863 }
4864
4865 public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
4866 {
4867 $ilDB = $this->db;
4868
4869 $a_email = trim($a_email);
4870
4871 // :TODO:
4872 if (($a_email && !ilUtil::is_email($a_email)) || $a_email == "") {
4873 return false;
4874 }
4875
4876 $data = array("email" => $a_email,
4877 "lastname" => trim($a_last_name),
4878 "firstname" => trim($a_first_name));
4879
4880 $fields = array(
4881 "externaldata" => array("text", serialize($data)),
4882 "sent" => array("integer", $a_sent)
4883 );
4884
4885 $ilDB->update(
4886 "svy_anonymous",
4887 $fields,
4888 array("anonymous_id" => array("integer", $a_id))
4889 );
4890
4891 return true;
4892 }
4893
4894
4895 //
4896 // 360°
4897 //
4898
4899 public function get360Mode()
4900 {
4901 if ($this->getMode() == ilObjSurvey::MODE_360) {
4902 return true;
4903 }
4904 return false;
4905 }
4906
4907 public function set360SelfEvaluation($a_value)
4908 {
4909 $this->mode_360_self_eval = (bool) $a_value;
4910 }
4911
4912 public function get360SelfEvaluation()
4913 {
4914 return (bool) $this->mode_360_self_eval;
4915 }
4916
4917 public function set360SelfAppraisee($a_value)
4918 {
4919 $this->mode_360_self_appr = (bool) $a_value;
4920 }
4921
4922 public function get360SelfAppraisee()
4923 {
4924 return (bool) $this->mode_360_self_appr;
4925 }
4926
4927 public function set360SelfRaters($a_value)
4928 {
4929 $this->mode_360_self_rate = (bool) $a_value;
4930 }
4931
4932 public function get360SelfRaters()
4933 {
4934 return (bool) $this->mode_360_self_rate;
4935 }
4936
4937 public function set360Results($a_value)
4938 {
4939 $this->mode_360_results = (int) $a_value;
4940 }
4941
4942 public function get360Results()
4943 {
4944 return (int) $this->mode_360_results;
4945 }
4946
4947 public function addAppraisee($a_user_id)
4948 {
4949 global $DIC;
4950
4951 $ilDB = $DIC->database();
4952 $access = $DIC->access();
4953
4954 if (!$this->isAppraisee($a_user_id) &&
4955 $a_user_id != ANONYMOUS_USER_ID) {
4956 $fields = array(
4957 "obj_id" => array("integer", $this->getSurveyId()),
4958 "user_id" => array("integer", $a_user_id)
4959 );
4960 $ilDB->insert("svy_360_appr", $fields);
4961
4962 // send notification and add to desktop
4963 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
4964 $this->sendAppraiseeNotification($a_user_id);
4965 }
4966 }
4967 }
4968
4974 public function sendAppraiseeNotification($a_user_id)
4975 {
4976 $ntf = new ilSystemNotification();
4977 $ntf->setLangModules(array("svy", "survey"));
4978 $ntf->setRefId($this->getRefId());
4979 $ntf->setGotoLangId('url');
4980
4981 // user specific language
4982 $lng = $ntf->getUserLanguage($a_user_id);
4983
4984 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_mail");
4985 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
4986
4987 // #10044
4988 $mail = new ilMail(ANONYMOUS_USER_ID);
4989 $mail->enqueue(
4990 ilObjUser::_lookupLogin($a_user_id),
4991 null,
4992 null,
4993 $subject,
4994 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
4995 []
4996 );
4997 }
4998
5004 public function sendAppraiseeCloseNotification($a_user_id)
5005 {
5006 $ntf = new ilSystemNotification();
5007 $ntf->setLangModules(array("svy", "survey"));
5008 $ntf->setRefId($this->getRefId());
5009 $ntf->setGotoLangId('url');
5010
5011 // user specific language
5012 $lng = $ntf->getUserLanguage($a_user_id);
5013
5014 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_close_mail");
5015 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
5016
5017 // #10044
5018 $mail = new ilMail(ANONYMOUS_USER_ID);
5019 $mail->enqueue(
5020 ilObjUser::_lookupLogin($a_user_id),
5021 null,
5022 null,
5023 $subject,
5024 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5025 []
5026 );
5027 }
5028
5034 public function sendRaterNotification($a_user_id, $a_appraisee_id)
5035 {
5036 $ntf = new ilSystemNotification();
5037 $ntf->setLangModules(array("svy", "survey"));
5038 $ntf->setRefId($this->getRefId());
5039 $ntf->setGotoLangId('url');
5040
5041 // user specific language
5042 $lng = $ntf->getUserLanguage($a_user_id);
5043
5044 $ntf->setIntroductionLangId("svy_user_added_360_rater_mail");
5045 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5046 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($a_appraisee_id, false, false, "", true));
5047
5048 // #10044
5049 $mail = new ilMail(ANONYMOUS_USER_ID);
5050 $mail->enqueue(
5051 ilObjUser::_lookupLogin($a_user_id),
5052 null,
5053 null,
5054 $subject,
5055 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5056 []
5057 );
5058 }
5059
5060 public function isAppraisee($a_user_id)
5061 {
5062 $ilDB = $this->db;
5063
5064 $set = $ilDB->query("SELECT user_id" .
5065 " FROM svy_360_appr" .
5066 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5067 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5068 return (bool) $ilDB->numRows($set);
5069 }
5070
5071 public function isAppraiseeClosed($a_user_id)
5072 {
5073 $ilDB = $this->db;
5074
5075 $set = $ilDB->query("SELECT has_closed" .
5076 " FROM svy_360_appr" .
5077 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5078 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5079 $row = $ilDB->fetchAssoc($set);
5080 return $row["has_closed"];
5081 }
5082
5083 public function deleteAppraisee($a_user_id)
5084 {
5085 $ilDB = $this->db;
5086
5087 $ilDB->manipulate("DELETE FROM svy_360_appr" .
5088 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5089 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5090
5091 $set = $ilDB->query("SELECT user_id" .
5092 " FROM svy_360_rater" .
5093 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5094 " AND appr_id = " . $ilDB->quote($a_user_id, "integer"));
5095 while ($row = $ilDB->fetchAssoc($set)) {
5096 $this->deleteRater($a_user_id, $row["user_id"]);
5097 }
5098 // appraisee will not be part of raters table
5099 if ($this->get360SelfEvaluation()) {
5100 $this->deleteRater($a_user_id, $a_user_id);
5101 }
5102 }
5103
5104 public function getAppraiseesData()
5105 {
5106 $ilDB = $this->db;
5107
5108 $res = array();
5109
5110 $set = $ilDB->query("SELECT * FROM svy_360_appr" .
5111 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5112 while ($row = $ilDB->fetchAssoc($set)) {
5113 $name = ilObjUser::_lookupName($row["user_id"]);
5114 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5115 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5116 $res[$row["user_id"]] = $name;
5117
5118 $finished = 0;
5119 $raters = $this->getRatersData($row["user_id"]);
5120 foreach ($raters as $rater) {
5121 if ($rater["finished"]) {
5122 $finished++;
5123 }
5124 }
5125 $res[$row["user_id"]]["finished"] = $finished . "/" . sizeof($raters);
5126 $res[$row["user_id"]]["closed"] = $row["has_closed"];
5127 }
5128
5129 return $res;
5130 }
5131
5132 public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5133 {
5134 global $DIC;
5135
5136 $ilDB = $DIC->database();
5137 $access = $DIC->access();
5138
5139 if ($this->isAppraisee($a_appraisee_id) &&
5140 !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id)) {
5141 $fields = array(
5142 "obj_id" => array("integer", $this->getSurveyId()),
5143 "appr_id" => array("integer", $a_appraisee_id),
5144 "user_id" => array("integer", $a_user_id),
5145 "anonymous_id" => array("integer", $a_anonymous_id)
5146 );
5147 $ilDB->insert("svy_360_rater", $fields);
5148
5149 // send notification and add to desktop
5150 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
5151 $this->sendRaterNotification($a_user_id, $a_appraisee_id);
5152 }
5153 }
5154 }
5155
5156 public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5157 {
5158 $ilDB = $this->db;
5159
5160 // user is rater if already appraisee and active self-evaluation
5161 if ($this->isAppraisee($a_user_id) &&
5162 $this->get360SelfEvaluation() &&
5163 (!$a_appraisee_id || $a_appraisee_id == $a_user_id)) {
5164 return true;
5165 }
5166
5167 // :TODO: should we get rid of code as well?
5168
5169 $sql = "SELECT user_id" .
5170 " FROM svy_360_rater" .
5171 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5172 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5173 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5174 if ($a_appraisee_id) {
5175 $sql .= " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer");
5176 }
5177 $set = $ilDB->query($sql);
5178 return (bool) $ilDB->numRows($set);
5179 }
5180
5181 public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5182 {
5183 $ilDB = $this->db;
5184
5185 $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5186 if ($finished_id) {
5187 $this->removeSelectedSurveyResults(array($finished_id));
5188 }
5189
5190 $ilDB->manipulate("DELETE FROM svy_360_rater" .
5191 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5192 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5193 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5194 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5195 }
5196
5197 public function getRatersData($a_appraisee_id)
5198 {
5199 $ilDB = $this->db;
5200
5201 $res = $anonymous_ids = array();
5202
5203 $set = $ilDB->query("SELECT * FROM svy_360_rater" .
5204 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5205 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer"));
5206 while ($row = $ilDB->fetchAssoc($set)) {
5207 if ($row["anonymous_id"]) {
5208 $res["a" . $row["anonymous_id"]] = array(
5209 "lastname" => "unknown code " . $row["anonymous_id"],
5210 "sent" => $row["mail_sent"],
5211 "finished" => null
5212 );
5213 $anonymous_ids[] = $row["anonymous_id"];
5214 } else {
5215 $name = ilObjUser::_lookupName($row["user_id"]);
5216 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5217 $name["user_id"] = "u" . $name["user_id"];
5218 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5219 $name["sent"] = $row["mail_sent"];
5220 $name["finished"] = (bool) $this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
5221 $res["u" . $row["user_id"]] = $name;
5222 }
5223 }
5224
5225 if (sizeof($anonymous_ids)) {
5226 $data = $this->getSurveyCodesTableData($anonymous_ids);
5227 foreach ($data as $item) {
5228 if (isset($res["a" . $item["id"]])) {
5229 $res["a" . $item["id"]] = array(
5230 "user_id" => "a" . $item["id"],
5231 "lastname" => $item["last_name"],
5232 "firstname" => $item["first_name"],
5233 "name" => $item["last_name"] . ", " . $item["first_name"],
5234 "login" => "",
5235 "email" => $item["email"],
5236 "code" => $item["code"],
5237 "href" => $item["href"],
5238 "sent" => $res["a" . $item["id"]]["sent"],
5239 "finished" => (bool) $this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
5240 );
5241 }
5242 }
5243 }
5244
5245 return $res;
5246 }
5247
5248 public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
5249 {
5250 $ilDB = $this->db;
5251
5252 $res = array();
5253
5254 $sql = "SELECT appr_id FROM svy_360_rater" .
5255 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer");
5256
5257 if ($a_user_id) {
5258 $sql .= " AND user_id = " . $ilDB->quote($a_user_id, "integer");
5259 } else {
5260 $sql .= " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5261 }
5262
5263 $set = $ilDB->query($sql);
5264 while ($row = $ilDB->fetchAssoc($set)) {
5265 $res[] = $row["appr_id"];
5266 }
5267
5268 // user may evaluate himself if already appraisee
5269 if ($this->get360SelfEvaluation() &&
5270 $this->isAppraisee($a_user_id) &&
5271 !in_array($a_user_id, $res)) {
5272 $res[] = $a_user_id;
5273 }
5274
5275 return $res;
5276 }
5277
5278 public function getAnonymousIdByCode($a_code)
5279 {
5280 $ilDB = $this->db;
5281
5282 $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous" .
5283 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5284 " AND survey_key = " . $ilDB->quote($a_code, "text"));
5285 $res = $ilDB->fetchAssoc($set);
5286 return $res["anonymous_id"];
5287 }
5288
5289 public function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
5290 {
5291 $ilDB = $this->db;
5292
5293 $sql = "SELECT * FROM svy_finished" .
5294 " WHERE survey_fi =" . $ilDB->quote($this->getSurveyId(), "integer") .
5295 " AND appr_id = " . $ilDB->quote($appr_id, "integer");
5296 if ($user_id) {
5297 $sql .= " AND user_fi = " . $ilDB->quote($user_id, "integer");
5298 } else {
5299 $sql .= " AND anonymous_id = " . $ilDB->quote($anonymous_code, "text");
5300 }
5301 $result = $ilDB->query($sql);
5302 if ($result->numRows() == 0) {
5303 return false;
5304 } else {
5305 $row = $ilDB->fetchAssoc($result);
5306 return (int) $row["state"];
5307 }
5308 }
5309
5310 public function getUserSurveyExecutionStatus($a_code = null)
5311 {
5313 $ilDB = $this->db;
5314
5315 $user_id = $ilUser->getId();
5316
5317 // code is obligatory?
5318 if (!$this->isAccessibleWithoutCode()) {
5319 if (!$a_code) {
5320 // registered raters do not need code
5321 if ($this->get360Mode() &&
5322 $user_id != ANONYMOUS_USER_ID &&
5323 $this->isRater(0, $user_id)) {
5324 // auto-generate code
5325 $a_code = $this->createNewAccessCode();
5326 $this->saveUserAccessCode($user_id, $a_code);
5327 } else {
5328 return null;
5329 }
5330 }
5331 } elseif ($user_id == ANONYMOUS_USER_ID ||
5332 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS) {
5333 if (!$a_code) {
5334 // auto-generate code
5335 $a_code = $this->createNewAccessCode();
5336 $this->saveUserAccessCode($user_id, $a_code);
5337 }
5338 } else {
5339 $a_code = null;
5340 }
5341
5342 $res = array();
5343
5344 $sql = "SELECT * FROM svy_finished" .
5345 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
5346 // if proper user id is given, use it or current code
5347 if ($user_id != ANONYMOUS_USER_ID) {
5348 $sql .= " AND (user_fi = " . $ilDB->quote($user_id, "integer") .
5349 " OR anonymous_id = " . $ilDB->quote($a_code, "text") . ")";
5350 }
5351 // use anonymous code to find finished id(s)
5352 else {
5353 $sql .= " AND anonymous_id = " . $ilDB->quote($a_code, "text");
5354 }
5355 $set = $ilDB->query($sql);
5356 while ($row = $ilDB->fetchAssoc($set)) {
5357 $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
5358 "user_id" => $row["user_fi"],
5359 "code" => $row["anonymous_id"],
5360 "finished" => (bool) $row["state"]);
5361 }
5362
5363 return array("code" => $a_code, "runs" => $res);
5364 }
5365
5366 public function findCodeForUser($a_user_id)
5367 {
5368 $ilDB = $this->db;
5369
5370 if ($a_user_id != ANONYMOUS_USER_ID) {
5371 $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf" .
5372 " WHERE sf.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5373 " AND sf.user_fi = " . $ilDB->quote($a_user_id, "integer"));
5374 $a_code = $ilDB->fetchAssoc($set);
5375 return $a_code["anonymous_id"];
5376 }
5377 }
5378
5379 public function isUnusedCode($a_code, $a_user_id)
5380 {
5381 $ilDB = $this->db;
5382
5383 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
5384 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5385 " AND anonymous_id = " . $ilDB->quote($a_code, "text"));
5386 $user_id = $ilDB->fetchAssoc($set);
5387 $user_id = $user_id["user_fi"];
5388
5389 if ($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID)) {
5390 return false;
5391 }
5392 return true;
5393 }
5394
5395 public function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
5396 {
5397 $ilDB = $this->db;
5398
5399 $res = array();
5400
5401 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5402 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5403 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer"));
5404 while ($row = $ilDB->fetchAssoc($set)) {
5405 if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id) {
5406 continue;
5407 }
5408 $res[] = $row["finished_id"];
5409 }
5410
5411 return $res;
5412 }
5413
5421 public function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
5422 {
5423 $ilDB = $this->db;
5424
5425 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5426 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5427 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer") .
5428 " AND user_fi = " . $ilDB->quote($a_rat_id, "integer"));
5429 $row = $ilDB->fetchAssoc($set);
5430 return $row["finished_id"];
5431 }
5432
5433 public function getFinishedIdsForSelfEval($a_user_id) : array
5434 {
5435 $ilDB = $this->db;
5436
5437 $finished_ids = [];
5438 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5439 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5440 " AND user_fi = " . $ilDB->quote($a_user_id, "integer"));
5441 if ($row = $ilDB->fetchAssoc($set)) {
5442 $finished_ids[] = (int) $row["finished_id"];
5443 }
5444 return $finished_ids;
5445 }
5446
5447 // 360° using competence/skill service
5448
5454 public function setSkillService($a_val)
5455 {
5456 $this->mode_skill_service = $a_val;
5457 }
5458
5464 public function getSkillService()
5465 {
5467 }
5468
5469 public function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
5470 {
5471 $ilDB = $this->db;
5472
5473 if (!$a_tstamp) {
5474 $a_tstamp = time();
5475 }
5476
5477 $ilDB->manipulate("UPDATE svy_360_rater" .
5478 " SET mail_sent = " . $ilDB->quote($a_tstamp, "integer") .
5479 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5480 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5481 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5482 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5483 }
5484
5485 public function closeAppraisee($a_user_id)
5486 {
5487 global $DIC;
5488
5489 $ilDB = $DIC->database();
5490 $user = $DIC->user();
5491
5492 // close the appraisee
5493 $ilDB->manipulate("UPDATE svy_360_appr" .
5494 " SET has_closed = " . $ilDB->quote(time(), "integer") .
5495 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5496 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5497
5498 // write competences
5499 $skmg_set = new ilSkillManagementSettings();
5500 if ($this->getSkillService() && $skmg_set->isActivated()) {
5501 $sskill = new ilSurveySkill($this);
5502 $sskill->writeAndAddAppraiseeSkills($a_user_id);
5503 }
5504
5505 // send notification
5506 if ($user->getId() != $a_user_id) {
5507 $this->sendAppraiseeCloseNotification($a_user_id);
5508 }
5509 }
5510
5511 public function openAllAppraisees()
5512 {
5513 $ilDB = $this->db;
5514
5515 $ilDB->manipulate("UPDATE svy_360_appr" .
5516 " SET has_closed = " . $ilDB->quote(null, "integer") .
5517 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5518 }
5519
5520 public static function validateExternalRaterCode($a_ref_id, $a_code)
5521 {
5522 if (!isset($_SESSION["360_extrtr"][$a_ref_id])) {
5523 $svy = new self($a_ref_id);
5524 $svy->loadFromDB();
5525
5526 if ($svy->canStartSurvey(null, true) &&
5527 $svy->get360Mode() &&
5528 $svy->isAnonymousKey($a_code)) {
5529 $anonymous_id = $svy->getAnonymousIdByCode($a_code);
5530 if ($anonymous_id) {
5531 if (sizeof($svy->getAppraiseesToRate(null, $anonymous_id))) {
5532 $_SESSION["360_extrtr"][$a_ref_id] = true;
5533 return true;
5534 }
5535 }
5536 }
5537
5538 $_SESSION["360_extrtr"][$a_ref_id] = false;
5539 return false;
5540 }
5541
5542 return $_SESSION["360_extrtr"][$a_ref_id];
5543 }
5544
5545
5546 //
5547 // reminder/notification
5548 //
5549
5550 public function getReminderStatus()
5551 {
5552 return (bool) $this->reminder_status;
5553 }
5554
5555 public function setReminderStatus($a_value)
5556 {
5557 $this->reminder_status = (bool) $a_value;
5558 }
5559
5560 public function getReminderStart()
5561 {
5562 return $this->reminder_start;
5563 }
5564
5565 public function setReminderStart(ilDate $a_value = null)
5566 {
5567 $this->reminder_start = $a_value;
5568 }
5569
5570 public function getReminderEnd()
5571 {
5572 return $this->reminder_end;
5573 }
5574
5575 public function setReminderEnd(ilDate $a_value = null)
5576 {
5577 $this->reminder_end = $a_value;
5578 }
5579
5580 public function getReminderFrequency()
5581 {
5583 }
5584
5585 public function setReminderFrequency($a_value)
5586 {
5587 $this->reminder_frequency = (int) $a_value;
5588 }
5589
5590 public function getReminderTarget()
5591 {
5593 }
5594
5595 public function setReminderTarget($a_value)
5596 {
5597 $this->reminder_target = (int) $a_value;
5598 }
5599
5600 public function getReminderLastSent()
5601 {
5603 }
5604
5605 public function setReminderLastSent($a_value)
5606 {
5607 $this->reminder_last_sent = $a_value;
5608 }
5609
5614 public function getReminderTemplate($selectDefault = false)
5615 {
5616 if ($selectDefault) {
5617 $defaultTemplateId = 0;
5618 $this->getReminderMailTemplates($defaultTemplateId);
5619
5620 if ($defaultTemplateId > 0) {
5621 return $defaultTemplateId;
5622 }
5623 }
5624
5625 return $this->reminder_tmpl;
5626 }
5627
5628 public function setReminderTemplate($a_value)
5629 {
5630 $this->reminder_tmpl = $a_value;
5631 }
5632
5634 {
5635 return (bool) $this->tutor_ntf_status;
5636 }
5637
5638 public function setTutorNotificationStatus($a_value)
5639 {
5640 $this->tutor_ntf_status = (bool) $a_value;
5641 }
5642
5644 {
5646 }
5647
5648 public function setTutorNotificationRecipients(array $a_value)
5649 {
5650 $this->tutor_ntf_recipients = $a_value;
5651 }
5652
5654 {
5656 }
5657
5658 public function setTutorNotificationTarget($a_value)
5659 {
5660 $this->tutor_ntf_target = (int) $a_value;
5661 }
5662
5663 public function getTutorResultsStatus()
5664 {
5665 return (bool) $this->tutor_res_status;
5666 }
5667
5668 public function setTutorResultsStatus($a_value)
5669 {
5670 $this->tutor_res_status = (bool) $a_value;
5671 }
5672
5674 {
5676 }
5677
5678 public function setTutorResultsRecipients(array $a_value)
5679 {
5680 $this->tutor_res_recipients = $a_value;
5681 }
5682
5683 protected function checkTutorNotification()
5684 {
5685 $ilDB = $this->db;
5686
5687 if ($this->getTutorNotificationStatus()) {
5688 $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
5689 if ($user_ids) {
5690 $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished" .
5691 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5692 " AND state = " . $ilDB->quote(1, "integer") .
5693 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
5694 $row = $ilDB->fetchAssoc($set);
5695 if ($row["numall"] == sizeof($user_ids)) {
5696 $this->sendTutorNotification();
5697 }
5698 }
5699 }
5700 }
5701
5708 public function sent360Reminders()
5709 {
5710 global $DIC;
5711
5712 $access = $DIC->access();
5713
5714 // collect all open ratings
5715 $rater_ids = array();
5716 foreach ($this->getAppraiseesData() as $app) {
5717 $this->svy_log->debug("Handle appraisee " . $app['user_id']);
5718
5719 if (!$this->isAppraiseeClosed($app['user_id'])) {
5720 $this->svy_log->debug("Check self evaluation, self: " . $this->get360SelfAppraisee() . ", target: " . $this->getReminderTarget());
5721
5722 // self evaluation?
5723 if ($this->get360SelfEvaluation() &&
5725 $this->svy_log->debug("...1");
5726 // did user already finished self evaluation?
5727 if (!$this->is360SurveyStarted($app['user_id'], $app['user_id'])) {
5728 $this->svy_log->debug("...2");
5729 if (!is_array($rater_ids[$app['user_id']])) {
5730 $rater_ids[$app['user_id']] = array();
5731 }
5732 if (!in_array($app["user_id"], $rater_ids[$app['user_id']])) {
5733 $rater_ids[$app['user_id']][] = $app["user_id"];
5734 }
5735 }
5736 }
5737
5738 $this->svy_log->debug("Check raters.");
5739
5740 // should raters be notified?
5742 foreach ($this->getRatersData($app['user_id']) as $rater) {
5743 // is rater not anonymous and did not rate yet?
5744 if (!$rater["anonymous_id"] && !$rater["finished"]) {
5745 if (!is_array($rater_ids[$rater["user_id"]])) {
5746 $rater_ids[$rater["user_id"]] = array();
5747 }
5748 if (!in_array($app["user_id"], $rater_ids[$rater["user_id"]])) {
5749 $rater_ids[$rater["user_id"]][] = $app["user_id"];
5750 }
5751 }
5752 }
5753 }
5754 }
5755 }
5756
5757 $this->svy_log->debug("Found raters:" . count($rater_ids));
5758
5759 foreach ($rater_ids as $id => $app) {
5760 if ($access->checkAccessOfUser($id, "read", "", $this->getRefId())) {
5761 $this->send360ReminderToUser($id, $app);
5762 }
5763 }
5764 }
5765
5771 public function send360ReminderToUser($a_user_id, $a_appraisee_ids)
5772 {
5773 $this->svy_log->debug("Send mail to:" . $a_user_id);
5774
5775 $ntf = new ilSystemNotification();
5776 $ntf->setLangModules(array("svy", "survey"));
5777 $ntf->setRefId($this->getRefId());
5778 $ntf->setGotoLangId('url');
5779
5780 // user specific language
5781 $lng = $ntf->getUserLanguage($a_user_id);
5782
5783 $ntf->setIntroductionLangId("svy_user_added_360_rater_reminder_mail");
5784 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5785
5786 foreach ($a_appraisee_ids as $appraisee_id) {
5787 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($appraisee_id, false, false, "", true));
5788 }
5789
5790 // #10044
5791 $mail = new ilMail(ANONYMOUS_USER_ID);
5792 $mail->enqueue(
5793 ilObjUser::_lookupLogin($a_user_id),
5794 null,
5795 null,
5796 $subject,
5797 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5798 []
5799 );
5800 }
5801
5802
5803 public function getNotificationTargetUserIds($a_use_invited)
5804 {
5806
5807 if ((bool) $a_use_invited) {
5808 $user_ids = $this->invitation_manager->getAllForSurvey($this->getSurveyId());
5809 } else {
5810 $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
5811 if ($parent_grp_ref_id) {
5812 $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
5813 $user_ids = $part->getMembers();
5814 } else {
5815 $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
5816 if ($parent_crs_ref_id) {
5817 $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
5818 $user_ids = $part->getMembers();
5819 }
5820 }
5821 }
5822 return $user_ids;
5823 }
5824
5825 protected function sendTutorNotification()
5826 {
5827 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
5828
5829 foreach ($this->getTutorNotificationRecipients() as $user_id) {
5830 // use language of recipient to compose message
5831 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
5832 $ulng->loadLanguageModule('survey');
5833
5834 $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
5835 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
5836
5837 $message .= $ulng->txt('survey_notification_tutor_body') . ":\n\n";
5838 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
5839 $message .= "\n" . $ulng->txt('survey_notification_tutor_link') . ": " . $link;
5840
5841 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
5842 $mail_obj->appendInstallationSignature(true);
5843 $mail_obj->enqueue(
5844 ilObjUser::_lookupLogin($user_id),
5845 "",
5846 "",
5847 $subject,
5848 $message,
5849 array()
5850 );
5851 }
5852 }
5853
5854 public function checkReminder()
5855 {
5856 $ilDB = $this->db;
5857 $ilAccess = $this->access;
5858
5859 $now = time();
5860 $now_with_format = date("YmdHis", $now);
5861 $today = date("Y-m-d");
5862
5863 $this->svy_log->debug("Check status and dates.");
5864
5865 // object settings / participation period
5866 if (
5867 $this->getOfflineStatus() ||
5868 !$this->getReminderStatus() ||
5869 ($this->getStartDate() && $now_with_format < $this->getStartDate()) ||
5870 ($this->getEndDate() && $now_with_format > $this->getEndDate())) {
5871 return false;
5872 }
5873
5874 // reminder period
5875 $start = $this->getReminderStart();
5876 if ($start) {
5877 $start = $start->get(IL_CAL_DATE);
5878 }
5879 $end = $this->getReminderEnd();
5880 if ($end) {
5881 $end = $end->get(IL_CAL_DATE);
5882 }
5883 if ($today < $start ||
5884 ($end && $today > $end)) {
5885 return false;
5886 }
5887
5888 $this->svy_log->debug("Check access period.");
5889
5890 // object access period
5891 $item_data = ilObjectActivation::getItem($this->getRefId());
5892 if ($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
5893 ($now < $item_data["timing_start"] ||
5894 $now > $item_data["timing_end"])) {
5895 return false;
5896 }
5897
5898 $this->svy_log->debug("Check frequency.");
5899
5900 // check frequency
5901 $cut = new ilDate($today, IL_CAL_DATE);
5902 $cut->increment(IL_CAL_DAY, $this->getReminderFrequency() * -1);
5903 if (!$this->getReminderLastSent() ||
5904 $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10)) {
5905 $missing_ids = array();
5906
5907 if (!$this->get360Mode()) {
5908 $this->svy_log->debug("Entering survey mode.");
5909
5910 // #16871
5911 $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
5912 if ($user_ids) {
5913 // gather participants who already finished
5914 $finished_ids = array();
5915 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
5916 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5917 " AND state = " . $ilDB->quote(1, "text") .
5918 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
5919 while ($row = $ilDB->fetchAssoc($set)) {
5920 $finished_ids[] = $row["user_fi"];
5921 }
5922
5923 // some users missing out?
5924 $missing_ids = array_diff($user_ids, $finished_ids);
5925 if ($missing_ids) {
5926 foreach ($missing_ids as $idx => $user_id) {
5927 // should be able to participate
5928 if (!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId())) {
5929 unset($missing_ids[$idx]);
5930 }
5931 }
5932 }
5933 if ($missing_ids) {
5934 $this->sentReminder($missing_ids);
5935 }
5936 }
5937 } else {
5938 $this->svy_log->debug("Entering 360 mode.");
5939
5940 $this->sent360Reminders();
5941 }
5942
5943
5944 $this->setReminderLastSent($today);
5945 $this->saveToDb();
5946
5947 return sizeof($missing_ids);
5948 }
5949
5950 return false;
5951 }
5952
5953 protected function sentReminder(array $a_recipient_ids)
5954 {
5955 global $DIC;
5956
5957 // use mail template
5958 if ($this->getReminderTemplate() &&
5959 array_key_exists($this->getReminderTemplate(), $this->getReminderMailTemplates())) {
5961 $templateService = $DIC['mail.texttemplates.service'];
5962 $tmpl = $templateService->loadTemplateForId((int) $this->getReminderTemplate());
5963
5964 $tmpl_params = array(
5965 "ref_id" => $this->getRefId(),
5966 "ts" => time()
5967 );
5968 } else {
5969 $tmpl = null;
5970 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
5971 }
5972
5973 foreach ($a_recipient_ids as $user_id) {
5974 if ($tmpl) {
5975 $subject = $tmpl->getSubject();
5976 $message = $this->sentReminderPlaceholders($tmpl->getMessage(), $user_id, $tmpl_params);
5977 }
5978 // use lng
5979 else {
5980 // use language of recipient to compose message
5981 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
5982 $ulng->loadLanguageModule('survey');
5983
5984 $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
5985 $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
5986
5987 $message .= $ulng->txt('survey_reminder_body') . ":\n\n";
5988 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
5989 $message .= "\n" . $ulng->txt('survey_reminder_link') . ": " . $link;
5990 }
5991
5992 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
5993 $mail_obj->appendInstallationSignature(true);
5994 $mail_obj->enqueue(
5995 ilObjUser::_lookupLogin($user_id),
5996 "",
5997 "",
5998 $subject,
5999 $message,
6000 array()
6001 );
6002 }
6003 }
6004
6005 public function setActivationStartDate($starting_time = null)
6006 {
6007 $this->activation_starting_time = $starting_time;
6008 }
6009
6010 public function setActivationEndDate($ending_time = null)
6011 {
6012 $this->activation_ending_time = $ending_time;
6013 }
6014
6015 public function getActivationStartDate()
6016 {
6017 return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : null;
6018 }
6019
6020 public function getActivationEndDate()
6021 {
6022 return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : null;
6023 }
6024
6025 public function setViewOwnResults($a_value)
6026 {
6027 $this->view_own_results = (bool) $a_value;
6028 }
6029
6030 public function hasViewOwnResults()
6031 {
6033 }
6034
6035 public function setMailOwnResults($a_value)
6036 {
6037 $this->mail_own_results = (bool) $a_value;
6038 }
6039
6040 public function hasMailOwnResults()
6041 {
6043 }
6044
6045 public function setMailConfirmation($a_value)
6046 {
6047 $this->mail_confirmation = (bool) $a_value;
6048 }
6049
6050 public function hasMailConfirmation()
6051 {
6053 }
6054
6055 public function setAnonymousUserList($a_value)
6056 {
6057 $this->anon_user_list = (bool) $a_value;
6058 }
6059
6060 public function hasAnonymousUserList()
6061 {
6062 return $this->anon_user_list;
6063 }
6064
6065 public static function getSurveySkippedValue()
6066 {
6067 global $DIC;
6068
6069 $lng = $DIC->language();
6070
6071 // #13541
6072
6073 $surveySetting = new ilSetting("survey");
6074 if (!$surveySetting->get("skipped_is_custom", false)) {
6075 return $lng->txt("skipped");
6076 } else {
6077 return $surveySetting->get("skipped_custom_value", "");
6078 }
6079 }
6080
6085 public function getReminderMailTemplates(&$defaultTemplateId = null)
6086 {
6087 global $DIC;
6088
6089 $res = array();
6090
6092 $templateService = $DIC['mail.texttemplates.service'];
6093 foreach ($templateService->loadTemplatesForContextId((string) ilSurveyMailTemplateReminderContext::ID) as $tmpl) {
6094 $res[$tmpl->getTplId()] = $tmpl->getTitle();
6095 if (null !== $defaultTemplateId && $tmpl->isDefault()) {
6096 $defaultTemplateId = $tmpl->getTplId();
6097 }
6098 }
6099
6100 return $res;
6101 }
6102
6103 protected function sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
6104 {
6105 // see ilMail::replacePlaceholders()
6106 try {
6108
6109 $user = new \ilObjUser($a_user_id);
6110
6111 $processor = new \ilMailTemplatePlaceholderResolver($context, $a_message);
6112 $a_message = $processor->resolve($user, $a_context_params);
6113 } catch (\Exception $e) {
6114 ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
6115 }
6116
6117 return $a_message;
6118 }
6119
6120 public function setMode($a_value)
6121 {
6122 $this->mode = $a_value;
6123 }
6124
6125 public function getMode()
6126 {
6127 return $this->mode;
6128 }
6129
6130 public function setSelfEvaluationResults($a_value)
6131 {
6132 $this->mode_self_eval_results = $a_value;
6133 }
6134
6136 {
6138 }
6139
6140 public static function getSurveysWithTutorResults()
6141 {
6142 global $ilDB;
6143
6144 $res = array();
6145
6147
6148
6149 $q = "SELECT obj_fi FROM svy_svy" .
6150 " WHERE tutor_res_cron IS NULL" .
6151 " AND tutor_res_status = " . $ilDB->quote(1, "integer") .
6152 " AND enddate < " . $ilDB->quote(date("Ymd000000"), "text");
6153
6154 if (DEVMODE) {
6155 $q = "SELECT obj_fi FROM svy_svy" .
6156 " WHERE tutor_res_status = " . $ilDB->quote(1, "integer") .
6157 " AND enddate < " . $ilDB->quote(date("Ymd000000"), "text");
6158 }
6159
6160 $set = $ilDB->query($q);
6161
6162 $log->debug($q);
6163
6164 while ($row = $ilDB->fetchAssoc($set)) {
6165 $res[] = $row["obj_fi"];
6166 }
6167
6168 return $res;
6169 }
6170
6171 public function sendTutorResults()
6172 {
6173 global $ilCtrl, $ilDB;
6174
6176
6177 include_once "./Services/Mail/classes/class.ilMail.php";
6178 include_once "./Services/User/classes/class.ilObjUser.php";
6179 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6180 include_once "./Services/User/classes/class.ilUserUtil.php";
6181
6182 include_once "./Services/Link/classes/class.ilLink.php";
6183 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6184
6185 // somehow needed in cron-calls
6186 //$ilCtrl->setTargetScript("ilias.php");
6187 //$ilCtrl->initBaseClass("ilobjsurveygui");
6188
6189 // yeah, I know...
6190 $old_ref_id = $_GET["ref_id"];
6191 $old_base_class = $_GET["baseClass"];
6192 $_GET["ref_id"] = $this->getRefId();
6193 $ilCtrl->setTargetScript("ilias.php");
6194 $_GET["baseClass"] = "ilObjSurveyGUI";
6195
6196 $ilCtrl->setParameterByClass("ilSurveyEvaluationGUI", "ref_id", $this->getRefId());
6197
6198 try {
6199 $gui = new ilSurveyEvaluationGUI($this);
6200 $html = $gui->evaluation(1, true, true);
6201 } catch (Exception $exception) {
6202 $_GET["ref_id"] = $old_ref_id;
6203 $_GET["baseClass"] = $old_base_class;
6204 throw $exception;
6205 }
6206 $_GET["ref_id"] = $old_ref_id;
6207 $_GET["baseClass"] = $old_base_class;
6208
6209 $html = preg_replace("/\?dummy\=[0-9]+/", "", $html);
6210 $html = preg_replace("/\?vers\=[0-9A-Za-z\-]+/", "", $html);
6211 $html = str_replace('.css$Id$', ".css", $html);
6212 $html = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $html);
6213 $html = preg_replace("/href=\"\\.\\//ims", "href=\"" . ILIAS_HTTP_PATH . "/", $html);
6214
6215 $log->debug("--pdf start, ref id " . $this->getRefId());
6216 $log->debug("html length: " . strlen($html));
6217 $log->debug("html (first 1000 chars): " . substr($html, 0, 1000));
6218 //echo $html; exit;
6219 $pdf_factory = new ilHtmlToPdfTransformerFactory();
6220 $attachment_filename = "survey_" . $this->getRefId() . "_" . (new DateTimeImmutable('now'))->format('Ymd_His') . ".pdf";
6221 $pdf = $pdf_factory->deliverPDFFromHTMLString(
6222 $html,
6223 $attachment_filename,
6225 "Survey",
6226 "Results"
6227 );
6228 $log->debug("--pdf end");
6229
6230 if (!$pdf ||
6231 !file_exists($pdf)) {
6232 return false;
6233 }
6234
6235 // prepare mail attachment
6236 require_once 'Services/Mail/classes/class.ilFileDataMail.php';
6237 $mail_data = new ilFileDataMail(ANONYMOUS_USER_ID);
6238 $mail_data->copyAttachmentFile($pdf, $attachment_filename);
6239
6240 foreach ($this->getTutorResultsRecipients() as $user_id) {
6241 // use language of recipient to compose message
6242 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6243 $ulng->loadLanguageModule('survey');
6244
6245 $subject = sprintf($ulng->txt('survey_results_tutor_subject'), $this->getTitle());
6246 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
6247
6248 $message .= $ulng->txt('survey_results_tutor_body') . ":\n\n";
6249 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
6250 $message .= "\n" . $ulng->txt('survey_notification_tutor_link') . ": " . $link;
6251
6252 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6253 $mail_obj->appendInstallationSignature(true);
6254 $log->debug("send mail to user id: " . $user_id . ",login: " . ilObjUser::_lookupLogin($user_id));
6255 $mail_obj->enqueue(
6256 ilObjUser::_lookupLogin($user_id),
6257 "",
6258 "",
6259 $subject,
6260 $message,
6261 array($attachment_filename)
6262 );
6263 }
6264
6265 $ilDB->manipulate("UPDATE svy_svy" .
6266 " SET tutor_res_cron = " . $ilDB->quote(1, "integer") .
6267 " WHERE survey_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
6268
6269 return true;
6270 }
6271
6276 public function getMaxSumScore() : int
6277 {
6278 $sum_score = 0;
6280 $sum_score += call_user_func([$c, "getMaxSumScore"], $this->getSurveyId());
6281 }
6282 return $sum_score;
6283 }
6284} // END class.ilObjSurvey
$result
user()
Definition: user.php:4
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$size
Definition: RandomTest.php:84
$total
Definition: Utf8Test.php:87
$_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
return true
Flag indicating whether or not HTTP headers will be sent when outputting captcha image/audio.
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.
Class ilFileDataMail.
Class ilHtmlToPdfTransformerFactory.
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.
static _getQuestionClasses()
Get question classes.
Class ilObjSurvey.
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.
modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle, $compress_view=false)
Modifies a question block.
setActivationVisibility($a_value)
setTutorResultsStatus($a_value)
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 The question is appended to t...
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.
getCalculateSumScore()
Get calculate sum score.
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...
getMaxSumScore()
Get max sum score.
setStartDateAndTime($start_date="", $start_time)
Sets the start date of the survey.
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)
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)
setTutorResultsRecipients(array $a_value)
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.
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.
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)
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.
getExternalCodeRecipients($a_check_finished=false)
toXML()
Returns a QTI xml representation of the survey.
getEvaluationAccess()
Gets the learners evaluation access.
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.
static getSurveysWithTutorResults()
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)
& getSurveyParticipants($finished_ids=null, $force_non_anonymous=false, $include_invites=false)
const ANONYMIZE_FREEACCESS
saveQuestionsToDb()
Saves the survey questions to the database.
updateOrder(array $a_order)
createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions, $compress_view=false)
Creates a question block for the survey.
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)
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.
setCalculateSumScore(bool $a_val)
Set calculate sum score.
static _addQuestionblock($title="", $owner=0, $show_questiontext=true, $show_blocktitle=false, $compress_view=false)
Adds a questionblock to the database.
getFinishedIdsForSelfEval($a_user_id)
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.
& 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.
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 _lookupName($a_user_id)
lookup user name
static _lookupFullname($a_user_id)
Lookup Full Name.
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
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 evaluation graphical output.
Survey exception class.
Skill tresholds for 360 surveys.
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 moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
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 unzip(string $path_to_zip_file, bool $overwrite_existing=false, bool $unpack_flat=false)
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 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.
$c
Definition: cli.php:37
$app
Definition: cli.php:38
const IL_INST_ID
Definition: constants.php:38
const ANONYMOUS_USER_ID
Definition: constants.php:25
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
global $DIC
Definition: goto.php:24
$mobs
Definition: imgupload.php:54
$ilUser
Definition: imgupload.php:18
xslt_error(&$proc)
xslt_free(&$proc)
xslt_create()
if($format !==null) $name
Definition: metadata.php:230
$index
Definition: metadata.php:128
if(!array_key_exists('PATH_INFO', $_SERVER)) $config
Definition: metadata.php:68
$i
Definition: metadata.php:24
$source
Definition: metadata.php:76
$xml
Definition: metadata.php:332
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
$url
foreach($_POST as $key=> $value) $res
global $ilDB
$data
Definition: storeScorm.php:23
$context
Definition: webdav.php:26
$messages
Definition: xapiexit.php:5
$lang
Definition: xapiexit.php:8
$message
Definition: xapiexit.php:14
$rows
Definition: xhr_table.php:10