ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
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 $user;
18
22 protected $access;
23
27 protected $plugin_admin;
28
32
33
34 const ANONYMIZE_OFF = 0; // personalized, no codes
35 const ANONYMIZE_ON = 1; // anonymized, codes
36 const ANONYMIZE_FREEACCESS = 2; // anonymized, no codes
37 const ANONYMIZE_CODE_ALL = 3; // personalized, codes
38
41
42 // constants to define the print view values.
43 const PRINT_HIDE_LABELS = 1; // Show only the titles in "print" and "PDF Export"
44 const PRINT_SHOW_LABELS = 3; // Show titles and labels in "print" and "PDF Export"
45
52 public $survey_id;
53
60 public $author;
61
68
74 public $outro;
75
76
83
90
96 public $end_date;
97
104
105
111
117
124
130
134 protected $log;
135
139
140 // 360°
141 protected $mode_360_self_eval; // [bool]
142 protected $mode_360_self_appr; // [bool]
143 protected $mode_360_self_rate; // [bool]
144 protected $mode_360_results; // [int]
145 protected $mode_skill_service; // [bool]
146
150
151 // reminder/notification
152 protected $reminder_status; // [bool]
153 protected $reminder_start; // [ilDate]
154 protected $reminder_end; // [ilDate]
155 protected $reminder_frequency; // [int]
156 protected $reminder_target; // [int]
157 protected $reminder_last_sent; // [bool]
158 protected $reminder_tmpl; // [int]
159 protected $tutor_ntf_status; // [bool]
160 protected $tutor_ntf_recipients; // [array]
161 protected $tutor_ntf_target; // [int]
162 protected $tutor_res_status; // [bool]
163 protected $tutor_res_recipients; // [array]
164
165 protected $view_own_results; // [bool]
166 protected $mail_own_results; // [bool]
167 protected $mail_confirmation; // [bool]
168
169 protected $anon_user_list; // [bool]
170
176
177 protected $mode; //[int]
178 protected $mode_self_eval_results; //[int]
179
180 //MODE TYPES
181 const MODE_STANDARD = 0;
182 const MODE_360 = 1;
183 const MODE_SELF_EVAL = 2;
184
185 //self evaluation only access to results
189
190
195
202 public function __construct($a_id = 0, $a_call_by_reference = true)
203 {
204 global $DIC;
205
206 $this->user = $DIC->user();
207 $this->lng = $DIC->language();
208 $this->db = $DIC->database();
209 $this->access = $DIC->access();
210 $this->log = $DIC["ilLog"];
211 $this->plugin_admin = $DIC["ilPluginAdmin"];
212 $this->tree = $DIC->repositoryTree();
213 $ilUser = $DIC->user();
214 $lng = $DIC->language();
215
216 $this->type = "svy";
217 $this->survey_id = -1;
218 $this->introduction = "";
219 $this->outro = $lng->txt("survey_finished");
220 $this->author = $ilUser->getFullname();
221 $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
222 $this->questions = array();
223 $this->anonymize = self::ANONYMIZE_OFF;
224 $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
225 $this->surveyCodeSecurity = true;
226 $this->template_id = null;
227 $this->pool_usage = true;
228 $this->log = ilLoggerFactory::getLogger("svy");
229 $this->mode = self::MODE_STANDARD;
230 $this->mode_self_eval_results = self::RESULTS_SELF_EVAL_OWN;
231
232 $this->invitation_manager = new Participants\InvitationsManager();
233
234 parent::__construct($a_id, $a_call_by_reference);
235 }
236
240 public function create($a_upload = false)
241 {
242 parent::create();
243 if (!$a_upload) {
244 $this->createMetaData();
245 }
246 $this->setOfflineStatus(true);
247 $this->update($a_upload);
248 }
249
255 public function createMetaData()
256 {
257 parent::createMetaData();
258 $this->saveAuthorToMetadata();
259 }
260
267 public function update($a_upload = false)
268 {
269 if (!$a_upload) {
270 $this->updateMetaData();
271 }
272
273 if (!parent::update()) {
274 return false;
275 }
276
277 // put here object specific stuff
278
279 return true;
280 }
281
282 public function createReference()
283 {
284 $result = parent::createReference();
285 $this->saveToDb();
286 return $result;
287 }
288
293 public function read()
294 {
295 parent::read();
296 $this->loadFromDb();
297 }
298
305 public function addQuestion($question_id)
306 {
307 array_push($this->questions, $question_id);
308 }
309
316 public function delete()
317 {
318 if ($this->countReferences() == 1) {
319 $this->deleteMetaData();
320
321 // Delete all survey questions, constraints and materials
322 foreach ($this->questions as $question_id) {
323 $this->removeQuestion($question_id);
324 }
325 $this->deleteSurveyRecord();
326
328 }
329
330 $remove = parent::delete();
331
332 // always call parent delete function first!!
333 if (!$remove) {
334 return false;
335 }
336 return true;
337 }
338
344 public function deleteSurveyRecord()
345 {
347
348 $affectedRows = $ilDB->manipulateF(
349 "DELETE FROM svy_svy WHERE survey_id = %s",
350 array('integer'),
351 array($this->getSurveyId())
352 );
353
354 $result = $ilDB->queryF(
355 "SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
356 array('integer'),
357 array($this->getSurveyId())
358 );
359 $questionblocks = array();
360 while ($row = $ilDB->fetchAssoc($result)) {
361 array_push($questionblocks, $row["questionblock_fi"]);
362 }
363 if (count($questionblocks)) {
364 $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
365 }
366 $affectedRows = $ilDB->manipulateF(
367 "DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
368 array('integer'),
369 array($this->getSurveyId())
370 );
371 $this->deleteAllUserData(false);
372
373 $affectedRows = $ilDB->manipulateF(
374 "DELETE FROM svy_anonymous WHERE survey_fi = %s",
375 array('integer'),
376 array($this->getSurveyId())
377 );
378
379 // delete export files
380 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
381 $directory = $svy_data_dir . "/svy_" . $this->getId();
382 if (is_dir($directory)) {
383 ilUtil::delDir($directory);
384 }
385
386 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
387 // remaining usages are not in text anymore -> delete them
388 // and media objects (note: delete method of ilObjMediaObject
389 // checks whether object is used in another context; if yes,
390 // the object is not deleted!)
391 foreach ($mobs as $mob) {
392 ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
393 $mob_obj = new ilObjMediaObject($mob);
394 $mob_obj->delete();
395 }
396 }
397
404 public function deleteAllUserData($reset_LP = true)
405 {
407
408 $result = $ilDB->queryF(
409 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
410 array('integer'),
411 array($this->getSurveyId())
412 );
413 $active_array = array();
414 while ($row = $ilDB->fetchAssoc($result)) {
415 array_push($active_array, $row["finished_id"]);
416 }
417
418 $affectedRows = $ilDB->manipulateF(
419 "DELETE FROM svy_finished WHERE survey_fi = %s",
420 array('integer'),
421 array($this->getSurveyId())
422 );
423
424 foreach ($active_array as $active_fi) {
425 $affectedRows = $ilDB->manipulateF(
426 "DELETE FROM svy_answer WHERE active_fi = %s",
427 array('integer'),
428 array($active_fi)
429 );
430 $affectedRows = $ilDB->manipulateF(
431 "DELETE FROM svy_times WHERE finished_fi = %s",
432 array('integer'),
433 array($active_fi)
434 );
435 }
436
437 if ($reset_LP) {
438 $lp_obj = ilObjectLP::getInstance($this->getId());
439 $lp_obj->resetLPDataForCompleteObject();
440 }
441 }
442
448 public function removeSelectedSurveyResults($finished_ids)
449 {
451
452 $user_ids[] = array();
453
454 foreach ($finished_ids as $finished_id) {
455 $result = $ilDB->queryF(
456 "SELECT finished_id FROM svy_finished WHERE finished_id = %s",
457 array('integer'),
458 array($finished_id)
459 );
460 $row = $ilDB->fetchAssoc($result);
461
462 if ($row["user_fi"]) {
463 $user_ids[] = $row["user_fi"];
464 }
465
466 $affectedRows = $ilDB->manipulateF(
467 "DELETE FROM svy_answer WHERE active_fi = %s",
468 array('integer'),
469 array($row["finished_id"])
470 );
471
472 $affectedRows = $ilDB->manipulateF(
473 "DELETE FROM svy_finished WHERE finished_id = %s",
474 array('integer'),
475 array($finished_id)
476 );
477
478 $affectedRows = $ilDB->manipulateF(
479 "DELETE FROM svy_times WHERE finished_fi = %s",
480 array('integer'),
481 array($row["finished_id"])
482 );
483 }
484
485 if (sizeof($user_ids)) {
486 $lp_obj = ilObjectLP::getInstance($this->getId());
487 $lp_obj->resetLPDataForUserIds($user_ids);
488 }
489 }
490
491 public function &getSurveyParticipants($finished_ids = null, $force_non_anonymous = false, $include_invites = false)
492 {
494
495 $sql = "SELECT * FROM svy_finished" .
496 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
497 if ($finished_ids) {
498 $sql .= " AND " . $ilDB->in("finished_id", $finished_ids, "", "integer");
499 }
500
501 $result = $ilDB->query($sql);
502 $participants = array();
503 if ($result->numRows() > 0) {
504 while ($row = $ilDB->fetchAssoc($result)) {
505 $userdata = $this->getUserDataFromActiveId($row["finished_id"], $force_non_anonymous);
506 $userdata["finished"] = (bool) $row["state"];
507 $userdata["finished_tstamp"] = $row["tstamp"];
508 $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
509 }
510 }
511 $participant_ids = array_column($participants, "usr_id");
512 if ($include_invites) {
513 foreach ($this->invitation_manager->getAllForSurvey($this->getSurveyId()) as $usr_id) {
514 if (!in_array($usr_id, $participant_ids)) {
515 $name = ilObjUser::_lookupName($usr_id);
516 $participants[$name["lastname"] . "," . $name["firstname"] . $usr_id] = [
517 "fullname" => ilObjUser::_lookupFullname($usr_id),
518 "sortname" => $name["lastname"] . "," . $name["firstname"],
519 "fistname" => $name["firstname"],
520 "lastname" => $name["lastname"],
521 "login" => $name["login"],
522 "gender" => "",
523 "usr_id" => $usr_id,
524 "finished" => false,
525 "finished_tstamp" => 0,
526 "invited" => true
527 ];
528 }
529 }
530 }
531
532 return $participants;
533 }
534
541 public function isComplete()
542 {
543 if (($this->getTitle()) and (count($this->questions))) {
544 return 1;
545 } else {
546 return 0;
547 }
548 }
549
555 public function saveCompletionStatus()
556 {
558
559 $complete = 0;
560 if ($this->isComplete()) {
561 $complete = 1;
562 }
563 if ($this->getSurveyId() > 0) {
564 $affectedRows = $ilDB->manipulateF(
565 "UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
566 array('text','integer','integer'),
567 array($this->isComplete(), time(), $this->getSurveyId())
568 );
569 }
570 }
571
579 public function duplicateQuestionForSurvey($question_id, $a_force = false)
580 {
582
583 $questiontype = $this->getQuestionType($question_id);
584 $question_gui = $this->getQuestionGUI($questiontype, $question_id);
585
586 // check if question is a pool question at all, if not do nothing
587 if ($this->getId() == $question_gui->object->getObjId() && !$a_force) {
588 return $question_id;
589 }
590
591 $duplicate_id = $question_gui->object->duplicate(true, "", "", "", $this->getId());
592 return $duplicate_id;
593 }
594
600 public function insertQuestion($question_id)
601 {
603
604 $this->log->debug("insert question, id:" . $question_id);
605
606 if (!SurveyQuestion::_isComplete($question_id)) {
607 $this->log->debug("question is not complete");
608 return false;
609 } else {
610 // get maximum sequence index in test
611 // @todo: refactor this
612 $result = $ilDB->queryF(
613 "SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
614 array('integer'),
615 array($this->getSurveyId())
616 );
617 $sequence = $result->numRows();
618 $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
619 $this->log->debug("duplicate, id: " . $question_id . ", duplicate id: " . $duplicate_id);
620
621 // check if question is not already in the survey, see #22018
622 if ($this->isQuestionInSurvey($duplicate_id)) {
623 return false;
624 }
625
626 $next_id = $ilDB->nextId('svy_svy_qst');
627 $affectedRows = $ilDB->manipulateF(
628 "INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
629 array('integer', 'integer', 'integer', 'integer', 'integer'),
630 array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
631 );
632
633 $this->log->debug("added entry to svy_svy_qst, id: " . $next_id . ", question id: " . $duplicate_id . ", sequence: " . $sequence);
634
635 $this->loadQuestionsFromDb();
636 return true;
637 }
638 }
639
646 public function isQuestionInSurvey($a_question_fi)
647 {
648 global $DIC;
649 //return false;
650 $ilDB = $DIC->database();
651
652 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
653 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
654 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
655 if ($rec = $ilDB->fetchAssoc($set)) {
656 return true;
657 }
658 return false;
659 }
660
661
662
668 public function insertQuestionblock($questionblock_id)
669 {
671 $result = $ilDB->queryF(
672 "SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle," .
673 " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst" .
674 " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi" .
675 " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi" .
676 " AND svy_qblk.questionblock_id = %s" .
677 " ORDER BY svy_svy_qst.sequence",
678 array('integer'),
679 array($questionblock_id)
680 );
681 $questions = array();
682 $show_questiontext = 0;
683 $show_blocktitle = 0;
684 while ($row = $ilDB->fetchAssoc($result)) {
685 $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
686 array_push($questions, $duplicate_id);
687 $title = $row["title"];
688 $show_questiontext = $row["show_questiontext"];
689 $show_blocktitle = $row["show_blocktitle"];
690 }
691 $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
692 }
693
694 public function saveUserSettings($usr_id, $key, $title, $value)
695 {
697
698 $next_id = $ilDB->nextId('svy_settings');
699 $affectedRows = $ilDB->insert("svy_settings", array(
700 "settings_id" => array("integer", $next_id),
701 "usr_id" => array("integer", $usr_id),
702 "keyword" => array("text", $key),
703 "title" => array("text", $title),
704 "value" => array("clob", $value)
705 ));
706 }
707
708 public function deleteUserSettings($id)
709 {
711
712 $affectedRows = $ilDB->manipulateF(
713 "DELETE FROM svy_settings WHERE settings_id = %s",
714 array('integer'),
715 array($id)
716 );
717 return $affectedRows;
718 }
719
720 public function getUserSettings($usr_id, $key)
721 {
723
724 $result = $ilDB->queryF(
725 "SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
726 array('integer', 'text'),
727 array($usr_id, $key)
728 );
729 $found = array();
730 if ($result->numRows()) {
731 while ($row = $ilDB->fetchAssoc($result)) {
732 $found[$row['settings_id']] = $row;
733 }
734 }
735 return $found;
736 }
737
743 public function saveToDb()
744 {
746
747 // date handling
748 $rmd_start = $this->getReminderStart();
749 if (is_object($rmd_start)) {
750 $rmd_start = $rmd_start->get(IL_CAL_DATE);
751 }
752 $rmd_end = $this->getReminderEnd();
753 if (is_object($rmd_end)) {
754 $rmd_end = $rmd_end->get(IL_CAL_DATE);
755 }
756
757 if ($this->getSurveyId() < 1) {
758 $next_id = $ilDB->nextId('svy_svy');
759 $affectedRows = $ilDB->insert("svy_svy", array(
760 "survey_id" => array("integer", $next_id),
761 "obj_fi" => array("integer", $this->getId()),
762 "author" => array("text", $this->getAuthor()),
763 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
764 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
765 "startdate" => array("text", $this->getStartDate()),
766 "enddate" => array("text", $this->getEndDate()),
767 "evaluation_access" => array("text", $this->getEvaluationAccess()),
768 "complete" => array("text", $this->isComplete()),
769 "created" => array("integer", time()),
770 "anonymize" => array("text", $this->getAnonymize()),
771 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
772 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
773 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
774 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
775 "tstamp" => array("integer", time()),
776 "template_id" => array("integer", $this->getTemplate()),
777 "pool_usage" => array("integer", $this->getPoolUsage()),
778 // Mode type
779 "mode" => array("integer", $this->getMode()),
780 // 360°
781 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
782 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
783 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
784 "mode_360_results" => array("integer", $this->get360Results()),
785 // competences
786 "mode_skill_service" => array("integer", (int) $this->getSkillService()),
787 // Self Evaluation Only
788 "mode_self_eval_results" => array("integer", ilObjSurvey::RESULTS_SELF_EVAL_OWN),
789 // reminder/notification
790 "reminder_status" => array("integer", (int) $this->getReminderStatus()),
791 "reminder_start" => array("datetime", $rmd_start),
792 "reminder_end" => array("datetime", $rmd_end),
793 "reminder_frequency" => array("integer", (int) $this->getReminderFrequency()),
794 "reminder_target" => array("integer", (int) $this->getReminderTarget()),
795 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
796 "reminder_tmpl" => array("text", $this->getReminderTemplate(true)),
797 "tutor_ntf_status" => array("integer", (int) $this->getTutorNotificationStatus()),
798 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
799 "tutor_ntf_target" => array("integer", (int) $this->getTutorNotificationTarget()),
800 "own_results_view" => array("integer", $this->hasViewOwnResults()),
801 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
802 "tutor_res_status" => array("integer", (int) $this->getTutorResultsStatus()),
803 "tutor_res_reci" => array("text", implode(";", (array) $this->getTutorResultsRecipients())),
804 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
805 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
806 ));
807 $this->setSurveyId($next_id);
808 } else {
809 $affectedRows = $ilDB->update("svy_svy", array(
810 "author" => array("text", $this->getAuthor()),
811 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
812 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
813 "startdate" => array("text", $this->getStartDate()),
814 "enddate" => array("text", $this->getEndDate()),
815 "evaluation_access" => array("text", $this->getEvaluationAccess()),
816 "complete" => array("text", $this->isComplete()),
817 "anonymize" => array("text", $this->getAnonymize()),
818 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
819 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
820 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : null),
821 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : null),
822 "tstamp" => array("integer", time()),
823 "template_id" => array("integer", $this->getTemplate()),
824 "pool_usage" => array("integer", $this->getPoolUsage()),
825 //MODE TYPE
826 "mode" => array("integer", $this->getMode()),
827 // 360°
828 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
829 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
830 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
831 "mode_360_results" => array("integer", $this->get360Results()),
832 // Competences
833 "mode_skill_service" => array("integer", (int) $this->getSkillService()),
834 // Self Evaluation Only
835 "mode_self_eval_results" => array("integer", $this->getSelfEvaluationResults()),
836 // reminder/notification
837 "reminder_status" => array("integer", $this->getReminderStatus()),
838 "reminder_start" => array("datetime", $rmd_start),
839 "reminder_end" => array("datetime", $rmd_end),
840 "reminder_frequency" => array("integer", $this->getReminderFrequency()),
841 "reminder_target" => array("integer", $this->getReminderTarget()),
842 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
843 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
844 "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
845 "tutor_ntf_reci" => array("text", implode(";", (array) $this->getTutorNotificationRecipients())),
846 "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget()),
847 "own_results_view" => array("integer", $this->hasViewOwnResults()),
848 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
849 "tutor_res_status" => array("integer", (int) $this->getTutorResultsStatus()),
850 "tutor_res_reci" => array("text", implode(";", (array) $this->getTutorResultsRecipients())),
851 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
852 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
853 ), array(
854 "survey_id" => array("integer", $this->getSurveyId())
855 ));
856 }
857 if ($affectedRows) {
858 // save questions to db
859 $this->saveQuestionsToDb();
860 }
861
862 // moved activation to ilObjectActivation
863 if ($this->ref_id) {
864 ilObjectActivation::getItem($this->ref_id);
865
866 $item = new ilObjectActivation;
867 if (!$this->isActivationLimited()) {
869 } else {
870 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
871 $item->setTimingStart($this->getActivationStartDate());
872 $item->setTimingEnd($this->getActivationEndDate());
873 $item->toggleVisible($this->getActivationVisibility());
874 }
875
876 $item->update($this->ref_id);
877 }
878 }
879
886 public function saveQuestionsToDb()
887 {
889
890 $this->log->debug("save questions");
891
892 // gather old questions state
893 $old_questions = array();
894 $result = $ilDB->queryF(
895 "SELECT survey_question_id,question_fi,sequence" .
896 " FROM svy_svy_qst WHERE survey_fi = %s",
897 array('integer'),
898 array($this->getSurveyId())
899 );
900 while ($row = $ilDB->fetchAssoc($result)) {
901 $old_questions[$row["question_fi"]] = $row; // problem, as soon as duplicates exist, they will be hidden here
902 }
903
904 // #15231 - diff with current questions state
905 $insert = $update = $delete = array();
906 foreach ($this->questions as $seq => $fi) {
907 if (!array_key_exists($fi, $old_questions)) { // really new fi IDs
908 $insert[] = $fi; // this should be ok, should not create duplicates here
909 } elseif ($old_questions[$fi]["sequence"] != $seq) { // we are updating one of the duplicates (if any)
910 $update[$fi] = $old_questions[$fi]["survey_question_id"];
911 }
912 // keep track of still relevant questions
913 unset($old_questions[$fi]); // deleting old question, if they are not in current array
914 }
915
916 // delete obsolete question relations
917 if (sizeof($old_questions)) {
918 $del_ids = array();
919 foreach ($old_questions as $fi => $old) {
920 $del_ids[] = $old["survey_question_id"];
921 }
922 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
923 " WHERE " . $ilDB->in("survey_question_id", $del_ids, "", "integer"));
924 $this->log->debug("delete: " . $q);
925 }
926 unset($old_questions);
927
928 // create/update question relations
929 foreach ($this->questions as $seq => $fi) {
930 if (in_array($fi, $insert)) {
931 // check if question is not already in the survey, see #22018
932 if (!$this->isQuestionInSurvey($fi)) {
933 $next_id = $ilDB->nextId('svy_svy_qst');
934 $ilDB->manipulateF(
935 "INSERT INTO svy_svy_qst" .
936 " (survey_question_id, survey_fi, question_fi, heading, sequence, tstamp)" .
937 " VALUES (%s, %s, %s, %s, %s, %s)",
938 array('integer', 'integer', 'integer', 'text', 'integer', 'integer'),
939 array($next_id, $this->getSurveyId(), $fi, null, $seq, time())
940 );
941 $this->log->debug("insert svy_svy_qst, id:" . $next_id . ", fi: " . $fi . ", seq:" . $seq);
942 }
943 } elseif (array_key_exists($fi, $update)) {
944 $ilDB->manipulate("UPDATE svy_svy_qst" .
945 " SET sequence = " . $ilDB->quote($seq, "integer") .
946 ", tstamp = " . $ilDB->quote(time(), "integer") .
947 " WHERE survey_question_id = " . $ilDB->quote($update[$fi], "integer"));
948 $this->log->debug("update svy_svy_qst, id:" . $update[$fi] . ", fi: " . $fi . ", seq:" . $seq);
949 }
950 }
951 }
952
960 public function getAnonymousId($id)
961 {
963 $result = $ilDB->queryF(
964 "SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
965 array('text'),
966 array($id)
967 );
968 if ($result->numRows()) {
969 $row = $ilDB->fetchAssoc($result);
970 return $row["anonymous_id"];
971 } else {
972 return "";
973 }
974 }
975
982 public function getQuestionGUI($questiontype, $question_id)
983 {
984 return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
985 }
986
994 public function getQuestionType($question_id)
995 {
997 if ($question_id < 1) {
998 return -1;
999 }
1000 $result = $ilDB->queryF(
1001 "SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
1002 "svy_question.questiontype_fi = svy_qtype.questiontype_id",
1003 array('integer'),
1004 array($question_id)
1005 );
1006 if ($result->numRows() == 1) {
1007 $data = $ilDB->fetchAssoc($result);
1008 return $data["type_tag"];
1009 } else {
1010 return "";
1011 }
1012 }
1013
1020 public function getSurveyId()
1021 {
1022 return $this->survey_id;
1023 }
1024
1028 public function setAnonymize($a_anonymize)
1029 {
1030 switch ($a_anonymize) {
1032 case self::ANONYMIZE_ON:
1035 $this->anonymize = $a_anonymize;
1036 break;
1037 default:
1038 $this->anonymize = self::ANONYMIZE_OFF;
1039 break;
1040 }
1041 }
1042
1048 public function getAnonymize()
1049 {
1050 return ($this->anonymize) ? $this->anonymize : 0;
1051 }
1052
1058 public function isAccessibleWithoutCode()
1059 {
1060 return ($this->getAnonymize() == self::ANONYMIZE_OFF ||
1061 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1062 }
1063
1069 public function hasAnonymizedResults()
1070 {
1071 return ($this->getAnonymize() == self::ANONYMIZE_ON ||
1072 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1073 }
1074
1080 public function loadFromDb()
1081 {
1082 $ilDB = $this->db;
1083 $result = $ilDB->queryF(
1084 "SELECT * FROM svy_svy WHERE obj_fi = %s",
1085 array('integer'),
1086 array($this->getId())
1087 );
1088 if ($result->numRows() == 1) {
1089 $data = $ilDB->fetchAssoc($result);
1090 $this->setSurveyId($data["survey_id"]);
1091 $this->setAuthor($data["author"]);
1092 $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1093 if (strcmp($data["outro"], "survey_finished") == 0) {
1094 $this->setOutro($this->lng->txt("survey_finished"));
1095 } else {
1097 }
1098 $this->setShowQuestionTitles($data["show_question_titles"]);
1099 $this->setStartDate($data["startdate"]);
1100 $this->setEndDate($data["enddate"]);
1101 $this->setAnonymize($data["anonymize"]);
1102 $this->setEvaluationAccess($data["evaluation_access"]);
1103 $this->loadQuestionsFromDb();
1104 $this->setMailNotification($data['mailnotification']);
1105 $this->setMailAddresses($data['mailaddresses']);
1106 $this->setMailParticipantData($data['mailparticipantdata']);
1107 $this->setTemplate($data['template_id']);
1108 $this->setPoolUsage($data['pool_usage']);
1109 // Mode
1110 $this->setMode($data['mode']);
1111 // 360°
1112 $this->set360SelfEvaluation($data['mode_360_self_eval']);
1113 $this->set360SelfRaters($data['mode_360_self_rate']);
1114 $this->set360SelfAppraisee($data['mode_360_self_appr']);
1115 $this->set360Results($data['mode_360_results']);
1116 // Mode self evaluated
1117 $this->setSelfEvaluationResults($data['mode_self_eval_results']);
1118 // Competences
1119 $this->setSkillService($data['mode_skill_service']);
1120 // reminder/notification
1121 $this->setReminderStatus($data["reminder_status"]);
1122 $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1123 $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1124 $this->setReminderFrequency($data["reminder_frequency"]);
1125 $this->setReminderTarget($data["reminder_target"]);
1126 $this->setReminderLastSent($data["reminder_last_sent"]);
1127 $this->setReminderTemplate($data["reminder_tmpl"]);
1128 $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1129 $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1130 $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1131 $this->setTutorResultsStatus($data["tutor_res_status"]);
1132 $this->setTutorResultsRecipients(explode(";", $data["tutor_res_reci"]));
1133
1134 $this->setViewOwnResults($data["own_results_view"]);
1135 $this->setMailOwnResults($data["own_results_mail"]);
1136 $this->setMailConfirmation($data["confirmation_mail"]);
1137
1138 $this->setAnonymousUserList($data["anon_user_list"]);
1139 }
1140
1141 // moved activation to ilObjectActivation
1142 if ($this->ref_id) {
1143 $activation = ilObjectActivation::getItem($this->ref_id);
1144 switch ($activation["timing_type"]) {
1146 $this->setActivationLimited(true);
1147 $this->setActivationStartDate($activation["timing_start"]);
1148 $this->setActivationEndDate($activation["timing_end"]);
1149 $this->setActivationVisibility($activation["visible"]);
1150 break;
1151
1152 default:
1153 $this->setActivationLimited(false);
1154 break;
1155 }
1156 }
1157 }
1158
1165 public function loadQuestionsFromDb()
1166 {
1167 $ilDB = $this->db;
1168 $this->questions = array();
1169 $result = $ilDB->queryF(
1170 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1171 array('integer'),
1172 array($this->getSurveyId())
1173 );
1174 while ($data = $ilDB->fetchAssoc($result)) {
1175 $this->questions[$data["sequence"]] = $data["question_fi"];
1176 }
1177 }
1178
1182 public function fixSequenceStructure()
1183 {
1184 global $DIC;
1185
1186 $ilDB = $DIC->database();
1187 //return;
1188 // we keep all survey question ids with their lowest sequence
1189 $result = $ilDB->queryF(
1190 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1191 array('integer'),
1192 array($this->getSurveyId())
1193 );
1194
1195 // step 1: find duplicates -> $to_delete_ids
1196 $fis = array();
1197 $to_delete_ids = array();
1198 while ($data = $ilDB->fetchAssoc($result)) {
1199 if (in_array($data["question_fi"], $fis)) { // found a duplicate
1200 $to_delete_ids[] = $data["survey_question_id"];
1201 } else {
1202 $fis[] = $data["question_fi"];
1203 }
1204 }
1205
1206 // step 2: we delete the duplicates
1207 if (count($to_delete_ids) > 0) {
1208 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
1209 " WHERE " . $ilDB->in("survey_question_id", $to_delete_ids, false, "integer") .
1210 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1211 $this->log->debug("delete: " . $q);
1212
1213 $ilDB->manipulate($q = "DELETE FROM svy_qblk_qst " .
1214 " WHERE " . $ilDB->in("question_fi", $fis, true, "integer") .
1215 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1216 $this->log->debug("delete: " . $q);
1217 }
1218
1219 // step 3: we fix the sequence
1220 $set = $ilDB->query("SELECT * FROM svy_svy_qst " .
1221 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") . " ORDER BY sequence");
1222 $seq = 0;
1223 while ($rec = $ilDB->fetchAssoc($set)) {
1224 $ilDB->manipulate(
1225 $q = "UPDATE svy_svy_qst SET " .
1226 " sequence = " . $ilDB->quote($seq++, "integer") .
1227 " WHERE survey_question_id = " . $ilDB->quote($rec["survey_question_id"], "integer")
1228 );
1229 $this->log->debug("update: " . $q);
1230 }
1231 }
1232
1233
1241 public function setAuthor($author = "")
1242 {
1243 $this->author = $author;
1244 }
1245
1255 public function saveAuthorToMetadata($a_author = "")
1256 {
1257 $md = new ilMD($this->getId(), 0, $this->getType());
1258 $md_life = &$md->getLifecycle();
1259 if (!$md_life) {
1260 if (strlen($a_author) == 0) {
1262 $a_author = $ilUser->getFullname();
1263 }
1264
1265 $md_life = &$md->addLifecycle();
1266 $md_life->save();
1267 $con = &$md_life->addContribute();
1268 $con->setRole("Author");
1269 $con->save();
1270 $ent = &$con->addEntity();
1271 $ent->setEntity($a_author);
1272 $ent->save();
1273 }
1274 }
1275
1283 public function getAuthor()
1284 {
1285 $author = array();
1286 $md = new ilMD($this->getId(), 0, $this->getType());
1287 $md_life = &$md->getLifecycle();
1288 if ($md_life) {
1289 $ids = &$md_life->getContributeIds();
1290 foreach ($ids as $id) {
1291 $md_cont = &$md_life->getContribute($id);
1292 if (strcmp($md_cont->getRole(), "Author") == 0) {
1293 $entids = &$md_cont->getEntityIds();
1294 foreach ($entids as $entid) {
1295 $md_ent = &$md_cont->getEntity($entid);
1296 array_push($author, $md_ent->getEntity());
1297 }
1298 }
1299 }
1300 }
1301 return join(",", $author);
1302 }
1303
1310 public function getShowQuestionTitles()
1311 {
1312 return ($this->display_question_titles) ? 1 : 0;
1313 }
1314
1321 public function setShowQuestionTitles($a_show)
1322 {
1323 $this->display_question_titles = ($a_show) ? 1 : 0;
1324 }
1325
1332 public function showQuestionTitles()
1333 {
1334 $this->display_question_titles = 1;
1335 }
1336
1343 public function hideQuestionTitles()
1344 {
1345 $this->display_question_titles = 0;
1346 }
1347
1354 public function setIntroduction($introduction = "")
1355 {
1356 $this->introduction = $introduction;
1357 }
1358
1365 public function setOutro($outro = "")
1366 {
1367 $this->outro = $outro;
1368 }
1369
1370
1378 public function getStartDate()
1379 {
1380 return (strlen($this->start_date)) ? $this->start_date : null;
1381 }
1382
1389 public function canStartSurvey($anonymous_id = null, $a_no_rbac = false)
1390 {
1391 $ilAccess = $this->access;
1392
1393 $result = true;
1394 $messages = array();
1395 $edit_settings = false;
1396 // check start date
1397 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches)) {
1398 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1399 $now = time();
1400 if ($now < $epoch_time) {
1401 array_push($messages, $this->lng->txt('start_date_not_reached') . ' (' .
1403 $result = false;
1404 $edit_settings = true;
1405 }
1406 }
1407 // check end date
1408 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches)) {
1409 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1410 $now = time();
1411 if ($now > $epoch_time) {
1412 array_push($messages, $this->lng->txt('end_date_reached') . ' (' .
1414 $result = false;
1415 $edit_settings = true;
1416 }
1417 }
1418
1419 // check online status
1420 if ($this->getOfflineStatus()) {
1421 array_push($messages, $this->lng->txt("survey_is_offline"));
1422 $result = false;
1423 $edit_settings = true;
1424 }
1425 // check rbac permissions
1426 if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id)) {
1427 array_push($messages, $this->lng->txt("cannot_participate_survey"));
1428 $result = false;
1429 }
1430 /*
1431 // 2. check previous access
1432 if (!$result["error"])
1433 {
1434 $ilUser = $this->user;
1435 $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1436 if ($survey_started === 1)
1437 {
1438 array_push($messages, $this->lng->txt("already_completed_survey"));
1439 $result = FALSE;
1440 }
1441 }
1442 */
1443 return array(
1444 "result" => $result,
1445 "messages" => $messages,
1446 "edit_settings" => $edit_settings
1447 );
1448 }
1449
1457 public function setStartDate($start_date = "")
1458 {
1459 $this->start_date = $start_date;
1460 }
1461
1470 public function setStartDateAndTime($start_date = "", $start_time)
1471 {
1472 $y = '';
1473 $m = '';
1474 $d = '';
1475 $h = '';
1476 $i = '';
1477 $s = '';
1478 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches)) {
1479 $y = $matches[1];
1480 $m = $matches[2];
1481 $d = $matches[3];
1482 }
1483 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches)) {
1484 $h = $matches[1];
1485 $i = $matches[2];
1486 $s = $matches[3];
1487 }
1488 $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1489 }
1490
1498 public function getEndDate()
1499 {
1500 return (strlen($this->end_date)) ? $this->end_date : null;
1501 }
1502
1510 public function setEndDate($end_date = "")
1511 {
1512 $this->end_date = $end_date;
1513 }
1514
1523 public function setEndDateAndTime($end_date = "", $end_time)
1524 {
1525 $y = '';
1526 $m = '';
1527 $d = '';
1528 $h = '';
1529 $i = '';
1530 $s = '';
1531 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches)) {
1532 $y = $matches[1];
1533 $m = $matches[2];
1534 $d = $matches[3];
1535 }
1536 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches)) {
1537 $h = $matches[1];
1538 $i = $matches[2];
1539 $s = $matches[3];
1540 }
1541 $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1542 }
1543
1551 public function getEvaluationAccess()
1552 {
1553 return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1554 }
1555
1563 public function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1564 {
1565 $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1566 }
1567
1568 public function setActivationVisibility($a_value)
1569 {
1570 $this->activation_visibility = (bool) $a_value;
1571 }
1572
1573 public function getActivationVisibility()
1574 {
1576 }
1577
1578 public function isActivationLimited()
1579 {
1580 return (bool) $this->activation_limited;
1581 }
1582
1583 public function setActivationLimited($a_value)
1584 {
1585 $this->activation_limited = (bool) $a_value;
1586 }
1587
1595 public function getIntroduction()
1596 {
1597 return (strlen($this->introduction)) ? $this->introduction : null;
1598 }
1599
1607 public function getOutro()
1608 {
1609 return (strlen($this->outro)) ? $this->outro : null;
1610 }
1611
1618 public function &getExistingQuestions()
1619 {
1620 $ilDB = $this->db;
1621 $existing_questions = array();
1622 $result = $ilDB->queryF(
1623 "SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1624 "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1625 array('integer'),
1626 array($this->getSurveyId())
1627 );
1628 while ($data = $ilDB->fetchAssoc($result)) {
1629 if ($data["original_id"]) {
1630 array_push($existing_questions, $data["original_id"]);
1631 }
1632 }
1633 return $existing_questions;
1634 }
1635
1642 public function &getQuestionpoolTitles($could_be_offline = false, $showPath = false)
1643 {
1644 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = true, $could_be_offline, $showPath);
1645 }
1646
1655 public function moveQuestions($move_questions, $target_index, $insert_mode)
1656 {
1657 $array_pos = array_search($target_index, $this->questions);
1658 if ($insert_mode == 0) {
1659 $part1 = array_slice($this->questions, 0, $array_pos);
1660 $part2 = array_slice($this->questions, $array_pos);
1661 } elseif ($insert_mode == 1) {
1662 $part1 = array_slice($this->questions, 0, $array_pos + 1);
1663 $part2 = array_slice($this->questions, $array_pos + 1);
1664 }
1665 $found = 0;
1666 foreach ($move_questions as $question_id) {
1667 if (!(array_search($question_id, $part1) === false)) {
1668 unset($part1[array_search($question_id, $part1)]);
1669 $found++;
1670 }
1671 if (!(array_search($question_id, $part2) === false)) {
1672 unset($part2[array_search($question_id, $part2)]);
1673 $found++;
1674 }
1675 }
1676 // sanity check: do not move questions if they have not be found in the array
1677 if ($found != count($move_questions)) {
1678 return;
1679 }
1680 $part1 = array_values($part1);
1681 $part2 = array_values($part2);
1682 $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1683 foreach ($move_questions as $question_id) {
1684 $constraints = $this->getConstraints($question_id);
1685 foreach ($constraints as $idx => $constraint) {
1686 foreach ($part2 as $next_question_id) {
1687 if ($constraint["question"] == $next_question_id) {
1688 // constraint concerning a question that follows -> delete constraint
1689 $this->deleteConstraint($constraint["id"]);
1690 }
1691 }
1692 }
1693 }
1694 $this->saveQuestionsToDb();
1695 }
1696
1703 public function removeQuestion($question_id)
1704 {
1705 $question = self::_instanciateQuestion($question_id);
1706 #20610 if no question found, do nothing.
1707 if ($question) {
1708 $question->delete($question_id);
1709 $this->removeConstraintsConcerningQuestion($question_id);
1710 }
1711 }
1712
1719 public function removeConstraintsConcerningQuestion($question_id)
1720 {
1721 $ilDB = $this->db;
1722 $result = $ilDB->queryF(
1723 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1724 array('integer','integer'),
1725 array($question_id, $this->getSurveyId())
1726 );
1727 if ($result->numRows() > 0) {
1728 $remove_constraints = array();
1729 while ($row = $ilDB->fetchAssoc($result)) {
1730 array_push($remove_constraints, $row["constraint_fi"]);
1731 }
1732 $affectedRows = $ilDB->manipulateF(
1733 "DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1734 array('integer','integer'),
1735 array($question_id, $this->getSurveyId())
1736 );
1737 foreach ($remove_constraints as $key => $constraint_id) {
1738 $affectedRows = $ilDB->manipulateF(
1739 "DELETE FROM svy_constraint WHERE constraint_id = %s",
1740 array('integer'),
1741 array($constraint_id)
1742 );
1743 }
1744 }
1745 }
1746
1754 public function removeQuestions($remove_questions, $remove_questionblocks)
1755 {
1756 $ilDB = $this->db;
1757
1758 $block_sizes = array();
1759 foreach ($this->getSurveyQuestions() as $question_id => $data) {
1760 if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks)) {
1761 unset($this->questions[array_search($question_id, $this->questions)]);
1762 $this->removeQuestion($question_id);
1763 } elseif ($data["questionblock_id"]) {
1764 $block_sizes[$data["questionblock_id"]]++;
1765 }
1766 }
1767
1768 // blocks with just 1 question need to be deleted
1769 foreach ($block_sizes as $block_id => $size) {
1770 if ($size < 2) {
1771 $remove_questionblocks[] = $block_id;
1772 }
1773 }
1774
1775 foreach (array_unique($remove_questionblocks) as $questionblock_id) {
1776 $affectedRows = $ilDB->manipulateF(
1777 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1778 array('integer'),
1779 array($questionblock_id)
1780 );
1781 $affectedRows = $ilDB->manipulateF(
1782 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1783 array('integer','integer'),
1784 array($questionblock_id, $this->getSurveyId())
1785 );
1786 }
1787
1788 $this->questions = array_values($this->questions);
1789 $this->saveQuestionsToDb();
1790 }
1791
1798 public function unfoldQuestionblocks($questionblocks)
1799 {
1800 $ilDB = $this->db;
1801 foreach ($questionblocks as $index) {
1802 $affectedRows = $ilDB->manipulateF(
1803 "DELETE FROM svy_qblk WHERE questionblock_id = %s",
1804 array('integer'),
1805 array($index)
1806 );
1807 $affectedRows = $ilDB->manipulateF(
1808 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1809 array('integer','integer'),
1810 array($index, $this->getSurveyId())
1811 );
1812 }
1813 }
1814
1815 public function removeQuestionFromBlock($question_id, $questionblock_id)
1816 {
1817 $ilDB = $this->db;
1818
1819 $affectedRows = $ilDB->manipulateF(
1820 "DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
1821 array('integer','integer','integer'),
1822 array($questionblock_id, $this->getSurveyId(), $question_id)
1823 );
1824 }
1825
1826 public function addQuestionToBlock($question_id, $questionblock_id)
1827 {
1828 $ilDB = $this->db;
1829
1830 // see #22018
1831 if (!$this->isQuestionInAnyBlock($question_id)) {
1832 $next_id = $ilDB->nextId('svy_qblk_qst');
1833 $affectedRows = $ilDB->manipulateF(
1834 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
1835 "question_fi) VALUES (%s, %s, %s, %s)",
1836 array('integer', 'integer', 'integer', 'integer'),
1837 array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
1838 );
1839
1840 $this->deleteConstraints($question_id); // #13713
1841 }
1842 }
1843
1850 public function isQuestionInAnyBlock($a_question_fi)
1851 {
1852 global $DIC;
1853
1854 $ilDB = $DIC->database();
1855
1856 $set = $ilDB->query("SELECT * FROM svy_qblk_qst " .
1857 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
1858 " AND question_fi = " . $ilDB->quote($a_question_fi, "integer"));
1859 if ($rec = $ilDB->fetchAssoc($set)) {
1860 return true;
1861 }
1862 return false;
1863 }
1864
1865
1872 public function &getQuestionblockQuestions($questionblock_id)
1873 {
1874 $ilDB = $this->db;
1875 $titles = array();
1876 $result = $ilDB->queryF(
1877 "SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM " .
1878 "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
1879 "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
1880 array('integer'),
1881 array($questionblock_id)
1882 );
1883 $survey_id = "";
1884 while ($row = $ilDB->fetchAssoc($result)) {
1885 $titles[$row["question_fi"]] = $row["title"];
1886 $survey_id = $row["survey_fi"];
1887 }
1888 $result = $ilDB->queryF(
1889 "SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1890 array('integer'),
1891 array($survey_id)
1892 );
1893 $resultarray = array();
1894 $counter = 1;
1895 while ($row = $ilDB->fetchAssoc($result)) {
1896 if (array_key_exists($row["question_fi"], $titles)) {
1897 $resultarray[$counter++] = $titles[$row["question_fi"]];
1898 }
1899 }
1900 return $resultarray;
1901 }
1902
1909 public function &getQuestionblockQuestionIds($questionblock_id)
1910 {
1911 $ilDB = $this->db;
1912
1913 // we need a correct order here, see #22011
1914 $result = $ilDB->queryF(
1915 "SELECT a.question_fi FROM svy_qblk_qst a JOIN svy_svy_qst b ON (a.question_fi = b.question_fi) " .
1916 " WHERE a.questionblock_fi = %s ORDER BY b.sequence",
1917 array("integer"),
1918 array($questionblock_id)
1919 );
1920 $ids = array();
1921 if ($result->numRows()) {
1922 while ($data = $ilDB->fetchAssoc($result)) {
1923 if (!in_array($data['question_fi'], $ids)) { // no duplicates, see #22018
1924 array_push($ids, $data['question_fi']);
1925 }
1926 }
1927 }
1928
1929 return $ids;
1930 }
1931
1939 public static function _getQuestionblock($questionblock_id)
1940 {
1941 global $DIC;
1942
1943 $ilDB = $DIC->database();
1944 $result = $ilDB->queryF(
1945 "SELECT * FROM svy_qblk WHERE questionblock_id = %s",
1946 array('integer'),
1947 array($questionblock_id)
1948 );
1949 $row = $ilDB->fetchAssoc($result);
1950 return $row;
1951 }
1952
1961 public static function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false)
1962 {
1963 global $DIC;
1964
1965 $ilDB = $DIC->database();
1966 $next_id = $ilDB->nextId('svy_qblk');
1967 $ilDB->manipulateF(
1968 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
1969 " show_blocktitle, owner_fi, tstamp) " .
1970 "VALUES (%s, %s, %s, %s, %s, %s)",
1971 array('integer','text','integer','integer','integer','integer'),
1972 array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time())
1973 );
1974 return $next_id;
1975 }
1976
1984 public function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
1985 {
1986 $ilDB = $this->db;
1987
1988 // if the selected questions are not in a continous selection, move all questions of the
1989 // questionblock at the position of the first selected question
1990 $this->moveQuestions($questions, $questions[0], 0);
1991
1992 // now save the question block
1994 $next_id = $ilDB->nextId('svy_qblk');
1995 $affectedRows = $ilDB->manipulateF(
1996 "INSERT INTO svy_qblk (questionblock_id, title, show_questiontext," .
1997 " show_blocktitle, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
1998 array('integer','text','text','text','integer','integer'),
1999 array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time())
2000 );
2001 if ($affectedRows) {
2002 $questionblock_id = $next_id;
2003 foreach ($questions as $index) {
2004 if (!$this->isQuestionInAnyBlock($index)) {
2005 $next_id = $ilDB->nextId('svy_qblk_qst'); // #22018
2006 $affectedRows = $ilDB->manipulateF(
2007 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2008 "question_fi) VALUES (%s, %s, %s, %s)",
2009 array('integer', 'integer', 'integer', 'integer'),
2010 array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2011 );
2012 $this->deleteConstraints($index);
2013 }
2014 }
2015 }
2016 }
2017
2025 public function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
2026 {
2027 $ilDB = $this->db;
2028 $affectedRows = $ilDB->manipulateF(
2029 "UPDATE svy_qblk SET title = %s, show_questiontext = %s," .
2030 " show_blocktitle = %s WHERE questionblock_id = %s",
2031 array('text','text','text','integer'),
2032 array($title, $show_questiontext, $show_blocktitle, $questionblock_id)
2033 );
2034 }
2035
2042 public function deleteConstraints($question_id)
2043 {
2044 $ilDB = $this->db;
2045 $result = $ilDB->queryF(
2046 "SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2047 array('integer','integer'),
2048 array($question_id, $this->getSurveyId())
2049 );
2050 $constraints = array();
2051 while ($row = $ilDB->fetchAssoc($result)) {
2052 array_push($constraints, $row["constraint_fi"]);
2053 }
2054 foreach ($constraints as $constraint_id) {
2055 $this->deleteConstraint($constraint_id);
2056 }
2057 }
2058
2066 public function deleteConstraint($constraint_id)
2067 {
2068 $ilDB = $this->db;
2069 $affectedRows = $ilDB->manipulateF(
2070 "DELETE FROM svy_constraint WHERE constraint_id = %s",
2071 array('integer'),
2072 array($constraint_id)
2073 );
2074 $affectedRows = $ilDB->manipulateF(
2075 "DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2076 array('integer'),
2077 array($constraint_id)
2078 );
2079 }
2080
2086 public function &getSurveyQuestions($with_answers = false)
2087 {
2088 $ilDB = $this->db;
2089 // get questionblocks
2090 $all_questions = array();
2091 $result = $ilDB->queryF(
2092 "SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, " .
2093 "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2094 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2095 "ORDER BY svy_svy_qst.sequence",
2096 array('integer'),
2097 array($this->getSurveyId())
2098 );
2099 while ($row = $ilDB->fetchAssoc($result)) {
2100 $add = true;
2101 if ($row["plugin"]) {
2102 if (!$this->isPluginActive($row["type_tag"])) {
2103 $add = false;
2104 }
2105 }
2106 if ($add) {
2107 $question = self::_instanciateQuestion($row["question_id"]);
2108 $questionrow = $question->getQuestionDataArray($row["question_id"]);
2109 foreach ($row as $key => $value) {
2110 $questionrow[$key] = $value;
2111 }
2112 $all_questions[$row["question_id"]] = $questionrow;
2113 $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2114 $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2115 }
2116 }
2117 // get all questionblocks
2118 $questionblocks = array();
2119 if (count($all_questions)) {
2120 $result = $ilDB->queryF(
2121 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2122 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2123 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2124 array('integer'),
2125 array($this->getSurveyId())
2126 );
2127 while ($row = $ilDB->fetchAssoc($result)) {
2128 $questionblocks[$row['question_fi']] = $row;
2129 }
2130 }
2131
2132 foreach ($all_questions as $question_id => $row) {
2133 $constraints = $this->getConstraints($question_id);
2134 if (isset($questionblocks[$question_id])) {
2135 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2136 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2137 $all_questions[$question_id]["constraints"] = $constraints;
2138 } else {
2139 $all_questions[$question_id]["questionblock_title"] = "";
2140 $all_questions[$question_id]["questionblock_id"] = "";
2141 $all_questions[$question_id]["constraints"] = $constraints;
2142 }
2143 if ($with_answers) {
2144 $answers = array();
2145 $result = $ilDB->queryF(
2146 "SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2147 "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id " .
2148 "ORDER BY sequence ASC",
2149 array('integer'),
2150 array($question_id)
2151 );
2152 if ($result->numRows() > 0) {
2153 while ($data = $ilDB->fetchAssoc($result)) {
2154 array_push($answers, $data["title"]);
2155 }
2156 }
2157 $all_questions[$question_id]["answers"] = $answers;
2158 }
2159 }
2160 return $all_questions;
2161 }
2162
2169 public function setObligatoryStates($obligatory_questions)
2170 {
2171 $ilDB = $this->db;
2172 $result = $ilDB->queryF(
2173 "SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2174 array('integer'),
2175 array($this->getSurveyId())
2176 );
2177 if ($result->numRows()) {
2178 while ($row = $ilDB->fetchAssoc($result)) {
2179 if (!array_key_exists($row["question_fi"], $obligatory_questions)) {
2180 $obligatory_questions[$row["question_fi"]] = 0;
2181 }
2182 }
2183 }
2184
2185 // set the obligatory states in the database
2186 foreach ($obligatory_questions as $question_fi => $obligatory) {
2187 // #12420
2188 $ilDB->manipulate("UPDATE svy_question" .
2189 " SET obligatory = " . $ilDB->quote($obligatory, "integer") .
2190 " WHERE question_id = " . $ilDB->quote($question_fi, "integer"));
2191 }
2192 }
2193
2199 public function &getSurveyPages()
2200 {
2201 $ilDB = $this->db;
2202 // get questionblocks
2203 $all_questions = array();
2204 $result = $ilDB->queryF(
2205 "SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2206 "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2207 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2208 "ORDER BY svy_svy_qst.sequence",
2209 array('integer'),
2210 array($this->getSurveyId())
2211 );
2212 while ($row = $ilDB->fetchAssoc($result)) {
2213 $all_questions[$row["question_id"]] = $row;
2214 }
2215 // get all questionblocks
2216 $questionblocks = array();
2217 if (count($all_questions)) {
2218 $result = $ilDB->queryF(
2219 "SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst " .
2220 "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2221 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2222 array('integer'),
2223 array($this->getSurveyId())
2224 );
2225 while ($row = $ilDB->fetchAssoc($result)) {
2226 $questionblocks[$row['question_fi']] = $row;
2227 }
2228 }
2229
2230 $all_pages = array();
2231 $pageindex = -1;
2232 $currentblock = "";
2233 foreach ($all_questions as $question_id => $row) {
2234 $constraints = array();
2235 if (isset($questionblocks[$question_id])) {
2236 if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id'])) {
2237 $pageindex++;
2238 }
2239 $all_questions[$question_id]['page'] = $pageindex;
2240 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2241 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2242 $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2243 $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2244 $currentblock = $questionblocks[$question_id]['questionblock_id'];
2245 $constraints = $this->getConstraints($question_id);
2246 $all_questions[$question_id]["constraints"] = $constraints;
2247 } else {
2248 $pageindex++;
2249 $all_questions[$question_id]['page'] = $pageindex;
2250 $all_questions[$question_id]["questionblock_title"] = "";
2251 $all_questions[$question_id]["questionblock_id"] = "";
2252 $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2253 $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2254 $currentblock = "";
2255 $constraints = $this->getConstraints($question_id);
2256 $all_questions[$question_id]["constraints"] = $constraints;
2257 }
2258 if (!isset($all_pages[$pageindex])) {
2259 $all_pages[$pageindex] = array();
2260 }
2261 array_push($all_pages[$pageindex], $all_questions[$question_id]);
2262 }
2263 // calculate position percentage for every page
2264 $max = count($all_pages);
2265 $counter = 1;
2266 foreach ($all_pages as $index => $block) {
2267 foreach ($block as $blockindex => $question) {
2268 $all_pages[$index][$blockindex]["position"] = $counter / $max;
2269 }
2270 $counter++;
2271 }
2272
2273 return $all_pages;
2274 }
2275
2284 public function getNextPage($active_page_question_id, $direction)
2285 {
2286 $foundpage = -1;
2287 $pages = &$this->getSurveyPages();
2288 if (strcmp($active_page_question_id, "") == 0) {
2289 return $pages[0];
2290 }
2291 foreach ($pages as $key => $question_array) {
2292 foreach ($question_array as $question) {
2293 if ($active_page_question_id == $question["question_id"]) {
2294 $foundpage = $key;
2295 }
2296 }
2297 }
2298 if ($foundpage == -1) {
2299 // error: page not found
2300 } else {
2301 $foundpage += $direction;
2302 if ($foundpage < 0) {
2303 return 0;
2304 }
2305 if ($foundpage >= count($pages)) {
2306 return 1;
2307 }
2308 return $pages[$foundpage];
2309 }
2310 }
2311
2318 public function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = false, $permission = "read")
2319 {
2320 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2321 }
2322
2328 public function getPrecondition($id)
2329 {
2330 $ilDB = $this->db;
2331
2332 $result_array = array();
2333 $result = $ilDB->queryF(
2334 "SELECT svy_constraint.*, svy_relation.*, svy_qst_constraint.question_fi ref_question_fi FROM svy_qst_constraint, svy_constraint, " .
2335 "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2336 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2337 array('integer'),
2338 array($id)
2339 );
2340 $pc = array();
2341 if ($result->numRows()) {
2342 $pc = $ilDB->fetchAssoc($result);
2343 }
2344 return $pc;
2345 }
2346
2352 public function getConstraints($question_id)
2353 {
2354 $ilDB = $this->db;
2355
2356 $result_array = array();
2357 $result = $ilDB->queryF(
2358 "SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation " .
2359 "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND " .
2360 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s " .
2361 "AND svy_qst_constraint.survey_fi = %s",
2362 array('integer','integer'),
2363 array($question_id, $this->getSurveyId())
2364 );
2365 while ($row = $ilDB->fetchAssoc($result)) {
2366 $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2367 SurveyQuestion::_includeClass($question_type);
2368 $question = new $question_type();
2369 $question->loadFromDb($row["question_fi"]);
2370 $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2371 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));
2372 }
2373 return $result_array;
2374 }
2375
2381 public static function _getConstraints($survey_id)
2382 {
2383 global $DIC;
2384
2385 $ilDB = $DIC->database();
2386 $result_array = array();
2387 $result = $ilDB->queryF(
2388 "SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* " .
2389 "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id " .
2390 "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2391 array('integer'),
2392 array($survey_id)
2393 );
2394 while ($row = $ilDB->fetchAssoc($result)) {
2395 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']));
2396 }
2397 return $result_array;
2398 }
2399
2400
2406 public function &getVariables($question_id)
2407 {
2408 $ilDB = $this->db;
2409
2410 $result_array = array();
2411 $result = $ilDB->queryF(
2412 "SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN " .
2413 "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s " .
2414 "ORDER BY svy_variable.sequence",
2415 array('integer'),
2416 array($question_id)
2417 );
2418 while ($row = $ilDB->fetchObject($result)) {
2419 $result_array[$row->sequence] = $row;
2420 }
2421 return $result_array;
2422 }
2423
2432 public function addConstraint($if_question_id, $relation, $value, $conjunction)
2433 {
2434 $ilDB = $this->db;
2435
2436 $next_id = $ilDB->nextId('svy_constraint');
2437 $affectedRows = $ilDB->manipulateF(
2438 "INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES " .
2439 "(%s, %s, %s, %s, %s)",
2440 array('integer','integer','integer','float', 'integer'),
2441 array($next_id, $if_question_id, $relation, $value, $conjunction)
2442 );
2443 if ($affectedRows) {
2444 return $next_id;
2445 } else {
2446 return null;
2447 }
2448 }
2449
2450
2457 public function addConstraintToQuestion($to_question_id, $constraint_id)
2458 {
2459 $ilDB = $this->db;
2460
2461 $next_id = $ilDB->nextId('svy_qst_constraint');
2462 $affectedRows = $ilDB->manipulateF(
2463 "INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, " .
2464 "constraint_fi) VALUES (%s, %s, %s, %s)",
2465 array('integer','integer','integer','integer'),
2466 array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2467 );
2468 }
2469
2480 public function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2481 {
2482 $ilDB = $this->db;
2483 $affectedRows = $ilDB->manipulateF(
2484 "UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s " .
2485 "WHERE constraint_id = %s",
2486 array('integer','integer','float','integer','integer'),
2487 array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2488 );
2489 }
2490
2491 public function updateConjunctionForQuestions($questions, $conjunction)
2492 {
2493 $ilDB = $this->db;
2494 foreach ($questions as $question_id) {
2495 $affectedRows = $ilDB->manipulateF(
2496 "UPDATE svy_constraint SET conjunction = %s " .
2497 "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2498 array('integer','integer'),
2499 array($conjunction, $question_id)
2500 );
2501 }
2502 }
2503
2509 public function getAllRelations($short_as_key = false)
2510 {
2511 $ilDB = $this->db;
2512
2513 // #7987
2514 $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2515 $custom_order = array_flip($custom_order);
2516
2517 $result_array = array();
2518 $result = $ilDB->query("SELECT * FROM svy_relation");
2519 while ($row = $ilDB->fetchAssoc($result)) {
2520 if ($short_as_key) {
2521 $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2522 } else {
2523 $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2524 }
2525 }
2526
2527 $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2528 foreach ($result_array as $idx => $item) {
2529 unset($result_array[$idx]["order"]);
2530 }
2531
2532 return $result_array;
2533 }
2534
2535
2536
2537
2545 public function deleteWorkingData($question_id, $active_id)
2546 {
2547 $ilDB = $this->db;
2548
2549 $affectedRows = $ilDB->manipulateF(
2550 "DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2551 array('integer','integer'),
2552 array($question_id, $active_id)
2553 );
2554 }
2555
2564 public function loadWorkingData($question_id, $active_id)
2565 {
2566 $ilDB = $this->db;
2567 $result_array = array();
2568 $result = $ilDB->queryF(
2569 "SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2570 array('integer','integer'),
2571 array($question_id, $active_id)
2572 );
2573 if ($result->numRows() >= 1) {
2574 while ($row = $ilDB->fetchAssoc($result)) {
2575 array_push($result_array, $row);
2576 }
2577 return $result_array;
2578 } else {
2579 return $result_array;
2580 }
2581 }
2582
2589 public function startSurvey($user_id, $anonymous_id, $appraisee_id)
2590 {
2591 $ilDB = $this->db;
2592
2593 if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) {
2594 return;
2595 }
2596
2597 if (strcmp($user_id, "") == 0) {
2598 if ($user_id == ANONYMOUS_USER_ID) {
2599 $user_id = 0;
2600 }
2601 }
2602 $next_id = $ilDB->nextId('svy_finished');
2603 $affectedRows = $ilDB->manipulateF(
2604 "INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) " .
2605 "VALUES (%s, %s, %s, %s, %s, %s, %s)",
2606 array('integer','integer','integer','text','text','integer','integer'),
2607 array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
2608 );
2609 return $next_id;
2610 }
2611
2618 public function finishSurvey($finished_id)
2619 {
2620 $ilDB = $this->db;
2621
2622 $ilDB->manipulateF(
2623 "UPDATE svy_finished SET state = %s, tstamp = %s" .
2624 " WHERE survey_fi = %s AND finished_id = %s",
2625 array('text','integer','integer','integer'),
2626 array(1, time(), $this->getSurveyId(), $finished_id)
2627 );
2628
2629 // self eval writes skills on finishing
2630 if ($this->getMode() == ilObjSurvey::MODE_SELF_EVAL) {
2631 $user = $this->getUserDataFromActiveId($finished_id);
2632 $sskill = new ilSurveySkill($this);
2633 $sskill->writeAndAddSelfEvalSkills($user['usr_id']);
2634 }
2635
2636 $this->checkTutorNotification();
2637 }
2638
2646 public function setPage($finished_id, $page_id)
2647 {
2648 $ilDB = $this->db;
2649
2650 $affectedRows = $ilDB->manipulateF(
2651 "UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
2652 array('integer','integer'),
2653 array(($page_id) ? $page_id : 0, $finished_id)
2654 );
2655 }
2656
2662 public function sendNotificationMail($a_user_id, $a_anonymize_id, $a_appr_id)
2663 {
2664 // #12755
2665 $placeholders = array(
2666 "FIRST_NAME" => "firstname",
2667 "LAST_NAME" => "lastname",
2668 "LOGIN" => "login",
2669 // old style
2670 "firstname" => "firstname"
2671 );
2672
2673 //mailaddresses is just text split by commas.
2674 //sendMail can send emails if it gets an user id or an email as first parameter.
2675 $recipients = preg_split('/,/', $this->mailaddresses);
2676 foreach ($recipients as $recipient) {
2677 // #11298
2678 $ntf = new ilSystemNotification();
2679 $ntf->setLangModules(array("survey"));
2680 $ntf->setRefId($this->getRefId());
2681 $ntf->setSubjectLangId('finished_mail_subject');
2682
2683 $messagetext = $this->mailparticipantdata;
2684 if (trim($messagetext)) {
2685 if (!$this->hasAnonymizedResults()) {
2686 $data = ilObjUser::_getUserData(array($a_user_id));
2687 $data = $data[0];
2688 }
2689 foreach ($placeholders as $key => $mapping) {
2690 if ($this->hasAnonymizedResults()) { // #16480
2691 $messagetext = str_replace('[' . $key . ']', '', $messagetext);
2692 } else {
2693 $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
2694 }
2695 }
2696 $ntf->setIntroductionDirect($messagetext);
2697 } else {
2698 $ntf->setIntroductionLangId('survey_notification_finished_introduction');
2699 }
2700
2701 // 360°? add appraisee data
2702 if ($a_appr_id) {
2703 $ntf->addAdditionalInfo(
2704 'survey_360_appraisee',
2706 );
2707 }
2708
2709 $active_id = $this->getActiveID($a_user_id, $a_anonymize_id, $a_appr_id);
2710 $ntf->addAdditionalInfo(
2711 'results',
2712 $this->getParticipantTextResults($active_id),
2713 true
2714 );
2715
2716 $ntf->setGotoLangId('survey_notification_tutor_link');
2717 $ntf->setReasonLangId('survey_notification_finished_reason');
2718
2719 if (is_numeric($recipient)) {
2720 $lng = $ntf->getUserLanguage($recipient);
2721 $ntf->sendMail(array($recipient), null, null);
2722 } else {
2723 $recipient = trim($recipient);
2724 $user_ids = ilObjUser::getUserIdsByEmail($recipient);
2725 if (empty($user_ids)) {
2726 $ntf->sendMail(array($recipient), null, null);
2727 } else {
2728 foreach ($user_ids as $user_id) {
2729 $lng = $ntf->getUserLanguage($user_id);
2730 $ntf->sendMail(array($user_id), null, null);
2731 }
2732 }
2733 }
2734 }
2735 }
2736
2737 protected function getParticipantTextResults($active_id)
2738 {
2739 $textresult = "";
2740 $userResults = &$this->getUserSpecificResults(array($active_id));
2741 $questions = &$this->getSurveyQuestions(true);
2742 $questioncounter = 1;
2743 foreach ($questions as $question_id => $question_data) {
2744 $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
2745 $found = $userResults[$question_id][$active_id];
2746 $text = "";
2747 if (is_array($found)) {
2748 $text = implode("\n", $found);
2749 } else {
2750 $text = $found;
2751 }
2752 if (strlen($text) == 0) {
2754 }
2755 $text = str_replace("<br />", "\n", $text);
2756 $textresult .= $text . "\n\n";
2757 }
2758 return $textresult;
2759 }
2760
2768 public function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
2769 {
2770 $ilDB = $this->db;
2771
2772 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2773 if ($anonymize_id) {
2774 $result = $ilDB->queryF(
2775 "SELECT * FROM svy_finished" .
2776 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2777 array('integer','text','integer'),
2778 array($this->getSurveyId(), $anonymize_id, $appr_id)
2779 );
2780 } else {
2781 $result = $ilDB->queryF(
2782 "SELECT * FROM svy_finished" .
2783 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2784 array('integer','integer','integer'),
2785 array($this->getSurveyId(), $user_id, $appr_id)
2786 );
2787 }
2788 if ($result->numRows() == 0) {
2789 return false;
2790 } else {
2791 $row = $ilDB->fetchAssoc($result);
2792 // yes, we are doing it this way
2793 $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
2794
2795 return (int) $row["state"];
2796 }
2797 }
2798
2806 public function getActiveID($user_id, $anonymize_id, $appr_id)
2807 {
2808 $ilDB = $this->db;
2809
2810 // see self::isSurveyStarted()
2811
2812 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
2813 if ($anonymize_id) {
2814 $result = $ilDB->queryF(
2815 "SELECT finished_id FROM svy_finished" .
2816 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
2817 array('integer','text','integer'),
2818 array($this->getSurveyId(), $anonymize_id, $appr_id)
2819 );
2820 } else {
2821 $result = $ilDB->queryF(
2822 "SELECT finished_id FROM svy_finished" .
2823 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
2824 array('integer','integer','integer'),
2825 array($this->getSurveyId(), $user_id, $appr_id)
2826 );
2827 }
2828 if ($result->numRows() == 0) {
2829 return false;
2830 } else {
2831 $row = $ilDB->fetchAssoc($result);
2832 return $row["finished_id"];
2833 }
2834 }
2835
2843 public function getLastActivePage($active_id)
2844 {
2845 $ilDB = $this->db;
2846 $result = $ilDB->queryF(
2847 "SELECT lastpage FROM svy_finished WHERE finished_id = %s",
2848 array('integer'),
2849 array($active_id)
2850 );
2851 if ($result->numRows() == 0) {
2852 return "";
2853 } else {
2854 $row = $ilDB->fetchAssoc($result);
2855 return ($row["lastpage"]) ? $row["lastpage"] : '';
2856 }
2857 }
2858
2867 public function checkConstraint($constraint_data, $working_data)
2868 {
2869 if (!is_array($working_data) || count($working_data) == 0) {
2870 return 0;
2871 }
2872
2873 if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0)) {
2874 return 0;
2875 }
2876
2877 $found = false;
2878 foreach ($working_data as $data) {
2879 switch ($constraint_data["short"]) {
2880 case "<":
2881 if ($data["value"] < $constraint_data["value"]) {
2882 $found = true;
2883 }
2884 break;
2885
2886 case "<=":
2887 if ($data["value"] <= $constraint_data["value"]) {
2888 $found = true;
2889 }
2890 break;
2891
2892 case "=":
2893 if ($data["value"] == $constraint_data["value"]) {
2894 $found = true;
2895 }
2896 break;
2897
2898 case "<>":
2899 if ($data["value"] <> $constraint_data["value"]) {
2900 $found = true;
2901 }
2902 break;
2903
2904 case ">=":
2905 if ($data["value"] >= $constraint_data["value"]) {
2906 $found = true;
2907 }
2908 break;
2909
2910 case ">":
2911 if ($data["value"] > $constraint_data["value"]) {
2912 $found = true;
2913 }
2914 break;
2915 }
2916 if ($found) {
2917 break;
2918 }
2919 }
2920
2921 return (int) $found;
2922 }
2923
2924 public static function _hasDatasets($survey_id)
2925 {
2926 global $DIC;
2927
2928 $ilDB = $DIC->database();
2929
2930 $result = $ilDB->queryF(
2931 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
2932 array('integer'),
2933 array($survey_id)
2934 );
2935 return ($result->numRows()) ? true : false;
2936 }
2937
2944 public function &getSurveyFinishedIds()
2945 {
2946 $ilDB = $this->db;
2948
2949 $users = array();
2950 $result = $ilDB->queryF(
2951 "SELECT * FROM svy_finished WHERE survey_fi = %s",
2952 array('integer'),
2953 array($this->getSurveyId())
2954 );
2955 if ($result->numRows()) {
2956 while ($row = $ilDB->fetchAssoc($result)) {
2957 array_push($users, $row["finished_id"]);
2958 }
2959 }
2960 return $users;
2961 }
2962
2969 public function getUserSpecificResults($finished_ids)
2970 {
2971 $evaluation = array();
2972
2973 foreach (array_keys($this->getSurveyQuestions()) as $question_id) {
2974 // get question instance
2975 $question_type = SurveyQuestion::_getQuestionType($question_id);
2976 SurveyQuestion::_includeClass($question_type);
2977 $question = new $question_type();
2978 $question->loadFromDb($question_id);
2979
2980 $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($question_id, $finished_ids);
2981 $q_res = $q_eval->getResults();
2982
2983 $data = array();
2984 foreach ($finished_ids as $user_id) {
2985 $data[$user_id] = $q_eval->parseUserSpecificResults($q_res, $user_id);
2986 }
2987
2988 $evaluation[$question_id] = $data;
2989 }
2990
2991 return $evaluation;
2992 }
2993
3001 public function getUserDataFromActiveId($active_id, $force_non_anonymous = false)
3002 {
3003 $ilDB = $this->db;
3004
3005 $surveySetting = new ilSetting("survey");
3006 $use_anonymous_id = $surveySetting->get("use_anonymous_id");
3007 $result = $ilDB->queryF(
3008 "SELECT * FROM svy_finished WHERE finished_id = %s",
3009 array('integer'),
3010 array($active_id)
3011 );
3012 $row = array();
3013 $foundrows = $result->numRows();
3014 if ($foundrows) {
3015 $row = $ilDB->fetchAssoc($result);
3016 }
3017 $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3018 $userdata = array(
3019 "fullname" => $name,
3020 "sortname" => $name,
3021 "firstname" => "",
3022 "lastname" => "",
3023 "login" => "",
3024 "gender" => "",
3025 "active_id" => "$active_id"
3026 );
3027 if ($foundrows) {
3028 if (($row["user_fi"] > 0) &&
3029 (($row["user_fi"] != ANONYMOUS_USER_ID &&
3030 !$this->hasAnonymizedResults() &&
3031 !$this->get360Mode()) || // 360° uses ANONYMIZE_CODE_ALL which is wrong - see ilObjSurveyGUI::afterSave()
3032 (bool) $force_non_anonymous)) {
3033 if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0) {
3034 $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3035 } else {
3036 $user = new ilObjUser($row["user_fi"]);
3037 $userdata['usr_id'] = $row['user_fi'];
3038 $userdata["fullname"] = $user->getFullname();
3039 $gender = $user->getGender();
3040 if (strlen($gender) == 1) {
3041 $gender = $this->lng->txt("gender_$gender");
3042 }
3043 $userdata["gender"] = $gender;
3044 $userdata["firstname"] = $user->getFirstname();
3045 $userdata["lastname"] = $user->getLastname();
3046 $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3047 $userdata["login"] = $user->getLogin();
3048 }
3049 }
3050 }
3051 return $userdata;
3052 }
3053
3063 public function &getEvaluationByUser($questions, $active_id)
3064 {
3065 $ilDB = $this->db;
3066
3067 // collect all answers
3068 $answers = array();
3069 $result = $ilDB->queryF(
3070 "SELECT * FROM svy_answer WHERE active_fi = %s",
3071 array('integer'),
3072 array($active_id)
3073 );
3074 while ($row = $ilDB->fetchAssoc($result)) {
3075 if (!is_array($answers[$row["question_fi"]])) {
3076 $answers[$row["question_fi"]] = array();
3077 }
3078 array_push($answers[$row["question_fi"]], $row);
3079 }
3080 $userdata = $this->getUserDataFromActiveId($active_id);
3081 $resultset = array(
3082 "name" => $userdata["fullname"],
3083 "firstname" => $userdata["firstname"],
3084 "lastname" => $userdata["lastname"],
3085 "login" => $userdata["login"],
3086 "gender" => $userdata["gender"],
3087 "answers" => array()
3088 );
3089 foreach ($questions as $key => $question) {
3090 if (array_key_exists($key, $answers)) {
3091 $resultset["answers"][$key] = $answers[$key];
3092 } else {
3093 $resultset["answers"][$key] = array();
3094 }
3095 sort($resultset["answers"][$key]);
3096 }
3097 return $resultset;
3098 }
3099
3105 public function getQuestionsTable($arrFilter)
3106 {
3108 $ilDB = $this->db;
3109 $where = "";
3110 if (is_array($arrFilter)) {
3111 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3112 $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3113 }
3114 if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description'])) {
3115 $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3116 }
3117 if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author'])) {
3118 $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3119 }
3120 if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type'])) {
3121 $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3122 }
3123 if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl'])) {
3124 $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3125 }
3126 }
3127
3128 $spls = &$this->getAvailableQuestionpools($use_obj_id = true, $could_be_offline = false, $showPath = false);
3129 $forbidden = "";
3130 $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3131 $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3132 $existing = "";
3133 $existing_questions = &$this->getExistingQuestions();
3134 if (count($existing_questions)) {
3135 $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3136 }
3137
3139
3140 $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id" .
3141 " FROM svy_question, svy_qtype, object_reference" .
3142 " WHERE svy_question.original_id IS NULL" . $forbidden . $existing .
3143 " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0" .
3144 " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3145
3146 $rows = array();
3147 if ($query_result->numRows()) {
3148 while ($row = $ilDB->fetchAssoc($query_result)) {
3149 if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt'])) {
3150 if (!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt'])) {
3151 continue;
3152 }
3153 }
3154
3155 $row['ttype'] = $trans[$row['type_tag']];
3156 if ($row["plugin"]) {
3157 if ($this->isPluginActive($row["type_tag"])) {
3158 array_push($rows, $row);
3159 }
3160 } else {
3161 array_push($rows, $row);
3162 }
3163 }
3164 }
3165 return $rows;
3166 }
3167
3173 public function getQuestionblocksTable($arrFilter)
3174 {
3176 $ilDB = $this->db;
3177
3178 $where = "";
3179 if (is_array($arrFilter)) {
3180 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title'])) {
3181 $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3182 }
3183 }
3184
3185 $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE " .
3186 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi " .
3187 "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, " .
3188 "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3189 $rows = array();
3190 if ($query_result->numRows()) {
3191 $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3192 $surveytitles = array();
3193 foreach ($survey_ref_ids as $survey_ref_id) {
3194 $survey_id = ilObject::_lookupObjId($survey_ref_id);
3196 }
3197 while ($row = $ilDB->fetchAssoc($query_result)) {
3198 $questions_array = &$this->getQuestionblockQuestions($row["questionblock_id"]);
3199 $counter = 1;
3200 foreach ($questions_array as $key => $value) {
3201 $questions_array[$key] = "$counter. $value";
3202 $counter++;
3203 }
3204 if (strlen($surveytitles[$row["obj_fi"]])) { // only questionpools which are not in trash
3205 $rows[$row["questionblock_id"]] = array(
3206 "questionblock_id" => $row["questionblock_id"],
3207 "title" => $row["title"],
3208 "svy" => $surveytitles[$row["obj_fi"]],
3209 "contains" => join(", ", $questions_array),
3210 "owner" => $row["owner_fi"]
3211 );
3212 }
3213 }
3214 }
3215 return $rows;
3216 }
3217
3224 public function toXML()
3225 {
3226 $a_xml_writer = new ilXmlWriter;
3227 // set xml header
3228 $a_xml_writer->xmlHeader();
3229 $attrs = array(
3230 "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3231 "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3232 );
3233 $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3234 $attrs = array(
3235 "id" => $this->getSurveyId(),
3236 "title" => $this->getTitle()
3237 );
3238 $a_xml_writer->xmlStartTag("survey", $attrs);
3239
3240 $a_xml_writer->xmlElement("description", null, $this->getDescription());
3241 $a_xml_writer->xmlElement("author", null, $this->getAuthor());
3242 $a_xml_writer->xmlStartTag("objectives");
3243 $attrs = array(
3244 "label" => "introduction"
3245 );
3246 $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), true, true, $attrs);
3247 $attrs = array(
3248 "label" => "outro"
3249 );
3250 $this->addMaterialTag($a_xml_writer, $this->getOutro(), true, true, $attrs);
3251 $a_xml_writer->xmlEndTag("objectives");
3252
3253 if ($this->getAnonymize()) {
3254 $attribs = array("enabled" => "1");
3255 } else {
3256 $attribs = array("enabled" => "0");
3257 }
3258 $a_xml_writer->xmlElement("anonymisation", $attribs);
3259 $a_xml_writer->xmlStartTag("restrictions");
3260 if ($this->getAnonymize() == 2) {
3261 $attribs = array("type" => "free");
3262 } else {
3263 $attribs = array("type" => "restricted");
3264 }
3265 $a_xml_writer->xmlElement("access", $attribs);
3266 if ($this->getStartDate()) {
3267 $attrs = array("type" => "date");
3268 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3269 $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]));
3270 }
3271 if ($this->getEndDate()) {
3272 $attrs = array("type" => "date");
3273 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3274 $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]));
3275 }
3276 $a_xml_writer->xmlEndTag("restrictions");
3277
3278 // constraints
3279 $pages = &$this->getSurveyPages();
3280 $hasconstraints = false;
3281 foreach ($pages as $question_array) {
3282 foreach ($question_array as $question) {
3283 if (count($question["constraints"])) {
3284 $hasconstraints = true;
3285 }
3286 }
3287 }
3288
3289 if ($hasconstraints) {
3290 $a_xml_writer->xmlStartTag("constraints");
3291 foreach ($pages as $question_array) {
3292 foreach ($question_array as $question) {
3293 if (count($question["constraints"])) {
3294 // found constraints
3295 foreach ($question["constraints"] as $constraint) {
3296 $attribs = array(
3297 "sourceref" => $question["question_id"],
3298 "destref" => $constraint["question"],
3299 "relation" => $constraint["short"],
3300 "value" => $constraint["value"],
3301 "conjunction" => $constraint["conjunction"]
3302 );
3303 $a_xml_writer->xmlElement("constraint", $attribs);
3304 }
3305 }
3306 }
3307 }
3308 $a_xml_writer->xmlEndTag("constraints");
3309 }
3310
3311 // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
3312 $a_xml_writer->xmlStartTag("metadata");
3313
3314 $custom_properties = array();
3315 $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
3316 $custom_properties["status"] = !$this->getOfflineStatus();
3317 $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
3318 $custom_properties["pool_usage"] = (int) $this->getPoolUsage();
3319
3320 $custom_properties["own_results_view"] = (int) $this->hasViewOwnResults();
3321 $custom_properties["own_results_mail"] = (int) $this->hasMailOwnResults();
3322 $custom_properties["confirmation_mail"] = (int) $this->hasMailConfirmation();
3323
3324 $custom_properties["anon_user_list"] = (int) $this->hasAnonymousUserList();
3325 $custom_properties["mode"] = (int) $this->getMode();
3326 $custom_properties["mode_360_self_eval"] = (int) $this->get360SelfEvaluation();
3327 $custom_properties["mode_360_self_rate"] = (int) $this->get360SelfRaters();
3328 $custom_properties["mode_360_self_appr"] = (int) $this->get360SelfAppraisee();
3329 $custom_properties["mode_360_results"] = $this->get360Results();
3330 $custom_properties["mode_skill_service"] = (int) $this->getSkillService();
3331 $custom_properties["mode_self_eval_results"] = (int) $this->getSelfEvaluationResults();
3332
3333
3334 // :TODO: skills?
3335
3336 // reminder/tutor notification are (currently?) not exportable
3337
3338 foreach ($custom_properties as $label => $value) {
3339 $a_xml_writer->xmlStartTag("metadatafield");
3340 $a_xml_writer->xmlElement("fieldlabel", null, $label);
3341 $a_xml_writer->xmlElement("fieldentry", null, $value);
3342 $a_xml_writer->xmlEndTag("metadatafield");
3343 }
3344
3345 $a_xml_writer->xmlStartTag("metadatafield");
3346 $a_xml_writer->xmlElement("fieldlabel", null, "SCORM");
3347 $md = new ilMD($this->getId(), 0, $this->getType());
3348 $writer = new ilXmlWriter();
3349 $md->toXml($writer);
3350 $metadata = $writer->xmlDumpMem();
3351 $a_xml_writer->xmlElement("fieldentry", null, $metadata);
3352 $a_xml_writer->xmlEndTag("metadatafield");
3353
3354 $a_xml_writer->xmlEndTag("metadata");
3355 $a_xml_writer->xmlEndTag("survey");
3356
3357 $attribs = array("id" => $this->getId());
3358 $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
3359 // add questionblock descriptions
3360 foreach ($pages as $question_array) {
3361 if (count($question_array) > 1) {
3362 $attribs = array("id" => $question_array[0]["question_id"]);
3363 $attribs = array("showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
3364 "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"]);
3365 $a_xml_writer->xmlStartTag("questionblock", $attribs);
3366 if (strlen($question_array[0]["questionblock_title"])) {
3367 $a_xml_writer->xmlElement("questionblocktitle", null, $question_array[0]["questionblock_title"]);
3368 }
3369 }
3370 foreach ($question_array as $question) {
3371 if (strlen($question["heading"])) {
3372 $a_xml_writer->xmlElement("textblock", null, $question["heading"]);
3373 }
3374 $questionObject = self::_instanciateQuestion($question["question_id"]);
3375 //questionObject contains all the fields from the database. (loadFromDb)
3376 //we don't need the value from svy_qst_oblig table, we already have the values from svy_question table.
3377 //if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
3378 if ($questionObject !== false) {
3379 $questionObject->insertXML($a_xml_writer, false);
3380 }
3381 }
3382 if (count($question_array) > 1) {
3383 $a_xml_writer->xmlEndTag("questionblock");
3384 }
3385 }
3386
3387 $a_xml_writer->xmlEndTag("surveyquestions");
3388 $a_xml_writer->xmlEndTag("surveyobject");
3389 $xml = $a_xml_writer->xmlDumpMem(false);
3390 return $xml;
3391 }
3392
3400 public static function _instanciateQuestion($question_id)
3401 {
3402 if ($question_id < 1) {
3403 return false;
3404 }
3405 $question_type = SurveyQuestion::_getQuestionType($question_id);
3406 if (strlen($question_type) == 0) {
3407 return false;
3408 }
3409 SurveyQuestion::_includeClass($question_type);
3410 $question = new $question_type();
3411 $question->loadFromDb($question_id);
3412 return $question;
3413 }
3414
3421 public function locateImportFiles($a_dir)
3422 {
3423 if (!is_dir($a_dir) || is_int(strpos($a_dir, ".."))) {
3424 return;
3425 }
3426 $importDirectory = "";
3427 $xmlFile = "";
3428
3429 $current_dir = opendir($a_dir);
3430 $files = array();
3431 while ($entryname = readdir($current_dir)) {
3432 $files[] = $entryname;
3433 }
3434
3435 foreach ($files as $file) {
3436 if (is_dir($a_dir . "/" . $file) and ($file != "." and $file != "..")) {
3437 // found directory created by zip
3438 $importDirectory = $a_dir . "/" . $file;
3439 }
3440 }
3441 closedir($current_dir);
3442 if (strlen($importDirectory)) {
3443 // find the xml file
3444 $current_dir = opendir($importDirectory);
3445 $files = array();
3446 while ($entryname = readdir($current_dir)) {
3447 $files[] = $entryname;
3448 }
3449 foreach ($files as $file) {
3450 if (@is_file($importDirectory . "/" . $file) &&
3451 ($file != "." && $file != "..") &&
3452 (preg_match("/^[0-9]{10}__[0-9]+__(svy_)*[0-9]+\.[A-Za-z]{1,3}$/", $file) ||
3453 preg_match("/^[0-9]{10}__[0-9]+__(survey__)*[0-9]+\.[A-Za-z]{1,3}$/", $file))) {
3454 // found xml file
3455 $xmlFile = $importDirectory . "/" . $file;
3456 }
3457 }
3458 }
3459 return array("dir" => $importDirectory, "xml" => $xmlFile);
3460 }
3461
3470 public function importObject($file_info, $svy_qpl_id)
3471 {
3472 if ($svy_qpl_id < 1) {
3473 $svy_qpl_id = -1;
3474 }
3475 // check if file was uploaded
3476 $source = $file_info["tmp_name"];
3477 $error = "";
3478 if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK) {
3479 $error = $this->lng->txt("import_no_file_selected");
3480 }
3481 // check correct file type
3482 $isXml = false;
3483 $isZip = false;
3484 if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0)) {
3485 $this->log->debug("isXML");
3486 $isXml = true;
3487 }
3488 // too many different mime-types, so we use the suffix
3489 $suffix = pathinfo($file_info["name"]);
3490 if (strcmp(strtolower($suffix["extension"]), "zip") == 0) {
3491 $this->log->debug("isZip");
3492 $isZip = true;
3493 }
3494 if (!$isXml && !$isZip) {
3495 $error = $this->lng->txt("import_wrong_file_type");
3496 $this->log->debug("Survey: Import error. Filetype was \"" . $file_info["type"] . "\"");
3497 }
3498 if (strlen($error) == 0) {
3499 // import file as a survey
3500 $import_dir = $this->getImportDirectory();
3501 $import_subdir = "";
3502 $importfile = "";
3503 if ($isZip) {
3504 $importfile = $import_dir . "/" . $file_info["name"];
3505 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3506 ilUtil::unzip($importfile);
3507 $found = $this->locateImportFiles($import_dir);
3508 if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0))) {
3509 $error = $this->lng->txt("wrong_import_file_structure");
3510 return $error;
3511 }
3512 $importfile = $found["xml"];
3513 $import_subdir = $found["dir"];
3514 } else {
3515 $importfile = tempnam($import_dir, "survey_import");
3516 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3517 }
3518
3519 $this->log->debug("Import file = $importfile");
3520 $this->log->debug("Import subdir = $import_subdir");
3521
3522 $fh = fopen($importfile, "r");
3523 if (!$fh) {
3524 $error = $this->lng->txt("import_error_opening_file");
3525 return $error;
3526 }
3527 $xml = fread($fh, filesize($importfile));
3528 $result = fclose($fh);
3529 if (!$result) {
3530 $error = $this->lng->txt("import_error_closing_file");
3531 return $error;
3532 }
3533
3534 unset($_SESSION["import_mob_xhtml"]);
3535 if (strpos($xml, "questestinterop")) {
3536 throw new ilInvalidSurveyImportFileException("Unsupported survey version (< 3.8) found.");
3537 } else {
3538 $this->log->debug("survey id = " . $this->getId());
3539 $this->log->debug("question pool id = " . $svy_qpl_id);
3540
3541 $imp = new ilImport();
3542 $config = $imp->getConfig("Modules/Survey");
3543 $config->setQuestionPoolID($svy_qpl_id);
3544 $imp->getMapping()->addMapping("Modules/Survey", "svy", 0, $this->getId());
3545 $imp->importFromDirectory($import_subdir, "svy", "Modules/Survey");
3546 $this->log->debug("config(Modules/survey)->getQuestionPoolId =" . $config->getQuestionPoolID());
3547 return "";
3548
3549 //old code
3550 $import = new SurveyImportParser($svy_qpl_id, "", true);
3551 $import->setSurveyObject($this);
3552 $import->setXMLContent($xml);
3553 $import->startParsing();
3554 }
3555
3556 if (is_array($_SESSION["import_mob_xhtml"])) {
3557 foreach ($_SESSION["import_mob_xhtml"] as $mob) {
3558 $importfile = $import_subdir . "/" . $mob["uri"];
3559 if (file_exists($importfile)) {
3560 if (!$mob["type"]) {
3561 $mob["type"] = "svy:html";
3562 }
3563
3564 $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, false);
3565
3566 // survey mob
3567 if ($mob["type"] == "svy:html") {
3568 ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
3569 $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
3570 $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
3571 }
3572 // question mob
3573 elseif ($import->questions[$mob["id"]]) {
3574 $new_qid = $import->questions[$mob["id"]];
3575 ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
3576 $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
3577 $qtext = $new_question->getQuestiontext();
3578 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
3579 $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
3580 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
3581 $new_question->setQuestiontext($qtext);
3582 $new_question->saveToDb();
3583
3584 // also fix existing original in pool
3585 if ($new_question->getOriginalId()) {
3586 $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
3587 $pool_question->setQuestiontext($qtext);
3588 $pool_question->saveToDb();
3589 }
3590 }
3591 } else {
3593 $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
3594 }
3595 }
3598 $this->saveToDb();
3599 }
3600
3601 // delete import directory
3603 }
3604 return $error;
3605 }
3606
3615 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
3616 {
3617 $ilDB = $this->db;
3618
3619 $this->loadFromDb();
3620
3621 //survey mode
3622 $svy_type = $this->getMode();
3623
3624 // Copy settings
3625 $newObj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
3626 $this->cloneMetaData($newObj);
3627 $newObj->updateMetaData();
3628
3629 $newObj->setAuthor($this->getAuthor());
3630 $newObj->setIntroduction($this->getIntroduction());
3631 $newObj->setOutro($this->getOutro());
3632 $newObj->setEvaluationAccess($this->getEvaluationAccess());
3633 $newObj->setStartDate($this->getStartDate());
3634 $newObj->setEndDate($this->getEndDate());
3635 $newObj->setAnonymize($this->getAnonymize());
3636 $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
3637 $newObj->setTemplate($this->getTemplate());
3638 $newObj->setPoolUsage($this->getPoolUsage());
3639 $newObj->setViewOwnResults($this->hasViewOwnResults());
3640 $newObj->setMailOwnResults($this->hasMailOwnResults());
3641 $newObj->setMailConfirmation($this->hasMailConfirmation());
3642 $newObj->setAnonymousUserList($this->hasAnonymousUserList());
3643
3644 // #12661
3645 if ($this->get360Mode()) {
3646 $newObj->setMode(ilObjSurvey::MODE_360);
3647 $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
3648 $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
3649 $newObj->set360SelfRaters($this->get360SelfRaters());
3650 $newObj->set360Results($this->get360Results());
3651 $newObj->setSkillService($this->getSkillService());
3652 }
3653 //svy mode self eval: skills + view results
3654 if ($svy_type == ilObjSurvey::MODE_SELF_EVAL) {
3655 $newObj->setMode(ilObjSurvey::MODE_SELF_EVAL);
3656 $newObj->setSkillService($this->getSkillService());
3657 $newObj->setSelfEvaluationResults($this->getSelfEvaluationResults());
3658 }
3659
3660 // reminder/notification
3661 $newObj->setReminderStatus($this->getReminderStatus());
3662 $newObj->setReminderStart($this->getReminderStart());
3663 $newObj->setReminderEnd($this->getReminderEnd());
3664 $newObj->setReminderFrequency($this->getReminderFrequency());
3665 $newObj->setReminderTarget($this->getReminderTarget());
3666 $newObj->setReminderTemplate($this->getReminderTemplate());
3667 // reminder_last_sent must not be copied!
3668 $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
3669 $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
3670 $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
3671 $newObj->setTutorResultsStatus($this->getTutorResultsStatus());
3672 $newObj->setTutorResultsRecipients($this->getTutorResultsRecipients());
3673
3674 $newObj->setMailNotification($this->getMailNotification());
3675 $newObj->setMailAddresses($this->getMailAddresses());
3676 $newObj->setMailParticipantData($this->getMailParticipantData());
3677
3678 $question_pointer = array();
3679 // clone the questions
3680 $mapping = array();
3681
3682 foreach ($this->questions as $key => $question_id) {
3684 $question = self::_instanciateQuestion($question_id);
3685 if ($question) { // #10824
3686 $question->id = -1;
3687 $original_id = SurveyQuestion::_getOriginalId($question_id, false);
3688 $question->setObjId($newObj->getId());
3689 $question->saveToDb($original_id);
3690 $newObj->questions[$key] = $question->getId();
3691 $question_pointer[$question_id] = $question->getId();
3692 $mapping[$question_id] = $question->getId();
3693 }
3694 }
3695
3696 //copy online status if object is not the root copy object
3697 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
3698
3699 if (!$cp_options->isRootNode($this->getRefId())) {
3700 $newObj->setOfflineStatus($this->getOfflineStatus());
3701 }
3702
3703 $newObj->saveToDb();
3704 $newObj->cloneTextblocks($mapping);
3705
3706 // #14929
3707 if (($svy_type == ilObjSurvey::MODE_360 || $svy_type == ilObjSurvey::MODE_SELF_EVAL) &&
3708 $this->getSkillService()) {
3709 $src_skills = new ilSurveySkill($this);
3710 $tgt_skills = new ilSurveySkill($newObj);
3711
3712 foreach ($mapping as $src_qst_id => $tgt_qst_id) {
3713 $qst_skill = $src_skills->getSkillForQuestion($src_qst_id);
3714 if ($qst_skill) {
3715 $tgt_skills->addQuestionSkillAssignment($tgt_qst_id, $qst_skill["base_skill_id"], $qst_skill["tref_id"]);
3716 }
3717 }
3718 }
3719
3720 // clone the questionblocks
3721 $questionblocks = array();
3722 $questionblock_questions = array();
3723 $result = $ilDB->queryF(
3724 "SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
3725 array('integer'),
3726 array($this->getSurveyId())
3727 );
3728 if ($result->numRows() > 0) {
3729 while ($row = $ilDB->fetchAssoc($result)) {
3730 array_push($questionblock_questions, $row);
3731 $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
3732 }
3733 }
3734 // create new questionblocks
3735 foreach ($questionblocks as $key => $value) {
3736 $questionblock = self::_getQuestionblock($key);
3737 $questionblock_id = self::_addQuestionblock($questionblock["title"], $questionblock["owner_fi"], $questionblock["show_questiontext"], $questionblock["show_blocktitle"]);
3738 $questionblocks[$key] = $questionblock_id;
3739 }
3740 // create new questionblock questions
3741 foreach ($questionblock_questions as $key => $value) {
3742 if ($questionblocks[$value["questionblock_fi"]] &&
3743 $question_pointer[$value["question_fi"]]) {
3744 $next_id = $ilDB->nextId('svy_qblk_qst');
3745 $affectedRows = $ilDB->manipulateF(
3746 "INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) " .
3747 "VALUES (%s, %s, %s, %s)",
3748 array('integer','integer','integer','integer'),
3749 array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
3750 );
3751 }
3752 }
3753
3754 // clone the constraints
3755 $constraints = self::_getConstraints($this->getSurveyId());
3756 $newConstraints = array();
3757 foreach ($constraints as $key => $constraint) {
3758 if ($question_pointer[$constraint["for_question"]] &&
3759 $question_pointer[$constraint["question"]]) {
3760 if (!array_key_exists($constraint['id'], $newConstraints)) {
3761 $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
3762 $newConstraints[$constraint['id']] = $constraint_id;
3763 }
3764 $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
3765 }
3766 }
3767
3768 // #16210 - clone LP settings
3769 $obj_settings = new ilLPObjSettings($this->getId());
3770 $obj_settings->cloneSettings($newObj->getId());
3771 unset($obj_settings);
3772
3773 return $newObj;
3774 }
3775
3776 public function getTextblock($question_id)
3777 {
3778 $ilDB = $this->db;
3779 $result = $ilDB->queryF(
3780 "SELECT * FROM svy_svy_qst WHERE question_fi = %s",
3781 array('integer'),
3782 array($question_id)
3783 );
3784 if ($result->numRows()) {
3785 $row = $ilDB->fetchAssoc($result);
3786 return $row["heading"];
3787 } else {
3788 return "";
3789 }
3790 }
3791
3797 public function cloneTextblocks($mapping)
3798 {
3799 foreach ($mapping as $original_id => $new_id) {
3800 $textblock = $this->getTextblock($original_id);
3801 $this->saveHeading(ilUtil::stripSlashes($textblock, true, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
3802 }
3803 }
3804
3812 public function createExportDirectory()
3813 {
3814 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
3815 ilUtil::makeDir($svy_data_dir);
3816 if (!is_writable($svy_data_dir)) {
3817 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
3818 }
3819
3820 // create learning module directory (data_dir/lm_data/lm_<id>)
3821 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
3822 ilUtil::makeDir($svy_dir);
3823 if (!@is_dir($svy_dir)) {
3824 throw new ilSurveyException("Creation of Survey Directory failed.");
3825 }
3826 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
3827 $export_dir = $svy_dir . "/export";
3828 ilUtil::makeDir($export_dir);
3829 if (!@is_dir($export_dir)) {
3830 throw new ilSurveyException("Creation of Export Directory failed.");
3831 }
3832 }
3833
3837 public function getExportDirectory()
3838 {
3839 $export_dir = ilUtil::getDataDir() . "/svy_data" . "/svy_" . $this->getId() . "/export";
3840
3841 return $export_dir;
3842 }
3843
3851 public function createImportDirectory()
3852 {
3853 $svy_data_dir = ilUtil::getDataDir() . "/svy_data";
3854 ilUtil::makeDir($svy_data_dir);
3855
3856 if (!is_writable($svy_data_dir)) {
3857 throw new ilSurveyException("Survey Data Directory (" . $svy_data_dir . ") not writeable.");
3858 }
3859
3860 // create test directory (data_dir/svy_data/svy_<id>)
3861 $svy_dir = $svy_data_dir . "/svy_" . $this->getId();
3862 ilUtil::makeDir($svy_dir);
3863 if (!@is_dir($svy_dir)) {
3864 throw new ilSurveyException("Creation of Survey Directory failed.");
3865 }
3866
3867 // create import subdirectory (data_dir/svy_data/svy_<id>/import)
3868 $import_dir = $svy_dir . "/import";
3869 ilUtil::makeDir($import_dir);
3870 if (!@is_dir($import_dir)) {
3871 throw new ilSurveyException("Creation of Import Directory failed.");
3872 }
3873 }
3874
3878 public function getImportDirectory()
3879 {
3880 $import_dir = ilUtil::getDataDir() . "/svy_data" .
3881 "/svy_" . $this->getId() . "/import";
3882 if (!is_dir($import_dir)) {
3883 ilUtil::makeDirParents($import_dir);
3884 }
3885 if (@is_dir($import_dir)) {
3886 return $import_dir;
3887 } else {
3888 return false;
3889 }
3890 }
3891
3892 public function saveHeading($heading = "", $insertbefore)
3893 {
3894 $ilDB = $this->db;
3895 if ($heading) {
3896 $affectedRows = $ilDB->manipulateF(
3897 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
3898 array('text','integer','integer'),
3899 array($heading, $this->getSurveyId(), $insertbefore)
3900 );
3901 } else {
3902 $affectedRows = $ilDB->manipulateF(
3903 "UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
3904 array('text','integer','integer'),
3905 array(null, $this->getSurveyId(), $insertbefore)
3906 );
3907 }
3908 }
3909
3910 public function isAnonymousKey($key)
3911 {
3912 $ilDB = $this->db;
3913
3914 $result = $ilDB->queryF(
3915 "SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
3916 array('text','integer'),
3917 array($key, $this->getSurveyId())
3918 );
3919 return ($result->numRows() == 1) ? true : false;
3920 }
3921
3922 public function bindSurveyCodeToUser($user_id, $code)
3923 {
3924 $ilDB = $this->db;
3925
3926 if ($user_id == ANONYMOUS_USER_ID) {
3927 return;
3928 }
3929
3930 if ($this->checkSurveyCode($code)) {
3931 $ilDB->manipulate("UPDATE svy_anonymous" .
3932 " SET user_key = " . $ilDB->quote(md5($user_id), "text") .
3933 " WHERE survey_key = " . $ilDB->quote($code, "text"));
3934 }
3935 }
3936
3937 public function isAnonymizedParticipant($key)
3938 {
3939 $ilDB = $this->db;
3940
3941 $result = $ilDB->queryF(
3942 "SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
3943 array('text','integer'),
3944 array($key, $this->getSurveyId())
3945 );
3946 return ($result->numRows() == 1) ? true : false;
3947 }
3948
3949 public function checkSurveyCode($code)
3950 {
3951 if ($this->isAnonymousKey($code)) {
3952 if ($this->isSurveyStarted("", $code) == 1) {
3953 return false;
3954 } else {
3955 return true;
3956 }
3957 } else {
3958 return false;
3959 }
3960 }
3961
3969 public function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
3970 {
3971 $ilDB = $this->db;
3973 $lng = $this->lng;
3974
3975 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
3976 " FROM svy_anonymous" .
3977 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
3978 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
3979 " AND svy_anonymous.user_key IS NULL";
3980
3981 if ($a_codes) {
3982 $sql .= " AND " . $ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
3983 } elseif ($a_ids) {
3984 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
3985 }
3986
3987 $export = array();
3988
3989 // #14905
3990 $titles = array();
3991 $titles[] = '"' . $lng->txt("survey_code") . '"';
3992 $titles[] = '"' . $lng->txt("email") . '"';
3993 $titles[] = '"' . $lng->txt("lastname") . '"';
3994 $titles[] = '"' . $lng->txt("firstname") . '"';
3995 $titles[] = '"' . $lng->txt("create_date") . '"';
3996 $titles[] = '"' . $lng->txt("used") . '"';
3997 $titles[] = '"' . $lng->txt("mail_sent_short") . '"';
3998 $titles[] = '"' . $lng->txt("survey_code_url") . '"';
3999 $export[] = implode(";", $titles);
4000
4001 $result = $ilDB->query($sql);
4002 $default_lang = $ilUser->getPref("survey_code_language");
4003 while ($row = $ilDB->fetchAssoc($result)) {
4004 $item = array();
4005 $item[] = $row["survey_key"];
4006
4007 if ($row["externaldata"]) {
4008 $ext = unserialize($row["externaldata"]);
4009 $item[] = $ext["email"];
4010 $item[] = $ext["lastname"];
4011 $item[] = $ext["firstname"];
4012 } else {
4013 $item[] = "";
4014 $item[] = "";
4015 $item[] = "";
4016 }
4017
4018 // No relative (today, tomorrow...) dates in export.
4019 $date = new ilDateTime($row['tstamp'], IL_CAL_UNIX);
4020 $item[] = $date->get(IL_CAL_DATETIME);
4021
4022 $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4023 $item[] = ($row["sent"]) ? 1 : 0;
4024
4025 $params = array("accesscode" => $row["survey_key"]);
4026 if ($default_lang) {
4027 $params["lang"] = $default_lang;
4028 }
4029 $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4030
4031 $export[] = '"' . implode('";"', $item) . '"';
4032 }
4033 return implode("\n", $export);
4034 }
4035
4043 public function getSurveyCodesTableData(array $ids = null, $lang = null)
4044 {
4045 $ilDB = $this->db;
4046
4047 $codes = array();
4048
4049 $sql = "SELECT svy_anonymous.*, svy_finished.state" .
4050 " FROM svy_anonymous" .
4051 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)" .
4052 " WHERE svy_anonymous.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") /*.
4053 " AND svy_anonymous.user_key IS NULL" */; // #15860
4054
4055 if ($ids) {
4056 $sql .= " AND " . $ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4057 }
4058
4059 $sql .= " ORDER BY tstamp, survey_key ASC";
4060 $result = $ilDB->query($sql);
4061 if ($result->numRows() > 0) {
4062 while ($row = $ilDB->fetchAssoc($result)) {
4063 $href = "";
4064 $used = false;
4065 if ($this->isSurveyCodeUsed($row["survey_key"])) {
4066 $used = true;
4067 } else {
4068 $params = array("accesscode" => $row["survey_key"]);
4069 if ($lang) {
4070 $params["lang"] = $lang;
4071 }
4072 $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4073 }
4074
4075
4076 $item = array(
4077 'id' => $row["anonymous_id"],
4078 'code' => $row["survey_key"],
4079 'date' => $row["tstamp"],
4080 'used' => $used,
4081 'sent' => $row['sent'],
4082 'href' => $href,
4083 'email' => '',
4084 'last_name' => '',
4085 'first_name' => ''
4086 );
4087
4088 if ($row["externaldata"]) {
4089 $ext = unserialize($row["externaldata"]);
4090 $item['email'] = $ext['email'];
4091 $item['last_name'] = $ext['lastname'];
4092 $item['first_name'] = $ext['firstname'];
4093 }
4094
4095 array_push($codes, $item);
4096 }
4097 }
4098 return $codes;
4099 }
4100
4101 public function isSurveyCodeUsed($code)
4102 {
4103 $ilDB = $this->db;
4104 $result = $ilDB->queryF(
4105 "SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4106 array('integer','text'),
4107 array($this->getSurveyId(), $code)
4108 );
4109 return ($result->numRows() > 0) ? true : false;
4110 }
4111
4112 public function isSurveyCodeUnique($code)
4113 {
4114 $ilDB = $this->db;
4115 $result = $ilDB->queryF(
4116 "SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4117 array('integer','text'),
4118 array($this->getSurveyId(), $code)
4119 );
4120 return ($result->numRows() > 0) ? false : true;
4121 }
4122
4123 public function createSurveyCodes($nrOfCodes)
4124 {
4125 $ilDB = $this->db;
4126
4127 $res = array();
4128
4129 for ($i = 0; $i < $nrOfCodes; $i++) {
4130 $next_id = $ilDB->nextId('svy_anonymous');
4131 $ilDB->manipulateF(
4132 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) " .
4133 "VALUES (%s, %s, %s, %s)",
4134 array('integer','text','integer','integer'),
4135 array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4136 );
4137 $res[] = $next_id;
4138 }
4139
4140 return $res;
4141 }
4142
4143 public function importSurveyCode($a_anonymize_key, $a_created, $a_data)
4144 {
4145 $ilDB = $this->db;
4146
4147 $next_id = $ilDB->nextId('svy_anonymous');
4148 $ilDB->manipulateF(
4149 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4150 "VALUES (%s, %s, %s, %s, %s)",
4151 array('integer','text','integer','text','integer'),
4152 array($next_id, $a_anonymize_key, $this->getSurveyId(), serialize($a_data), $a_created)
4153 );
4154 }
4155
4157 {
4158 $ilDB = $this->db;
4159
4160 $ids = array();
4161 foreach ($data as $dataset) {
4162 $anonymize_key = $this->createNewAccessCode();
4163 $next_id = $ilDB->nextId('svy_anonymous');
4164 $affectedRows = $ilDB->manipulateF(
4165 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) " .
4166 "VALUES (%s, %s, %s, %s, %s)",
4167 array('integer','text','integer','text','integer'),
4168 array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
4169 );
4170 $ids[] = $next_id;
4171 }
4172 return $ids;
4173 }
4174
4175 public function sendCodes($not_sent, $subject, $message, $lang)
4176 {
4177 global $DIC;
4178 /*
4179 * 0 = all
4180 * 1 = not sent
4181 * 2 = finished
4182 * 3 = not finished
4183 */
4184 $check_finished = ($not_sent > 1);
4185
4186
4187 $mail = new ilMail(ANONYMOUS_USER_ID);
4188 $recipients = $this->getExternalCodeRecipients($check_finished);
4189 foreach ($recipients as $data) {
4190 if ($data['email'] && $data['code']) {
4191 $do_send = false;
4192 switch ((int) $not_sent) {
4193 case 1:
4194 $do_send = !(bool) $data['sent'];
4195 break;
4196
4197 case 2:
4198 $do_send = $data['finished'];
4199 break;
4200
4201 case 3:
4202 $do_send = !$data['finished'];
4203 break;
4204
4205 default:
4206 $do_send = true;
4207 break;
4208 }
4209 if ($do_send) {
4210 // build text
4211 $messagetext = $message;
4213 $this->getRefId(),
4214 "svy",
4215 array(
4216 "accesscode" => $data["code"],
4217 "lang" => $lang
4218 )
4219 );
4220 $messagetext = str_replace('[url]', $url, $messagetext);
4221 foreach ($data as $key => $value) {
4222 $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
4223 }
4224
4225 // send mail
4226 $mail->enqueue(
4227 $data['email'], // to
4228 "", // cc
4229 "", // bcc
4230 $subject, // subject
4231 $messagetext, // message
4232 array() // attachments
4233 );
4234 }
4235 }
4236 }
4237
4238 $ilDB = $this->db;
4239 $ilDB->manipulateF(
4240 "UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
4241 array('integer','integer'),
4242 array(1, $this->getSurveyId())
4243 );
4244 }
4245
4246 public function getExternalCodeRecipients($a_check_finished = false)
4247 {
4248 $ilDB = $this->db;
4249 $result = $ilDB->queryF(
4250 "SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
4251 array('integer'),
4252 array($this->getSurveyId())
4253 );
4254 $res = array();
4255 while ($row = $ilDB->fetchAssoc($result)) {
4256 if (!$row['externaldata']) {
4257 continue;
4258 }
4259
4260 $externaldata = unserialize($row['externaldata']);
4261 if (!$externaldata['email']) {
4262 continue;
4263 }
4264
4265 $externaldata['code'] = $row['code'];
4266 $externaldata['sent'] = $row['sent'];
4267
4268 if ($a_check_finished) {
4269 #23294
4270 //$externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
4271 $externaldata['finished'] = $this->isSurveyFinishedByCode($row['code']);
4272 }
4273
4274 array_push($res, $externaldata);
4275 }
4276 return $res;
4277 }
4278
4284 public function isSurveyFinishedByCode($a_code)
4285 {
4286 $result = $this->db->queryF(
4287 "SELECT state FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4288 array('integer','text'),
4289 array($this->getSurveyId(), $a_code)
4290 );
4291
4292 $row = $this->db->fetchAssoc($result);
4293
4294 return $row['state'];
4295 }
4296
4302 public function deleteSurveyCode($survey_code)
4303 {
4304 $ilDB = $this->db;
4305
4306 if (strlen($survey_code) > 0) {
4307 $affectedRows = $ilDB->manipulateF(
4308 "DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4309 array('integer', 'text'),
4310 array($this->getSurveyId(), $survey_code)
4311 );
4312 }
4313 }
4314
4321 public function getUserAccessCode($user_id)
4322 {
4323 $ilDB = $this->db;
4324 $access_code = "";
4325 $result = $ilDB->queryF(
4326 "SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
4327 array('integer','text'),
4328 array($this->getSurveyId(), md5($user_id))
4329 );
4330 if ($result->numRows()) {
4331 $row = $ilDB->fetchAssoc($result);
4332 $access_code = $row["survey_key"];
4333 }
4334 return $access_code;
4335 }
4336
4343 public function saveUserAccessCode($user_id, $access_code)
4344 {
4345 $ilDB = $this->db;
4346
4347 // not really sure what to do about ANONYMOUS_USER_ID
4348
4349 $next_id = $ilDB->nextId('svy_anonymous');
4350 $affectedRows = $ilDB->manipulateF(
4351 "INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) " .
4352 "VALUES (%s, %s, %s, %s, %s)",
4353 array('integer','text', 'integer', 'text', 'integer'),
4354 array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
4355 );
4356 }
4357
4363 public function createNewAccessCode()
4364 {
4365 // create a 5 character code
4366 $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4367 mt_srand();
4368 $code = "";
4369 for ($i = 1; $i <= 5; $i++) {
4370 $index = mt_rand(0, strlen($codestring) - 1);
4371 $code .= substr($codestring, $index, 1);
4372 }
4373 // verify it against the database
4374 while (!$this->isSurveyCodeUnique($code)) {
4375 $code = $this->createNewAccessCode();
4376 }
4377 return $code;
4378 }
4379
4380 public function getLastAccess($finished_id)
4381 {
4382 $ilDB = $this->db;
4383
4384 $result = $ilDB->queryF(
4385 "SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
4386 array('integer'),
4387 array($finished_id)
4388 );
4389 if ($result->numRows()) {
4390 $row = $ilDB->fetchAssoc($result);
4391 return $row["tstamp"];
4392 } else {
4393 $result = $ilDB->queryF(
4394 "SELECT tstamp FROM svy_finished WHERE finished_id = %s",
4395 array('integer'),
4396 array($finished_id)
4397 );
4398 if ($result->numRows()) {
4399 $row = $ilDB->fetchAssoc($result);
4400 return $row["tstamp"];
4401 }
4402 }
4403 return "";
4404 }
4405
4412 public function prepareTextareaOutput($txt_output)
4413 {
4414 return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
4415 }
4416
4424 public function isHTML($a_text)
4425 {
4426 if (preg_match("/<[^>]*?>/", $a_text)) {
4427 return true;
4428 } else {
4429 return false;
4430 }
4431 }
4432
4441 public function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = true, $add_mobs = true, $attribs = null)
4442 {
4443 $a_xml_writer->xmlStartTag("material", $attribs);
4444 $attrs = array(
4445 "type" => "text/plain"
4446 );
4447 if ($this->isHTML($a_material)) {
4448 $attrs["type"] = "text/xhtml";
4449 }
4450 $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
4451 $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
4452
4453 if ($add_mobs) {
4454 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
4455 foreach ($mobs as $mob) {
4456 $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
4457 if (strpos($mattext, $mob_id) !== false) {
4458 $mob_obj = new ilObjMediaObject($mob);
4459 $imgattrs = array(
4460 "label" => $mob_id,
4461 "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
4462 "type" => "svy:html",
4463 "id" => $this->getId()
4464 );
4465 $a_xml_writer->xmlElement("matimage", $imgattrs, null);
4466 }
4467 }
4468 }
4469 if ($close_material_tag) {
4470 $a_xml_writer->xmlEndTag("material");
4471 }
4472 }
4473
4482 public function canExportSurveyCode()
4483 {
4484 if ($this->getAnonymize() != self::ANONYMIZE_OFF) {
4485 if ($this->surveyCodeSecurity == false) {
4486 return true;
4487 }
4488 }
4489 return false;
4490 }
4491
4499 public function processPrintoutput2FO($print_output)
4500 {
4501 if (extension_loaded("tidy")) {
4502 $config = array(
4503 "indent" => false,
4504 "output-xml" => true,
4505 "numeric-entities" => true
4506 );
4507 $tidy = new tidy();
4508 $tidy->parseString($print_output, $config, 'utf8');
4509 $tidy->cleanRepair();
4510 $print_output = tidy_get_output($tidy);
4511 $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
4512 } else {
4513 $print_output = str_replace("&nbsp;", "&#160;", $print_output);
4514 $print_output = str_replace("&otimes;", "X", $print_output);
4515
4516 // #17680 - metric questions use &#160; in print view
4517 $print_output = str_replace("&gt;", "~|gt|~", $print_output); // see #21550
4518 $print_output = str_replace("&lt;", "~|lt|~", $print_output);
4519 $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
4520 $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
4521 $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
4522 $print_output = str_replace("~|gt|~", "&gt;", $print_output);
4523 $print_output = str_replace("~|lt|~", "&lt;", $print_output);
4524 }
4525 $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
4526
4527 // additional font support
4528 $xsl = str_replace(
4529 'font-family="Helvetica, unifont"',
4530 'font-family="' . $GLOBALS['ilSetting']->get('rpc_pdf_font', 'Helvetica, unifont') . '"',
4531 $xsl
4532 );
4533 $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
4534 $xh = xslt_create();
4535 $params = array();
4536 try {
4537 $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
4538 } catch (Exception $e) {
4539 $this->log->error("Print XSLT failed:");
4540 $this->log->error("Content: " . $print_output);
4541 $this->log->error("Xsl: " . $xsl);
4542 throw ($e);
4543 }
4544 xslt_error($xh);
4545 xslt_free($xh);
4546
4547 return $output;
4548 }
4549
4556 public function deliverPDFfromFO($fo)
4557 {
4559
4560 $fo_file = ilUtil::ilTempnam() . ".fo";
4561 $fp = fopen($fo_file, "w");
4562 fwrite($fp, $fo);
4563 fclose($fp);
4564
4565 try {
4566 $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
4567 ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
4568 return true;
4569 } catch (Exception $e) {
4570 $ilLog->write(__METHOD__ . ': ' . $e->getMessage());
4571 return false;
4572 }
4573 }
4574
4581 public function isPluginActive($a_pname)
4582 {
4583 $ilPluginAdmin = $this->plugin_admin;
4584 if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname)) {
4585 return true;
4586 } else {
4587 return false;
4588 }
4589 }
4590
4596 public function setSurveyId($survey_id)
4597 {
4598 $this->survey_id = $survey_id;
4599 }
4600
4607 public function &getUserData($ids)
4608 {
4609 $ilDB = $this->db;
4610
4611 if (!is_array($ids) || count($ids) == 0) {
4612 return array();
4613 }
4614
4615 $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
4616 $result_array = array();
4617 while ($row = $ilDB->fetchAssoc($result)) {
4618 $result_array[$row["usr_id"]] = $row;
4619 }
4620 return $result_array;
4621 }
4622
4623 public function getMailNotification()
4624 {
4626 }
4627
4628 public function setMailNotification($a_notification)
4629 {
4630 $this->mailnotification = ($a_notification) ? true : false;
4631 }
4632
4633 public function getMailAddresses()
4634 {
4635 return $this->mailaddresses;
4636 }
4637
4638 public function setMailAddresses($a_addresses)
4639 {
4640 $this->mailaddresses = $a_addresses;
4641 }
4642
4643 public function getMailParticipantData()
4644 {
4646 }
4647
4648 public function setMailParticipantData($a_data)
4649 {
4650 $this->mailparticipantdata = $a_data;
4651 }
4652
4653 public function setStartTime($finished_id, $first_question)
4654 {
4655 $ilDB = $this->db;
4656 $time = time();
4657 //primary for table svy_times
4658 $id = $ilDB->nextId('svy_times');
4659 $_SESSION['svy_entered_page'] = $time;
4660 $affectedRows = $ilDB->manipulateF(
4661 "INSERT INTO svy_times (id, finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s,%s)",
4662 array('integer','integer', 'integer', 'integer', 'integer'),
4663 array($id, $finished_id, $time, null, $first_question)
4664 );
4665 }
4666
4667 public function setEndTime($finished_id)
4668 {
4669 $ilDB = $this->db;
4670 $time = time();
4671 $affectedRows = $ilDB->manipulateF(
4672 "UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
4673 array('integer', 'integer', 'integer'),
4674 array($time, $finished_id, $_SESSION['svy_entered_page'])
4675 );
4676 unset($_SESSION['svy_entered_page']);
4677 }
4678
4679 public function getWorkingtimeForParticipant($finished_id)
4680 {
4681 $ilDB = $this->db;
4682
4683 $result = $ilDB->queryF(
4684 "SELECT * FROM svy_times WHERE finished_fi = %s",
4685 array('integer'),
4686 array($finished_id)
4687 );
4688 $total = 0;
4689 while ($row = $ilDB->fetchAssoc($result)) {
4690 if ($row['left_page'] > 0 && $row['entered_page'] > 0) {
4691 $total += $row['left_page'] - $row['entered_page'];
4692 }
4693 }
4694 return $total;
4695 }
4696
4697 public function setTemplate($template_id)
4698 {
4699 $this->template_id = (int) $template_id;
4700 }
4701
4702 public function getTemplate()
4703 {
4704 return $this->template_id;
4705 }
4706
4707 public function updateOrder(array $a_order)
4708 {
4709 if (sizeof($this->questions) == sizeof($a_order)) {
4710 $this->questions = array_flip($a_order);
4711 $this->saveQuestionsToDB();
4712 }
4713 }
4714
4715 public function getPoolUsage()
4716 {
4717 return $this->pool_usage;
4718 }
4719
4720 public function setPoolUsage($a_value)
4721 {
4722 $this->pool_usage = (bool) $a_value;
4723 }
4724
4730 public function isPoolActive()
4731 {
4732 $use_pool = (bool) $this->getPoolUsage();
4733 $template_settings = $this->getTemplate();
4734 if ($template_settings) {
4735 $template_settings = new ilSettingsTemplate($template_settings);
4736 $template_settings = $template_settings->getSettings();
4737 $template_settings = $template_settings["use_pool"];
4738 if ($template_settings && $template_settings["hide"]) {
4739 $use_pool = (bool) $template_settings["value"];
4740 }
4741 }
4742 return $use_pool;
4743 }
4744
4751 {
4752 if (!$template_id) {
4753 return;
4754 }
4755
4756 $template = new ilSettingsTemplate($template_id);
4757 $template_settings = $template->getSettings();
4758 //ilUtil::dumpVar($template_settings); exit;
4759 if ($template_settings) {
4760 if ($template_settings["show_question_titles"] !== null) {
4761 if ($template_settings["show_question_titles"]["value"]) {
4762 $this->setShowQuestionTitles(true);
4763 } else {
4764 $this->setShowQuestionTitles(false);
4765 }
4766 }
4767
4768 if ($template_settings["use_pool"] !== null) {
4769 if ($template_settings["use_pool"]["value"]) {
4770 $this->setPoolUsage(true);
4771 } else {
4772 $this->setPoolUsage(false);
4773 }
4774 }
4775
4776
4777 /* see #0021719
4778 if($template_settings["anonymization_options"]["value"])
4779 {
4780 $anon_map = array('personalized' => self::ANONYMIZE_OFF,
4781 'anonymize_with_code' => self::ANONYMIZE_ON,
4782 'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
4783 $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
4784 }*/
4785
4786 // see #0021719 and ilObjectSurveyGUI::savePropertiesObject
4787 $this->setEvaluationAccess($template_settings["evaluation_access"]["value"]);
4788 $codes = (bool) $template_settings["acc_codes"]["value"];
4789 $anon = (bool) $template_settings["anonymization_options"]["value"];
4790 if (!$anon) {
4791 if (!$codes) {
4793 } else {
4795 }
4796 } else {
4797 if ($codes) {
4799 } else {
4801 }
4802
4803 $this->setAnonymousUserList($_POST["anon_list"]);
4804 }
4805
4806
4807
4808 /* other settings: not needed here
4809 * - enabled_end_date
4810 * - enabled_start_date
4811 * - rte_switch
4812 */
4813 }
4814
4815 $this->setTemplate($template_id);
4816 $this->saveToDb();
4817 }
4818
4819 public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
4820 {
4821 $ilDB = $this->db;
4822
4823 $a_email = trim($a_email);
4824
4825 // :TODO:
4826 if (($a_email && !ilUtil::is_email($a_email)) || $a_email == "") {
4827 return false;
4828 }
4829
4830 $data = array("email" => $a_email,
4831 "lastname" => trim($a_last_name),
4832 "firstname" => trim($a_first_name));
4833
4834 $fields = array(
4835 "externaldata" => array("text", serialize($data)),
4836 "sent" => array("integer", $a_sent)
4837 );
4838
4839 $ilDB->update(
4840 "svy_anonymous",
4841 $fields,
4842 array("anonymous_id" => array("integer", $a_id))
4843 );
4844
4845 return true;
4846 }
4847
4848
4849 //
4850 // 360°
4851 //
4852
4853 public function get360Mode()
4854 {
4855 if ($this->getMode() == ilObjSurvey::MODE_360) {
4856 return true;
4857 }
4858 return false;
4859 }
4860
4861 public function set360SelfEvaluation($a_value)
4862 {
4863 $this->mode_360_self_eval = (bool) $a_value;
4864 }
4865
4866 public function get360SelfEvaluation()
4867 {
4868 return (bool) $this->mode_360_self_eval;
4869 }
4870
4871 public function set360SelfAppraisee($a_value)
4872 {
4873 $this->mode_360_self_appr = (bool) $a_value;
4874 }
4875
4876 public function get360SelfAppraisee()
4877 {
4878 return (bool) $this->mode_360_self_appr;
4879 }
4880
4881 public function set360SelfRaters($a_value)
4882 {
4883 $this->mode_360_self_rate = (bool) $a_value;
4884 }
4885
4886 public function get360SelfRaters()
4887 {
4888 return (bool) $this->mode_360_self_rate;
4889 }
4890
4891 public function set360Results($a_value)
4892 {
4893 $this->mode_360_results = (int) $a_value;
4894 }
4895
4896 public function get360Results()
4897 {
4898 return (int) $this->mode_360_results;
4899 }
4900
4901 public function addAppraisee($a_user_id)
4902 {
4903 global $DIC;
4904
4905 $ilDB = $DIC->database();
4906 $access = $DIC->access();
4907
4908 if (!$this->isAppraisee($a_user_id) &&
4909 $a_user_id != ANONYMOUS_USER_ID) {
4910 $fields = array(
4911 "obj_id" => array("integer", $this->getSurveyId()),
4912 "user_id" => array("integer", $a_user_id)
4913 );
4914 $ilDB->insert("svy_360_appr", $fields);
4915
4916 // send notification and add to desktop
4917 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
4918 $this->sendAppraiseeNotification($a_user_id);
4919 }
4920 }
4921 }
4922
4928 public function sendAppraiseeNotification($a_user_id)
4929 {
4930 $ntf = new ilSystemNotification();
4931 $ntf->setLangModules(array("svy", "survey"));
4932 $ntf->setRefId($this->getRefId());
4933 $ntf->setGotoLangId('url');
4934
4935 // user specific language
4936 $lng = $ntf->getUserLanguage($a_user_id);
4937
4938 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_mail");
4939 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
4940
4941 // #10044
4942 $mail = new ilMail(ANONYMOUS_USER_ID);
4943 $mail->enqueue(
4944 ilObjUser::_lookupLogin($a_user_id),
4945 null,
4946 null,
4947 $subject,
4948 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
4949 []
4950 );
4951 }
4952
4958 public function sendAppraiseeCloseNotification($a_user_id)
4959 {
4960 $ntf = new ilSystemNotification();
4961 $ntf->setLangModules(array("svy", "survey"));
4962 $ntf->setRefId($this->getRefId());
4963 $ntf->setGotoLangId('url');
4964
4965 // user specific language
4966 $lng = $ntf->getUserLanguage($a_user_id);
4967
4968 $ntf->setIntroductionLangId("svy_user_added_360_appraisee_close_mail");
4969 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_appraisee"));
4970
4971 // #10044
4972 $mail = new ilMail(ANONYMOUS_USER_ID);
4973 $mail->enqueue(
4974 ilObjUser::_lookupLogin($a_user_id),
4975 null,
4976 null,
4977 $subject,
4978 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
4979 []
4980 );
4981 }
4982
4988 public function sendRaterNotification($a_user_id, $a_appraisee_id)
4989 {
4990 $ntf = new ilSystemNotification();
4991 $ntf->setLangModules(array("svy", "survey"));
4992 $ntf->setRefId($this->getRefId());
4993 $ntf->setGotoLangId('url');
4994
4995 // user specific language
4996 $lng = $ntf->getUserLanguage($a_user_id);
4997
4998 $ntf->setIntroductionLangId("svy_user_added_360_rater_mail");
4999 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5000 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($a_appraisee_id, false, false, "", true));
5001
5002 // #10044
5003 $mail = new ilMail(ANONYMOUS_USER_ID);
5004 $mail->enqueue(
5005 ilObjUser::_lookupLogin($a_user_id),
5006 null,
5007 null,
5008 $subject,
5009 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5010 []
5011 );
5012 }
5013
5014 public function isAppraisee($a_user_id)
5015 {
5016 $ilDB = $this->db;
5017
5018 $set = $ilDB->query("SELECT user_id" .
5019 " FROM svy_360_appr" .
5020 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5021 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5022 return (bool) $ilDB->numRows($set);
5023 }
5024
5025 public function isAppraiseeClosed($a_user_id)
5026 {
5027 $ilDB = $this->db;
5028
5029 $set = $ilDB->query("SELECT has_closed" .
5030 " FROM svy_360_appr" .
5031 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5032 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5033 $row = $ilDB->fetchAssoc($set);
5034 return $row["has_closed"];
5035 }
5036
5037 public function deleteAppraisee($a_user_id)
5038 {
5039 $ilDB = $this->db;
5040
5041 $ilDB->manipulate("DELETE FROM svy_360_appr" .
5042 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5043 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5044
5045 $set = $ilDB->query("SELECT user_id" .
5046 " FROM svy_360_rater" .
5047 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5048 " AND appr_id = " . $ilDB->quote($a_user_id, "integer"));
5049 while ($row = $ilDB->fetchAssoc($set)) {
5050 $this->deleteRater($a_user_id, $row["user_id"]);
5051 }
5052 // appraisee will not be part of raters table
5053 if ($this->get360SelfEvaluation()) {
5054 $this->deleteRater($a_user_id, $a_user_id);
5055 }
5056 }
5057
5058 public function getAppraiseesData()
5059 {
5060 $ilDB = $this->db;
5061
5062 $res = array();
5063
5064 $set = $ilDB->query("SELECT * FROM svy_360_appr" .
5065 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5066 while ($row = $ilDB->fetchAssoc($set)) {
5067 $name = ilObjUser::_lookupName($row["user_id"]);
5068 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5069 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5070 $res[$row["user_id"]] = $name;
5071
5072 $finished = 0;
5073 $raters = $this->getRatersData($row["user_id"]);
5074 foreach ($raters as $rater) {
5075 if ($rater["finished"]) {
5076 $finished++;
5077 }
5078 }
5079 $res[$row["user_id"]]["finished"] = $finished . "/" . sizeof($raters);
5080 $res[$row["user_id"]]["closed"] = $row["has_closed"];
5081 }
5082
5083 return $res;
5084 }
5085
5086 public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5087 {
5088 global $DIC;
5089
5090 $ilDB = $DIC->database();
5091 $access = $DIC->access();
5092
5093 if ($this->isAppraisee($a_appraisee_id) &&
5094 !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id)) {
5095 $fields = array(
5096 "obj_id" => array("integer", $this->getSurveyId()),
5097 "appr_id" => array("integer", $a_appraisee_id),
5098 "user_id" => array("integer", $a_user_id),
5099 "anonymous_id" => array("integer", $a_anonymous_id)
5100 );
5101 $ilDB->insert("svy_360_rater", $fields);
5102
5103 // send notification and add to desktop
5104 if ($access->checkAccessOfUser($a_user_id, "read", "", $this->getRefId())) {
5105 $this->sendRaterNotification($a_user_id, $a_appraisee_id);
5106 }
5107 }
5108 }
5109
5110 public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5111 {
5112 $ilDB = $this->db;
5113
5114 // user is rater if already appraisee and active self-evaluation
5115 if ($this->isAppraisee($a_user_id) &&
5116 $this->get360SelfEvaluation() &&
5117 (!$a_appraisee_id || $a_appraisee_id == $a_user_id)) {
5118 return true;
5119 }
5120
5121 // :TODO: should we get rid of code as well?
5122
5123 $sql = "SELECT user_id" .
5124 " FROM svy_360_rater" .
5125 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5126 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5127 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5128 if ($a_appraisee_id) {
5129 $sql .= " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer");
5130 }
5131 $set = $ilDB->query($sql);
5132 return (bool) $ilDB->numRows($set);
5133 }
5134
5135 public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5136 {
5137 $ilDB = $this->db;
5138
5139 $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5140 if ($finished_id) {
5141 $this->removeSelectedSurveyResults(array($finished_id));
5142 }
5143
5144 $ilDB->manipulate("DELETE FROM svy_360_rater" .
5145 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5146 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5147 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5148 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5149 }
5150
5151 public function getRatersData($a_appraisee_id)
5152 {
5153 $ilDB = $this->db;
5154
5155 $res = $anonymous_ids = array();
5156
5157 $set = $ilDB->query("SELECT * FROM svy_360_rater" .
5158 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5159 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer"));
5160 while ($row = $ilDB->fetchAssoc($set)) {
5161 if ($row["anonymous_id"]) {
5162 $res["a" . $row["anonymous_id"]] = array(
5163 "lastname" => "unknown code " . $row["anonymous_id"],
5164 "sent" => $row["mail_sent"],
5165 "finished" => null
5166 );
5167 $anonymous_ids[] = $row["anonymous_id"];
5168 } else {
5169 $name = ilObjUser::_lookupName($row["user_id"]);
5170 $name["name"] = $name["lastname"] . ", " . $name["firstname"];
5171 $name["user_id"] = "u" . $name["user_id"];
5172 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5173 $name["sent"] = $row["mail_sent"];
5174 $name["finished"] = (bool) $this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
5175 $res["u" . $row["user_id"]] = $name;
5176 }
5177 }
5178
5179 if (sizeof($anonymous_ids)) {
5180 $data = $this->getSurveyCodesTableData($anonymous_ids);
5181 foreach ($data as $item) {
5182 if (isset($res["a" . $item["id"]])) {
5183 $res["a" . $item["id"]] = array(
5184 "user_id" => "a" . $item["id"],
5185 "lastname" => $item["last_name"],
5186 "firstname" => $item["first_name"],
5187 "name" => $item["last_name"] . ", " . $item["first_name"],
5188 "login" => "",
5189 "email" => $item["email"],
5190 "code" => $item["code"],
5191 "href" => $item["href"],
5192 "sent" => $res["a" . $item["id"]]["sent"],
5193 "finished" => (bool) $this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
5194 );
5195 }
5196 }
5197 }
5198
5199 return $res;
5200 }
5201
5202 public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
5203 {
5204 $ilDB = $this->db;
5205
5206 $res = array();
5207
5208 $sql = "SELECT appr_id FROM svy_360_rater" .
5209 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer");
5210
5211 if ($a_user_id) {
5212 $sql .= " AND user_id = " . $ilDB->quote($a_user_id, "integer");
5213 } else {
5214 $sql .= " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer");
5215 }
5216
5217 $set = $ilDB->query($sql);
5218 while ($row = $ilDB->fetchAssoc($set)) {
5219 $res[] = $row["appr_id"];
5220 }
5221
5222 // user may evaluate himself if already appraisee
5223 if ($this->get360SelfEvaluation() &&
5224 $this->isAppraisee($a_user_id) &&
5225 !in_array($a_user_id, $res)) {
5226 $res[] = $a_user_id;
5227 }
5228
5229 return $res;
5230 }
5231
5232 public function getAnonymousIdByCode($a_code)
5233 {
5234 $ilDB = $this->db;
5235
5236 $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous" .
5237 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5238 " AND survey_key = " . $ilDB->quote($a_code, "text"));
5239 $res = $ilDB->fetchAssoc($set);
5240 return $res["anonymous_id"];
5241 }
5242
5243 public function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
5244 {
5245 $ilDB = $this->db;
5246
5247 $sql = "SELECT * FROM svy_finished" .
5248 " WHERE survey_fi =" . $ilDB->quote($this->getSurveyId(), "integer") .
5249 " AND appr_id = " . $ilDB->quote($appr_id, "integer");
5250 if ($user_id) {
5251 $sql .= " AND user_fi = " . $ilDB->quote($user_id, "integer");
5252 } else {
5253 $sql .= " AND anonymous_id = " . $ilDB->quote($anonymous_code, "text");
5254 }
5255 $result = $ilDB->query($sql);
5256 if ($result->numRows() == 0) {
5257 return false;
5258 } else {
5259 $row = $ilDB->fetchAssoc($result);
5260 return (int) $row["state"];
5261 }
5262 }
5263
5264 public function getUserSurveyExecutionStatus($a_code = null)
5265 {
5267 $ilDB = $this->db;
5268
5269 $user_id = $ilUser->getId();
5270
5271 // code is obligatory?
5272 if (!$this->isAccessibleWithoutCode()) {
5273 if (!$a_code) {
5274 // registered raters do not need code
5275 if ($this->get360Mode() &&
5276 $user_id != ANONYMOUS_USER_ID &&
5277 $this->isRater(0, $user_id)) {
5278 // auto-generate code
5279 $a_code = $this->createNewAccessCode();
5280 $this->saveUserAccessCode($user_id, $a_code);
5281 } else {
5282 return null;
5283 }
5284 }
5285 } elseif ($user_id == ANONYMOUS_USER_ID ||
5286 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS) {
5287 if (!$a_code) {
5288 // auto-generate code
5289 $a_code = $this->createNewAccessCode();
5290 $this->saveUserAccessCode($user_id, $a_code);
5291 }
5292 } else {
5293 $a_code = null;
5294 }
5295
5296 $res = array();
5297
5298 $sql = "SELECT * FROM svy_finished" .
5299 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer");
5300 // if proper user id is given, use it or current code
5301 if ($user_id != ANONYMOUS_USER_ID) {
5302 $sql .= " AND (user_fi = " . $ilDB->quote($user_id, "integer") .
5303 " OR anonymous_id = " . $ilDB->quote($a_code, "text") . ")";
5304 }
5305 // use anonymous code to find finished id(s)
5306 else {
5307 $sql .= " AND anonymous_id = " . $ilDB->quote($a_code, "text");
5308 }
5309 $set = $ilDB->query($sql);
5310 while ($row = $ilDB->fetchAssoc($set)) {
5311 $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
5312 "user_id" => $row["user_fi"],
5313 "code" => $row["anonymous_id"],
5314 "finished" => (bool) $row["state"]);
5315 }
5316
5317 return array("code" => $a_code, "runs" => $res);
5318 }
5319
5320 public function findCodeForUser($a_user_id)
5321 {
5322 $ilDB = $this->db;
5323
5324 if ($a_user_id != ANONYMOUS_USER_ID) {
5325 $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf" .
5326 " WHERE sf.survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5327 " AND sf.user_fi = " . $ilDB->quote($a_user_id, "integer"));
5328 $a_code = $ilDB->fetchAssoc($set);
5329 return $a_code["anonymous_id"];
5330 }
5331 }
5332
5333 public function isUnusedCode($a_code, $a_user_id)
5334 {
5335 $ilDB = $this->db;
5336
5337 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
5338 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5339 " AND anonymous_id = " . $ilDB->quote($a_code, "text"));
5340 $user_id = $ilDB->fetchAssoc($set);
5341 $user_id = $user_id["user_fi"];
5342
5343 if ($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID)) {
5344 return false;
5345 }
5346 return true;
5347 }
5348
5349 public function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
5350 {
5351 $ilDB = $this->db;
5352
5353 $res = array();
5354
5355 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5356 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5357 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer"));
5358 while ($row = $ilDB->fetchAssoc($set)) {
5359 if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id) {
5360 continue;
5361 }
5362 $res[] = $row["finished_id"];
5363 }
5364
5365 return $res;
5366 }
5367
5375 public function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
5376 {
5377 $ilDB = $this->db;
5378
5379 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished" .
5380 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5381 " AND appr_id = " . $ilDB->quote($a_appr_id, "integer") .
5382 " AND user_fi = " . $ilDB->quote($a_rat_id, "integer"));
5383 $row = $ilDB->fetchAssoc($set);
5384 return $row["finished_id"];
5385 }
5386
5387
5388 // 360° using competence/skill service
5389
5395 public function setSkillService($a_val)
5396 {
5397 $this->mode_skill_service = $a_val;
5398 }
5399
5405 public function getSkillService()
5406 {
5408 }
5409
5410 public function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
5411 {
5412 $ilDB = $this->db;
5413
5414 if (!$a_tstamp) {
5415 $a_tstamp = time();
5416 }
5417
5418 $ilDB->manipulate("UPDATE svy_360_rater" .
5419 " SET mail_sent = " . $ilDB->quote($a_tstamp, "integer") .
5420 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5421 " AND appr_id = " . $ilDB->quote($a_appraisee_id, "integer") .
5422 " AND user_id = " . $ilDB->quote($a_user_id, "integer") .
5423 " AND anonymous_id = " . $ilDB->quote($a_anonymous_id, "integer"));
5424 }
5425
5426 public function closeAppraisee($a_user_id)
5427 {
5428 global $DIC;
5429
5430 $ilDB = $DIC->database();
5431 $user = $DIC->user();
5432
5433 // close the appraisee
5434 $ilDB->manipulate("UPDATE svy_360_appr" .
5435 " SET has_closed = " . $ilDB->quote(time(), "integer") .
5436 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer") .
5437 " AND user_id = " . $ilDB->quote($a_user_id, "integer"));
5438
5439 // write competences
5440 $skmg_set = new ilSkillManagementSettings();
5441 if ($this->getSkillService() && $skmg_set->isActivated()) {
5442 $sskill = new ilSurveySkill($this);
5443 $sskill->writeAndAddAppraiseeSkills($a_user_id);
5444 }
5445
5446 // send notification
5447 if ($user->getId() != $a_user_id) {
5448 $this->sendAppraiseeCloseNotification($a_user_id);
5449 }
5450 }
5451
5452 public function openAllAppraisees()
5453 {
5454 $ilDB = $this->db;
5455
5456 $ilDB->manipulate("UPDATE svy_360_appr" .
5457 " SET has_closed = " . $ilDB->quote(null, "integer") .
5458 " WHERE obj_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
5459 }
5460
5461 public static function validateExternalRaterCode($a_ref_id, $a_code)
5462 {
5463 if (!isset($_SESSION["360_extrtr"][$a_ref_id])) {
5464 $svy = new self($a_ref_id);
5465 $svy->loadFromDB();
5466
5467 if ($svy->canStartSurvey(null, true) &&
5468 $svy->get360Mode() &&
5469 $svy->isAnonymousKey($a_code)) {
5470 $anonymous_id = $svy->getAnonymousIdByCode($a_code);
5471 if ($anonymous_id) {
5472 if (sizeof($svy->getAppraiseesToRate(null, $anonymous_id))) {
5473 $_SESSION["360_extrtr"][$a_ref_id] = true;
5474 return true;
5475 }
5476 }
5477 }
5478
5479 $_SESSION["360_extrtr"][$a_ref_id] = false;
5480 return false;
5481 }
5482
5483 return $_SESSION["360_extrtr"][$a_ref_id];
5484 }
5485
5486
5487 //
5488 // reminder/notification
5489 //
5490
5491 public function getReminderStatus()
5492 {
5493 return (bool) $this->reminder_status;
5494 }
5495
5496 public function setReminderStatus($a_value)
5497 {
5498 $this->reminder_status = (bool) $a_value;
5499 }
5500
5501 public function getReminderStart()
5502 {
5503 return $this->reminder_start;
5504 }
5505
5506 public function setReminderStart(ilDate $a_value = null)
5507 {
5508 $this->reminder_start = $a_value;
5509 }
5510
5511 public function getReminderEnd()
5512 {
5513 return $this->reminder_end;
5514 }
5515
5516 public function setReminderEnd(ilDate $a_value = null)
5517 {
5518 $this->reminder_end = $a_value;
5519 }
5520
5521 public function getReminderFrequency()
5522 {
5524 }
5525
5526 public function setReminderFrequency($a_value)
5527 {
5528 $this->reminder_frequency = (int) $a_value;
5529 }
5530
5531 public function getReminderTarget()
5532 {
5534 }
5535
5536 public function setReminderTarget($a_value)
5537 {
5538 $this->reminder_target = (int) $a_value;
5539 }
5540
5541 public function getReminderLastSent()
5542 {
5544 }
5545
5546 public function setReminderLastSent($a_value)
5547 {
5548 $this->reminder_last_sent = $a_value;
5549 }
5550
5555 public function getReminderTemplate($selectDefault = false)
5556 {
5557 if ($selectDefault) {
5558 $defaultTemplateId = 0;
5559 $this->getReminderMailTemplates($defaultTemplateId);
5560
5561 if ($defaultTemplateId > 0) {
5562 return $defaultTemplateId;
5563 }
5564 }
5565
5566 return $this->reminder_tmpl;
5567 }
5568
5569 public function setReminderTemplate($a_value)
5570 {
5571 $this->reminder_tmpl = $a_value;
5572 }
5573
5575 {
5576 return (bool) $this->tutor_ntf_status;
5577 }
5578
5579 public function setTutorNotificationStatus($a_value)
5580 {
5581 $this->tutor_ntf_status = (bool) $a_value;
5582 }
5583
5585 {
5587 }
5588
5589 public function setTutorNotificationRecipients(array $a_value)
5590 {
5591 $this->tutor_ntf_recipients = $a_value;
5592 }
5593
5595 {
5597 }
5598
5599 public function setTutorNotificationTarget($a_value)
5600 {
5601 $this->tutor_ntf_target = (int) $a_value;
5602 }
5603
5604 public function getTutorResultsStatus()
5605 {
5606 return (bool) $this->tutor_res_status;
5607 }
5608
5609 public function setTutorResultsStatus($a_value)
5610 {
5611 $this->tutor_res_status = (bool) $a_value;
5612 }
5613
5615 {
5617 }
5618
5619 public function setTutorResultsRecipients(array $a_value)
5620 {
5621 $this->tutor_res_recipients = $a_value;
5622 }
5623
5624 protected function checkTutorNotification()
5625 {
5626 $ilDB = $this->db;
5627
5628 if ($this->getTutorNotificationStatus()) {
5629 $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
5630 if ($user_ids) {
5631 $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished" .
5632 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5633 " AND state = " . $ilDB->quote(1, "integer") .
5634 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
5635 $row = $ilDB->fetchAssoc($set);
5636 if ($row["numall"] == sizeof($user_ids)) {
5637 $this->sendTutorNotification();
5638 }
5639 }
5640 }
5641 }
5642
5649 public function sent360Reminders()
5650 {
5651 global $DIC;
5652
5653 $access = $DIC->access();
5654
5655 // collect all open ratings
5656 $rater_ids = array();
5657 foreach ($this->getAppraiseesData() as $app) {
5658 $this->log->debug("Handle appraisee " . $app['user_id']);
5659
5660 if (!$this->isAppraiseeClosed($app['user_id'])) {
5661 $this->log->debug("Check self evaluation, self: " . $this->get360SelfAppraisee() . ", target: " . $this->getReminderTarget());
5662
5663 // self evaluation?
5664 if ($this->get360SelfEvaluation() &&
5666 $this->log->debug("...1");
5667 // did user already finished self evaluation?
5668 if (!$this->is360SurveyStarted($app['user_id'], $app['user_id'])) {
5669 $this->log->debug("...2");
5670 if (!is_array($rater_ids[$app['user_id']])) {
5671 $rater_ids[$app['user_id']] = array();
5672 }
5673 if (!in_array($app["user_id"], $rater_ids[$app['user_id']])) {
5674 $rater_ids[$app['user_id']][] = $app["user_id"];
5675 }
5676 }
5677 }
5678
5679 $this->log->debug("Check raters.");
5680
5681 // should raters be notified?
5683 foreach ($this->getRatersData($app['user_id']) as $rater) {
5684 // is rater not anonymous and did not rate yet?
5685 if (!$rater["anonymous_id"] && !$rater["finished"]) {
5686 if (!is_array($rater_ids[$rater["user_id"]])) {
5687 $rater_ids[$rater["user_id"]] = array();
5688 }
5689 if (!in_array($app["user_id"], $rater_ids[$rater["user_id"]])) {
5690 $rater_ids[$rater["user_id"]][] = $app["user_id"];
5691 }
5692 }
5693 }
5694 }
5695 }
5696 }
5697
5698 $this->log->debug("Found raters:" . count($rater_ids));
5699
5700 foreach ($rater_ids as $id => $app) {
5701 if ($access->checkAccessOfUser($id, "read", "", $this->getRefId())) {
5702 $this->send360ReminderToUser($id, $app);
5703 }
5704 }
5705 }
5706
5712 public function send360ReminderToUser($a_user_id, $a_appraisee_ids)
5713 {
5714 $this->log->debug("Send mail to:" . $a_user_id);
5715
5716 $ntf = new ilSystemNotification();
5717 $ntf->setLangModules(array("svy", "survey"));
5718 $ntf->setRefId($this->getRefId());
5719 $ntf->setGotoLangId('url');
5720
5721 // user specific language
5722 $lng = $ntf->getUserLanguage($a_user_id);
5723
5724 $ntf->setIntroductionLangId("svy_user_added_360_rater_reminder_mail");
5725 $subject = str_replace("%1", $this->getTitle(), $lng->txt("svy_user_added_360_rater"));
5726
5727 foreach ($a_appraisee_ids as $appraisee_id) {
5728 $ntf->addAdditionalInfo("survey_360_appraisee", ilUserUtil::getNamePresentation($appraisee_id, false, false, "", true));
5729 }
5730
5731 // #10044
5732 $mail = new ilMail(ANONYMOUS_USER_ID);
5733 $mail->enqueue(
5734 ilObjUser::_lookupLogin($a_user_id),
5735 null,
5736 null,
5737 $subject,
5738 $ntf->composeAndGetMessage($a_user_id, null, "read", true),
5739 []
5740 );
5741 }
5742
5743
5744 public function getNotificationTargetUserIds($a_use_invited)
5745 {
5747
5748 if ((bool) $a_use_invited) {
5749 $user_ids = $this->invitation_manager->getAllForSurvey($this->getSurveyId());
5750 } else {
5751 $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
5752 if ($parent_grp_ref_id) {
5753 $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
5754 $user_ids = $part->getMembers();
5755 } else {
5756 $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
5757 if ($parent_crs_ref_id) {
5758 $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
5759 $user_ids = $part->getMembers();
5760 }
5761 }
5762 }
5763 return $user_ids;
5764 }
5765
5766 protected function sendTutorNotification()
5767 {
5768 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
5769
5770 foreach ($this->getTutorNotificationRecipients() as $user_id) {
5771 // use language of recipient to compose message
5772 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
5773 $ulng->loadLanguageModule('survey');
5774
5775 $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
5776 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
5777
5778 $message .= $ulng->txt('survey_notification_tutor_body') . ":\n\n";
5779 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
5780 $message .= "\n" . $ulng->txt('survey_notification_tutor_link') . ": " . $link;
5781
5782 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
5783 $mail_obj->appendInstallationSignature(true);
5784 $mail_obj->enqueue(
5785 ilObjUser::_lookupLogin($user_id),
5786 "",
5787 "",
5788 $subject,
5789 $message,
5790 array()
5791 );
5792 }
5793 }
5794
5795 public function checkReminder()
5796 {
5797 $ilDB = $this->db;
5798 $ilAccess = $this->access;
5799
5800 $now = time();
5801 $now_with_format = date("YmdHis", $now);
5802 $today = date("Y-m-d");
5803
5804 $this->log->debug("Check status and dates.");
5805
5806 // object settings / participation period
5807 if (
5808 $this->getOfflineStatus() ||
5809 !$this->getReminderStatus() ||
5810 ($this->getStartDate() && $now_with_format < $this->getStartDate()) ||
5811 ($this->getEndDate() && $now_with_format > $this->getEndDate())) {
5812 return false;
5813 }
5814
5815 // reminder period
5816 $start = $this->getReminderStart();
5817 if ($start) {
5818 $start = $start->get(IL_CAL_DATE);
5819 }
5820 $end = $this->getReminderEnd();
5821 if ($end) {
5822 $end = $end->get(IL_CAL_DATE);
5823 }
5824 if ($today < $start ||
5825 ($end && $today > $end)) {
5826 return false;
5827 }
5828
5829 $this->log->debug("Check access period.");
5830
5831 // object access period
5832 $item_data = ilObjectActivation::getItem($this->getRefId());
5833 if ($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
5834 ($now < $item_data["timing_start"] ||
5835 $now > $item_data["timing_end"])) {
5836 return false;
5837 }
5838
5839 $this->log->debug("Check frequency.");
5840
5841 // check frequency
5842 $cut = new ilDate($today, IL_CAL_DATE);
5843 $cut->increment(IL_CAL_DAY, $this->getReminderFrequency() * -1);
5844 if (!$this->getReminderLastSent() ||
5845 $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10)) {
5846 $missing_ids = array();
5847
5848 if (!$this->get360Mode()) {
5849 $this->log->debug("Entering survey mode.");
5850
5851 // #16871
5852 $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
5853 if ($user_ids) {
5854 // gather participants who already finished
5855 $finished_ids = array();
5856 $set = $ilDB->query("SELECT user_fi FROM svy_finished" .
5857 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer") .
5858 " AND state = " . $ilDB->quote(1, "text") .
5859 " AND " . $ilDB->in("user_fi", $user_ids, "", "integer"));
5860 while ($row = $ilDB->fetchAssoc($set)) {
5861 $finished_ids[] = $row["user_fi"];
5862 }
5863
5864 // some users missing out?
5865 $missing_ids = array_diff($user_ids, $finished_ids);
5866 if ($missing_ids) {
5867 foreach ($missing_ids as $idx => $user_id) {
5868 // should be able to participate
5869 if (!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId())) {
5870 unset($missing_ids[$idx]);
5871 }
5872 }
5873 }
5874 if ($missing_ids) {
5875 $this->sentReminder($missing_ids);
5876 }
5877 }
5878 } else {
5879 $this->log->debug("Entering 360 mode.");
5880
5881 $this->sent360Reminders();
5882 }
5883
5884
5885 $this->setReminderLastSent($today);
5886 $this->saveToDb();
5887
5888 return sizeof($missing_ids);
5889 }
5890
5891 return false;
5892 }
5893
5894 protected function sentReminder(array $a_recipient_ids)
5895 {
5896 global $DIC;
5897
5898 // use mail template
5899 if ($this->getReminderTemplate() &&
5900 array_key_exists($this->getReminderTemplate(), $this->getReminderMailTemplates())) {
5902 $templateService = $DIC['mail.texttemplates.service'];
5903 $tmpl = $templateService->loadTemplateForId((int) $this->getReminderTemplate());
5904
5905 $tmpl_params = array(
5906 "ref_id" => $this->getRefId(),
5907 "ts" => time()
5908 );
5909 } else {
5910 $tmpl = null;
5911 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
5912 }
5913
5914 foreach ($a_recipient_ids as $user_id) {
5915 if ($tmpl) {
5916 $subject = $tmpl->getSubject();
5917 $message = $this->sentReminderPlaceholders($tmpl->getMessage(), $user_id, $tmpl_params);
5918 }
5919 // use lng
5920 else {
5921 // use language of recipient to compose message
5922 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
5923 $ulng->loadLanguageModule('survey');
5924
5925 $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
5926 $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
5927
5928 $message .= $ulng->txt('survey_reminder_body') . ":\n\n";
5929 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
5930 $message .= "\n" . $ulng->txt('survey_reminder_link') . ": " . $link;
5931 }
5932
5933 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
5934 $mail_obj->appendInstallationSignature(true);
5935 $mail_obj->enqueue(
5936 ilObjUser::_lookupLogin($user_id),
5937 "",
5938 "",
5939 $subject,
5940 $message,
5941 array()
5942 );
5943 }
5944 }
5945
5946 public function setActivationStartDate($starting_time = null)
5947 {
5948 $this->activation_starting_time = $starting_time;
5949 }
5950
5951 public function setActivationEndDate($ending_time = null)
5952 {
5953 $this->activation_ending_time = $ending_time;
5954 }
5955
5956 public function getActivationStartDate()
5957 {
5958 return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : null;
5959 }
5960
5961 public function getActivationEndDate()
5962 {
5963 return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : null;
5964 }
5965
5966 public function setViewOwnResults($a_value)
5967 {
5968 $this->view_own_results = (bool) $a_value;
5969 }
5970
5971 public function hasViewOwnResults()
5972 {
5974 }
5975
5976 public function setMailOwnResults($a_value)
5977 {
5978 $this->mail_own_results = (bool) $a_value;
5979 }
5980
5981 public function hasMailOwnResults()
5982 {
5984 }
5985
5986 public function setMailConfirmation($a_value)
5987 {
5988 $this->mail_confirmation = (bool) $a_value;
5989 }
5990
5991 public function hasMailConfirmation()
5992 {
5994 }
5995
5996 public function setAnonymousUserList($a_value)
5997 {
5998 $this->anon_user_list = (bool) $a_value;
5999 }
6000
6001 public function hasAnonymousUserList()
6002 {
6003 return $this->anon_user_list;
6004 }
6005
6006 public static function getSurveySkippedValue()
6007 {
6008 global $DIC;
6009
6010 $lng = $DIC->language();
6011
6012 // #13541
6013
6014 $surveySetting = new ilSetting("survey");
6015 if (!$surveySetting->get("skipped_is_custom", false)) {
6016 return $lng->txt("skipped");
6017 } else {
6018 return $surveySetting->get("skipped_custom_value", "");
6019 }
6020 }
6021
6026 public function getReminderMailTemplates(&$defaultTemplateId = null)
6027 {
6028 global $DIC;
6029
6030 $res = array();
6031
6033 $templateService = $DIC['mail.texttemplates.service'];
6034 foreach ($templateService->loadTemplatesForContextId((string) ilSurveyMailTemplateReminderContext::ID) as $tmpl) {
6035 $res[$tmpl->getTplId()] = $tmpl->getTitle();
6036 if (null !== $defaultTemplateId && $tmpl->isDefault()) {
6037 $defaultTemplateId = $tmpl->getTplId();
6038 }
6039 }
6040
6041 return $res;
6042 }
6043
6044 protected function sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
6045 {
6046 // see ilMail::replacePlaceholders()
6047 try {
6049
6050 $user = new \ilObjUser($a_user_id);
6051
6052 $processor = new \ilMailTemplatePlaceholderResolver($context, $a_message);
6053 $a_message = $processor->resolve($user, $a_context_params);
6054 } catch (\Exception $e) {
6055 ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
6056 }
6057
6058 return $a_message;
6059 }
6060
6061 public function setMode($a_value)
6062 {
6063 $this->mode = $a_value;
6064 }
6065
6066 public function getMode()
6067 {
6068 return $this->mode;
6069 }
6070
6071 public function setSelfEvaluationResults($a_value)
6072 {
6073 $this->mode_self_eval_results = $a_value;
6074 }
6075
6077 {
6079 }
6080
6081 public static function getSurveysWithTutorResults()
6082 {
6083 global $ilDB;
6084
6085 $res = array();
6086
6088
6089
6090 $q = "SELECT obj_fi FROM svy_svy" .
6091 " WHERE tutor_res_cron IS NULL" .
6092 " AND tutor_res_status = " . $ilDB->quote(1, "integer") .
6093 " AND enddate < " . $ilDB->quote(date("Ymd000000"), "text");
6094
6095 if (DEVMODE) {
6096 $q = "SELECT obj_fi FROM svy_svy" .
6097 " WHERE tutor_res_status = " . $ilDB->quote(1, "integer") .
6098 " AND enddate < " . $ilDB->quote(date("Ymd000000"), "text");
6099 }
6100
6101 $set = $ilDB->query($q);
6102
6103 $log->debug($q);
6104
6105 while ($row = $ilDB->fetchAssoc($set)) {
6106 $res[] = $row["obj_fi"];
6107 }
6108
6109 return $res;
6110 }
6111
6112 public function sendTutorResults()
6113 {
6114 global $ilCtrl, $ilDB;
6115
6117
6118 include_once "./Services/Mail/classes/class.ilMail.php";
6119 include_once "./Services/User/classes/class.ilObjUser.php";
6120 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6121 include_once "./Services/User/classes/class.ilUserUtil.php";
6122
6123 include_once "./Services/Link/classes/class.ilLink.php";
6124 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6125
6126 // somehow needed in cron-calls
6127 //$ilCtrl->setTargetScript("ilias.php");
6128 //$ilCtrl->initBaseClass("ilobjsurveygui");
6129
6130 // yeah, I know...
6131 $old_ref_id = $_GET["ref_id"];
6132 $old_base_class = $_GET["baseClass"];
6133 $_GET["ref_id"] = $this->getRefId();
6134 $ilCtrl->setTargetScript("ilias.php");
6135 $_GET["baseClass"] = "ilObjSurveyGUI";
6136
6137 $ilCtrl->setParameterByClass("ilSurveyEvaluationGUI", "ref_id", $this->getRefId());
6138
6139 try {
6140 $gui = new ilSurveyEvaluationGUI($this);
6141 $html = $gui->evaluation(1, true, true);
6142 } catch (Exception $exception) {
6143 $_GET["ref_id"] = $old_ref_id;
6144 $_GET["baseClass"] = $old_base_class;
6145 throw $exception;
6146 }
6147 $_GET["ref_id"] = $old_ref_id;
6148 $_GET["baseClass"] = $old_base_class;
6149
6150 $html = preg_replace("/\?dummy\=[0-9]+/", "", $html);
6151 $html = preg_replace("/\?vers\=[0-9A-Za-z\-]+/", "", $html);
6152 $html = str_replace('.css$Id$', ".css", $html);
6153 $html = preg_replace("/src=\"\\.\\//ims", "src=\"" . ILIAS_HTTP_PATH . "/", $html);
6154 $html = preg_replace("/href=\"\\.\\//ims", "href=\"" . ILIAS_HTTP_PATH . "/", $html);
6155
6156 $log->debug("--pdf start, ref id " . $this->getRefId());
6157 $log->debug("html length: " . strlen($html));
6158 $log->debug("html (first 1000 chars): " . substr($html, 0, 1000));
6159 //echo $html; exit;
6160 $pdf_factory = new ilHtmlToPdfTransformerFactory();
6161 $pdf = $pdf_factory->deliverPDFFromHTMLString($html, "survey.pdf", ilHtmlToPdfTransformerFactory::PDF_OUTPUT_FILE, "Survey", "Results");
6162 $log->debug("--pdf end");
6163
6164 /*
6165 $log->debug("calling phantom for ref_id: " . $this->getRefId());
6166
6167 $pdf = $gui->callPdfGeneration($url, "pdf", true, true);
6168
6169 $log->debug("phantom called : " . $pdf);*/
6170
6171 if (!$pdf ||
6172 !file_exists($pdf)) {
6173 return false;
6174 }
6175
6176 // prepare mail attachment
6177 require_once 'Services/Mail/classes/class.ilFileDataMail.php';
6178 $att = "survey_" . $this->getRefId() . ".pdf";
6179 $mail_data = new ilFileDataMail(ANONYMOUS_USER_ID);
6180 $mail_data->copyAttachmentFile($pdf, $att);
6181
6182 foreach ($this->getTutorResultsRecipients() as $user_id) {
6183 // use language of recipient to compose message
6184 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6185 $ulng->loadLanguageModule('survey');
6186
6187 $subject = sprintf($ulng->txt('survey_results_tutor_subject'), $this->getTitle());
6188 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id)) . "\n\n";
6189
6190 $message .= $ulng->txt('survey_results_tutor_body') . ":\n\n";
6191 $message .= $ulng->txt('obj_svy') . ": " . $this->getTitle() . "\n";
6192 $message .= "\n" . $ulng->txt('survey_notification_tutor_link') . ": " . $link;
6193
6194 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6195 $mail_obj->appendInstallationSignature(true);
6196 $log->debug("send mail to user id: " . $user_id . ",login: " . ilObjUser::_lookupLogin($user_id));
6197 $mail_obj->enqueue(
6198 ilObjUser::_lookupLogin($user_id),
6199 "",
6200 "",
6201 $subject,
6202 $message,
6203 array($att)
6204 );
6205 }
6206
6207 $ilDB->manipulate("UPDATE svy_svy" .
6208 " SET tutor_res_cron = " . $ilDB->quote(1, "integer") .
6209 " WHERE survey_id = " . $ilDB->quote($this->getSurveyId(), "integer"));
6210
6211 return true;
6212 }
6213} // 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
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.
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.
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.
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.
getAnonymize()
get anonymize status
setActivationStartDate($starting_time=null)
addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag=true, $add_mobs=true, $attribs=null)
Creates an XML material tag from a plain text or xhtml text.
getConstraints($question_id)
Returns the constraints to a given question or questionblock.
addQuestion($question_id)
Adds a question to the survey (used in importer!)
prepareTextareaOutput($txt_output)
Prepares a string for a text area output in surveys.
update($a_upload=false)
update object data
getQuestionType($question_id)
Returns the question type of a question with a given id.
setIntroduction($introduction="")
Sets the introduction text.
showQuestionTitles()
Sets the question titles visible during the query.
setMailOwnResults($a_value)
deleteWorkingData($question_id, $active_id)
Deletes the working data of a question in the database.
setActivationLimited($a_value)
createImportDirectory()
creates data directory for import files (data_dir/svy_data/svy_<id>/import, depending on data directo...
setStartDateAndTime($start_date="", $start_time)
Sets the start date of the survey.
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.
createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
Creates a question block for the survey.
static _hasDatasets($survey_id)
getAnonymousIdByCode($a_code)
getLastAccess($finished_id)
getAppraiseesToRate($a_user_id, $a_anonymous_id=null)
const NOTIFICATION_APPRAISEES_AND_RATERS
& getSurveyPages()
Returns the survey pages in an array (a page contains one or more questions)
saveToDb()
Saves a survey object to a database.
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.
modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
Modifies a question block.
updateOrder(array $a_order)
createNewAccessCode()
Returns a new, unused survey access code.
read()
read object data from db into object @access public
loadFromDb()
Loads a survey object from a database.
static _getQuestionblock($questionblock_id)
Returns the database row for a given question block.
setStartTime($finished_id, $first_question)
getQuestionsTable($arrFilter)
Calculates the data for the output of the question browser.
saveUserSettings($usr_id, $key, $title, $value)
unfoldQuestionblocks($questionblocks)
Unfolds question blocks of a question pool.
deliverPDFfromFO($fo)
Delivers a PDF file from a XSL-FO string.
is360SurveyStarted($appr_id, $user_id, $anonymous_code=null)
removeSelectedSurveyResults($finished_ids)
Deletes the user data of a given array of survey participants.
setViewOwnResults($a_value)
& getSurveyQuestions($with_answers=false)
Returns the survey questions and questionblocks in an array.
getSurveyId()
Returns the survey database id.
isSurveyFinishedByCode($a_code)
Get if survey is finished for an specific anonymous user code.
setStartDate($start_date="")
Sets the start date of the survey.
removeQuestionFromBlock($question_id, $questionblock_id)
getUserSpecificResults($finished_ids)
Calculates the evaluation data for the user specific results.
sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
setEvaluationAccess($evaluation_access=self::EVALUATION_ACCESS_OFF)
Sets the learners evaluation access.
getEndDate()
Gets the end date of the survey.
sendRaterNotification($a_user_id, $a_appraisee_id)
Send rater notification.
set360SelfEvaluation($a_value)
setPoolUsage($a_value)
setTutorNotificationRecipients(array $a_value)
send360ReminderToUser($a_user_id, $a_appraisee_ids)
Send rater notification.
isComplete()
Returns 1, if a survey is complete for use.
getSurveyCodesForExport(array $a_codes=null, array $a_ids=null)
Returns a list of survey codes for file export.
getUserDataFromActiveId($active_id, $force_non_anonymous=false)
Returns the user information from an active_id (survey_finished.finished_id)
setReminderTarget($a_value)
set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp=null)
saveCompletionStatus()
Saves the completion status of the survey.
static getSurveySkippedValue()
getAllRelations($short_as_key=false)
Returns all available relations.
getNextPage($active_page_question_id, $direction)
Returns the next "page" of a running test.
const EVALUATION_ACCESS_OFF
& getUserData($ids)
Returns a data of all users specified by id list.
createReference()
creates reference for object
static validateExternalRaterCode($a_ref_id, $a_code)
removeQuestion($question_id)
Remove a question from the survey.
bindSurveyCodeToUser($user_id, $code)
& getEvaluationByUser($questions, $active_id)
Calculates the evaluation data for a given user or anonymous id.
getStartDate()
Gets the start date of the survey.
static _addQuestionblock($title="", $owner=0, $show_questiontext=true, $show_blocktitle=false)
Adds a questionblock to the database.
& getVariables($question_id)
Returns all variables of a question.
getImportDirectory()
get import directory of survey
deleteSurveyRecord()
Deletes the survey from the database.
getSurveyCodesTableData(array $ids=null, $lang=null)
Fetches the data for the survey codes table.
getNotificationTargetUserIds($a_use_invited)
const RESULTS_SELF_EVAL_OWN
setReminderStatus($a_value)
startSurvey($user_id, $anonymous_id, $appraisee_id)
Starts the survey creating an entry in the database.
sent360Reminders()
Send 360 reminders.
& getQuestionblockQuestions($questionblock_id)
Returns the question titles of all questions of a question block.
saveUserAccessCode($user_id, $access_code)
Saves a survey access code for a registered user to the database.
const NOTIFICATION_APPRAISEES
removeQuestions($remove_questions, $remove_questionblocks)
Remove questions from the survey.
fixSequenceStructure()
Remove duplicate sequence entries, see #22018.
const ANONYMIZE_CODE_ALL
& getSurveyFinishedIds()
Get the finished id's of all survey participants.
set360SelfAppraisee($a_value)
getLastActivePage($active_id)
Returns the question id of the last active page a user visited in a survey.
getIntroduction()
Gets the introduction text.
setReminderEnd(ilDate $a_value=null)
setEndDateAndTime($end_date="", $end_time)
Sets the end date of the survey.
setEndDate($end_date="")
Sets the end date of the survey.
sendAppraiseeNotification($a_user_id)
Send appraisee notification.
setTemplate($template_id)
setReminderFrequency($a_value)
createSurveyCodes($nrOfCodes)
getAuthor()
Gets the authors name of the ilObjSurvey object.
& getExistingQuestions()
Gets the question id's of the questions which are already in the survey.
& getQuestionblockQuestionIds($questionblock_id)
Returns the question id's of all questions of a question block.
getShowQuestionTitles()
Gets the status of the display_question_titles attribute.
setAnonymize($a_anonymize)
set anonymize status
isSurveyStarted($user_id, $anonymize_id, $appr_id=0)
Checks if a user already started a survey.
addConstraint($if_question_id, $relation, $value, $conjunction)
Adds a constraint.
& getQuestionpoolTitles($could_be_offline=false, $showPath=false)
Get the titles of all available survey question pools.
set360SelfRaters($a_value)
getAnonymousId($id)
Checks for an anomyous survey id in the database an returns the id.
setEndTime($finished_id)
loadWorkingData($question_id, $active_id)
Gets the working data of question from the database.
isAppraiseeClosed($a_user_id)
addConstraintToQuestion($to_question_id, $constraint_id)
Adds a constraint to a question.
createExportDirectory()
creates data directory for export files (data_dir/svy_data/svy_<id>/export, depending on data directo...
setPage($finished_id, $page_id)
Sets the number of the active survey page.
saveAuthorToMetadata($a_author="")
Saves an authors name into the lifecycle metadata if no lifecycle metadata exists This will only be c...
canExportSurveyCode()
Checks if the survey code can be exported with the survey evaluation.
importObject($file_info, $svy_qpl_id)
Imports a survey from XML into the ILIAS database.
isPluginActive($a_pname)
Checks whether or not a question plugin with a given name is active.
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/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 is_email($a_email, ilMailRfc822AddressParserFactory $mailAddressParserFactory=null)
This preg-based function checks whether an e-mail address is formally valid.
static ilTempnam($a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
XML writer class.
xmlHeader()
Writes xml header @access public.
$app
Definition: cli.php:38
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
global $ilCtrl
Definition: ilias.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
$mobs
$ilUser
Definition: imgupload.php:18
$context
Definition: webdav.php:26
$messages
Definition: xapiexit.php:5
$lang
Definition: xapiexit.php:8
$message
Definition: xapiexit.php:14
$DIC
Definition: xapitoken.php:46
$rows
Definition: xhr_table.php:10