ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilObjSurvey.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "./Services/Object/classes/class.ilObject.php";
5
15class ilObjSurvey extends ilObject
16{
17 const STATUS_OFFLINE = 0;
18 const STATUS_ONLINE = 1;
19
23
24 const INVITATION_OFF = 0;
25 const INVITATION_ON = 1;
26
27 const MODE_UNLIMITED = 0;
29
30 const ANONYMIZE_OFF = 0; // personalized, no codes
31 const ANONYMIZE_ON = 1; // anonymized, codes
32 const ANONYMIZE_FREEACCESS = 2; // anonymized, no codes
33 const ANONYMIZE_CODE_ALL = 3; // personalized, codes
34
37
45
53
60
66 var $outro;
67
74
81
88
95
102
109
116
122
128
135
141
145 protected $log;
146
150
151 // 360°
152 protected $mode_360; // [bool]
153 protected $mode_360_self_eval; // [bool]
154 protected $mode_360_self_appr; // [bool]
155 protected $mode_360_self_rate; // [bool]
156 protected $mode_360_results; // [int]
157 protected $mode_360_skill_service; // [bool]
158
162
163 // reminder/notification
164 protected $reminder_status; // [bool]
165 protected $reminder_start; // [ilDate]
166 protected $reminder_end; // [ilDate]
167 protected $reminder_frequency; // [int]
168 protected $reminder_target; // [int]
169 protected $reminder_last_sent; // [bool]
170 protected $reminder_tmpl; // [int]
171 protected $tutor_ntf_status; // [bool]
172 protected $tutor_ntf_recipients; // [array]
173 protected $tutor_ntf_target; // [int]
174
175 protected $view_own_results; // [bool]
176 protected $mail_own_results; // [bool]
177 protected $mail_confirmation; // [bool]
178
179 protected $anon_user_list; // [bool]
180
183
184
191 function __construct($a_id = 0,$a_call_by_reference = true)
192 {
193 global $ilUser, $lng;
194
195 $this->type = "svy";
196 $this->survey_id = -1;
197 $this->introduction = "";
198 $this->outro = $lng->txt("survey_finished");
199 $this->author = $ilUser->getFullname();
200 $this->status = self::STATUS_OFFLINE;
201 $this->evaluation_access = self::EVALUATION_ACCESS_OFF;
202 $this->questions = array();
203 $this->invitation = self::INVITATION_OFF;
204 $this->invitation_mode = self::MODE_PREDEFINED_USERS;
205 $this->anonymize = self::ANONYMIZE_OFF;
206 $this->display_question_titles = self::QUESTIONTITLES_VISIBLE;
207 $this->surveyCodeSecurity = TRUE;
208 $this->template_id = NULL;
209 $this->pool_usage = true;
210 $this->log = ilLoggerFactory::getLogger("svy");
211
212 parent::__construct($a_id,$a_call_by_reference);
213 }
214
218 function create($a_upload = false)
219 {
220 parent::create();
221 if(!$a_upload)
222 {
223 $this->createMetaData();
224 }
225 }
226
232 function createMetaData()
233 {
234 parent::createMetaData();
235 $this->saveAuthorToMetadata();
236 }
237
244 function update()
245 {
246 $this->updateMetaData();
247
248 if (!parent::update())
249 {
250 return false;
251 }
252
253 // put here object specific stuff
254
255 return true;
256 }
257
258 function createReference()
259 {
260 $result = parent::createReference();
261 $this->saveToDb();
262 return $result;
263 }
264
269 public function read()
270 {
271 parent::read();
272 $this->loadFromDb();
273 }
274
281 function addQuestion($question_id)
282 {
283 array_push($this->questions, $question_id);
284 }
285
292 function delete()
293 {
294 if ($this->countReferences() == 1)
295 {
296 $this->deleteMetaData();
297
298 // Delete all survey questions, constraints and materials
299 foreach ($this->questions as $question_id)
300 {
301 $this->removeQuestion($question_id);
302 }
303 $this->deleteSurveyRecord();
304
306 }
307
308 $remove = parent::delete();
309
310 // always call parent delete function first!!
311 if (!$remove)
312 {
313 return false;
314 }
315 return true;
316 }
317
324 {
325 global $ilDB;
326
327 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_svy WHERE survey_id = %s",
328 array('integer'),
329 array($this->getSurveyId())
330 );
331
332 $result = $ilDB->queryF("SELECT questionblock_fi FROM svy_qblk_qst WHERE survey_fi = %s",
333 array('integer'),
334 array($this->getSurveyId())
335 );
336 $questionblocks = array();
337 while ($row = $ilDB->fetchAssoc($result))
338 {
339 array_push($questionblocks, $row["questionblock_fi"]);
340 }
341 if (count($questionblocks))
342 {
343 $affectedRows = $ilDB->manipulate("DELETE FROM svy_qblk WHERE " . $ilDB->in('questionblock_id', $questionblocks, false, 'integer'));
344 }
345 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE survey_fi = %s",
346 array('integer'),
347 array($this->getSurveyId())
348 );
349 $this->deleteAllUserData();
350
351 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_anonymous WHERE survey_fi = %s",
352 array('integer'),
353 array($this->getSurveyId())
354 );
355
356 // delete export files
357 $svy_data_dir = ilUtil::getDataDir()."/svy_data";
358 $directory = $svy_data_dir."/svy_".$this->getId();
359 if (is_dir($directory))
360 {
361 ilUtil::delDir($directory);
362 }
363
364 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
365 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
366 // remaining usages are not in text anymore -> delete them
367 // and media objects (note: delete method of ilObjMediaObject
368 // checks whether object is used in another context; if yes,
369 // the object is not deleted!)
370 foreach($mobs as $mob)
371 {
372 ilObjMediaObject::_removeUsage($mob, "svy:html", $this->getId());
373 $mob_obj = new ilObjMediaObject($mob);
374 $mob_obj->delete();
375 }
376 }
377
384 {
385 global $ilDB;
386
387 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
388 array('integer'),
389 array($this->getSurveyId())
390 );
391 $active_array = array();
392 while ($row = $ilDB->fetchAssoc($result))
393 {
394 array_push($active_array, $row["finished_id"]);
395 }
396
397 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_finished WHERE survey_fi = %s",
398 array('integer'),
399 array($this->getSurveyId())
400 );
401
402 foreach ($active_array as $active_fi)
403 {
404 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE active_fi = %s",
405 array('integer'),
406 array($active_fi)
407 );
408 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_times WHERE finished_fi = %s",
409 array('integer'),
410 array($active_fi)
411 );
412 }
413
414 include_once "Services/Object/classes/class.ilObjectLP.php";
415 $lp_obj = ilObjectLP::getInstance($this->getId());
416 $lp_obj->resetLPDataForCompleteObject();
417 }
418
424 function removeSelectedSurveyResults($finished_ids)
425 {
426 global $ilDB;
427
428 $user_ids[] = array();
429
430 foreach ($finished_ids as $finished_id)
431 {
432 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE finished_id = %s",
433 array('integer'),
434 array($finished_id)
435 );
436 $row = $ilDB->fetchAssoc($result);
437
438 if($row["user_fi"])
439 {
440 $user_ids[] = $row["user_fi"];
441 }
442
443 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE active_fi = %s",
444 array('integer'),
445 array($row["finished_id"])
446 );
447
448 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_finished WHERE finished_id = %s",
449 array('integer'),
450 array($finished_id)
451 );
452
453 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_times WHERE finished_fi = %s",
454 array('integer'),
455 array($row["finished_id"])
456 );
457 }
458
459 if(sizeof($user_ids))
460 {
461 include_once "Services/Object/classes/class.ilObjectLP.php";
462 $lp_obj = ilObjectLP::getInstance($this->getId());
463 $lp_obj->resetLPDataForUserIds($user_ids);
464 }
465 }
466
467 function &getSurveyParticipants($finished_ids = null, $force_non_anonymous = false)
468 {
469 global $ilDB;
470
471 $sql = "SELECT * FROM svy_finished".
472 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
473 if($finished_ids)
474 {
475 $sql .= " AND ".$ilDB->in("finished_id", $finished_ids, "", "integer");
476 }
477
478 $result = $ilDB->query($sql);
479 $participants = array();
480 if ($result->numRows() > 0)
481 {
482 while ($row = $ilDB->fetchAssoc($result))
483 {
484 $userdata = $this->getUserDataFromActiveId($row["finished_id"], $force_non_anonymous);
485 $userdata["finished"] = (bool)$row["state"];
486 $userdata["finished_tstamp"] = $row["tstamp"];
487 $participants[$userdata["sortname"] . $userdata["active_id"]] = $userdata;
488 }
489 }
490 return $participants;
491 }
492
499 function isComplete()
500 {
501 if (($this->getTitle()) and (count($this->questions)))
502 {
503 return 1;
504 }
505 else
506 {
507 return 0;
508 }
509 }
510
517 {
518 global $ilDB;
519
520 $complete = 0;
521 if ($this->isComplete())
522 {
523 $complete = 1;
524 }
525 if ($this->getSurveyId() > 0)
526 {
527 $affectedRows = $ilDB->manipulateF("UPDATE svy_svy SET complete = %s, tstamp = %s WHERE survey_id = %s",
528 array('text','integer','integer'),
529 array($this->isComplete(), time(), $this->getSurveyId())
530 );
531 }
532 }
533
541 function duplicateQuestionForSurvey($question_id, $a_force = false)
542 {
543 global $ilUser;
544
545 $questiontype = $this->getQuestionType($question_id);
546 $question_gui = $this->getQuestionGUI($questiontype, $question_id);
547
548 // check if question is a pool question at all, if not do nothing
549 if($this->getId() == $question_gui->object->getObjId() && !$a_force)
550 {
551 return $question_id;
552 }
553
554 $duplicate_id = $question_gui->object->duplicate(true, "", "", "", $this->getId());
555 return $duplicate_id;
556 }
557
563 function insertQuestion($question_id)
564 {
565 global $ilDB;
566
567 $this->log->debug("insert question, id:".$question_id);
568
569 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
570 if (!SurveyQuestion::_isComplete($question_id))
571 {
572 $this->log->debug("question is not complete");
573 return FALSE;
574 }
575 else
576 {
577 // get maximum sequence index in test
578 // @todo: refactor this
579 $result = $ilDB->queryF("SELECT survey_question_id FROM svy_svy_qst WHERE survey_fi = %s",
580 array('integer'),
581 array($this->getSurveyId())
582 );
583 $sequence = $result->numRows();
584 $duplicate_id = $this->duplicateQuestionForSurvey($question_id);
585 $this->log->debug("duplicate, id: ".$question_id.", duplicate id: ".$duplicate_id);
586
587 // check if question is not already in the survey, see #22018
588 if ($this->isQuestionInSurvey($duplicate_id))
589 {
590 return false;
591 }
592
593 $next_id = $ilDB->nextId('svy_svy_qst');
594 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_svy_qst (survey_question_id, survey_fi, question_fi, sequence, tstamp) VALUES (%s, %s, %s, %s, %s)",
595 array('integer', 'integer', 'integer', 'integer', 'integer'),
596 array($next_id, $this->getSurveyId(), $duplicate_id, $sequence, time())
597 );
598
599 $this->log->debug("added entry to svy_svy_qst, id: ".$next_id.", question id: ".$duplicate_id.", sequence: ".$sequence);
600
601 $this->loadQuestionsFromDb();
602 return TRUE;
603 }
604 }
605
612 function isQuestionInSurvey($a_question_fi)
613 {
614 global $DIC;
615//return false;
616 $ilDB = $DIC->database();
617
618 $set = $ilDB->query("SELECT * FROM svy_svy_qst ".
619 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
620 " AND question_fi = ".$ilDB->quote($a_question_fi, "integer"));
621 if ($rec = $ilDB->fetchAssoc($set))
622 {
623 return true;
624 }
625 return false;
626 }
627
628
629
635 function insertQuestionblock($questionblock_id)
636 {
637 global $ilDB;
638 $result = $ilDB->queryF("SELECT svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle,".
639 " svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst, svy_svy_qst".
640 " WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi".
641 " AND svy_svy_qst.question_fi = svy_qblk_qst.question_fi".
642 " AND svy_qblk.questionblock_id = %s".
643 " ORDER BY svy_svy_qst.sequence",
644 array('integer'),
645 array($questionblock_id)
646 );
647 $questions = array();
648 $show_questiontext = 0;
649 $show_blocktitle = 0;
650 while ($row = $ilDB->fetchAssoc($result))
651 {
652 $duplicate_id = $this->duplicateQuestionForSurvey($row["question_fi"]);
653 array_push($questions, $duplicate_id);
654 $title = $row["title"];
655 $show_questiontext = $row["show_questiontext"];
656 $show_blocktitle = $row["show_blocktitle"];
657 }
658 $this->createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions);
659 }
660
661 public function saveUserSettings($usr_id, $key, $title, $value)
662 {
663 global $ilDB;
664
665 $next_id = $ilDB->nextId('svy_settings');
666 $affectedRows = $ilDB->insert("svy_settings", array(
667 "settings_id" => array("integer", $next_id),
668 "usr_id" => array("integer", $usr_id),
669 "keyword" => array("text", $key),
670 "title" => array("text", $title),
671 "value" => array("clob", $value)
672 ));
673 }
674
675 public function deleteUserSettings($id)
676 {
677 global $ilDB;
678
679 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_settings WHERE settings_id = %s",
680 array('integer'),
681 array($id)
682 );
683 return $affectedRows;
684 }
685
686 public function getUserSettings($usr_id, $key)
687 {
688 global $ilDB;
689
690 $result = $ilDB->queryF("SELECT * FROM svy_settings WHERE usr_id = %s AND keyword = %s",
691 array('integer', 'text'),
692 array($usr_id, $key)
693 );
694 $found = array();
695 if ($result->numRows())
696 {
697 while ($row = $ilDB->fetchAssoc($result))
698 {
699 $found[$row['settings_id']] = $row;
700 }
701 }
702 return $found;
703 }
704
710 function saveToDb()
711 {
712 global $ilDB;
713
714 // date handling
715 $rmd_start = $this->getReminderStart();
716 if(is_object($rmd_start))
717 {
718 $rmd_start = $rmd_start->get(IL_CAL_DATE);
719 }
720 $rmd_end = $this->getReminderEnd();
721 if(is_object($rmd_end))
722 {
723 $rmd_end = $rmd_end->get(IL_CAL_DATE);
724 }
725
726 include_once("./Services/RTE/classes/class.ilRTE.php");
727 if ($this->getSurveyId() < 1)
728 {
729 $next_id = $ilDB->nextId('svy_svy');
730 $affectedRows = $ilDB->insert("svy_svy", array(
731 "survey_id" => array("integer", $next_id),
732 "obj_fi" => array("integer", $this->getId()),
733 "author" => array("text", $this->getAuthor()),
734 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
735 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
736 "status" => array("text", $this->getStatus()),
737 "startdate" => array("text", $this->getStartDate()),
738 "enddate" => array("text", $this->getEndDate()),
739 "evaluation_access" => array("text", $this->getEvaluationAccess()),
740 "invitation" => array("text", $this->getInvitation()),
741 "invitation_mode" => array("text", $this->getInvitationMode()),
742 "complete" => array("text", $this->isComplete()),
743 "created" => array("integer", time()),
744 "anonymize" => array("text", $this->getAnonymize()),
745 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
746 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
747 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : NULL),
748 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : NULL),
749 "tstamp" => array("integer", time()),
750 "template_id" => array("integer", $this->getTemplate()),
751 "pool_usage" => array("integer", $this->getPoolUsage()),
752 // 360°
753 "mode_360" => array("integer", $this->get360Mode()),
754 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
755 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
756 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
757 "mode_360_results" => array("integer", $this->get360Results()),
758 "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
759 // reminder/notification
760 "reminder_status" => array("integer", (int)$this->getReminderStatus()),
761 "reminder_start" => array("datetime", $rmd_start),
762 "reminder_end" => array("datetime", $rmd_end),
763 "reminder_frequency" => array("integer", (int)$this->getReminderFrequency()),
764 "reminder_target" => array("integer", (int)$this->getReminderTarget()),
765 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
766 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
767 "tutor_ntf_status" => array("integer", (int)$this->getTutorNotificationStatus()),
768 "tutor_ntf_reci" => array("text", implode(";", (array)$this->getTutorNotificationRecipients())),
769 "tutor_ntf_target" => array("integer", (int)$this->getTutorNotificationTarget()),
770 "own_results_view" => array("integer", $this->hasViewOwnResults()),
771 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
772 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
773 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
774 ));
775 $this->setSurveyId($next_id);
776 }
777 else
778 {
779 $affectedRows = $ilDB->update("svy_svy", array(
780 "author" => array("text", $this->getAuthor()),
781 "introduction" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getIntroduction(), 0)),
782 "outro" => array("clob", ilRTE::_replaceMediaObjectImageSrc($this->getOutro(), 0)),
783 "status" => array("text", $this->getStatus()),
784 "startdate" => array("text", $this->getStartDate()),
785 "enddate" => array("text", $this->getEndDate()),
786 "evaluation_access" => array("text", $this->getEvaluationAccess()),
787 "invitation" => array("text", $this->getInvitation()),
788 "invitation_mode" => array("text", $this->getInvitationMode()),
789 "complete" => array("text", $this->isComplete()),
790 "anonymize" => array("text", $this->getAnonymize()),
791 "show_question_titles" => array("text", $this->getShowQuestionTitles()),
792 "mailnotification" => array('integer', ($this->getMailNotification()) ? 1 : 0),
793 "mailaddresses" => array('text', strlen($this->getMailAddresses()) ? $this->getMailAddresses() : NULL),
794 "mailparticipantdata" => array('text', strlen($this->getMailParticipantData()) ? $this->getMailParticipantData() : NULL),
795 "tstamp" => array("integer", time()),
796 "template_id" => array("integer", $this->getTemplate()),
797 "pool_usage" => array("integer", $this->getPoolUsage()),
798 // 360°
799 "mode_360" => array("integer", $this->get360Mode()),
800 "mode_360_self_eval" => array("integer", $this->get360SelfEvaluation()),
801 "mode_360_self_rate" => array("integer", $this->get360SelfRaters()),
802 "mode_360_self_appr" => array("integer", $this->get360SelfAppraisee()),
803 "mode_360_results" => array("integer", $this->get360Results()),
804 "mode_360_skill_service" => array("integer", (int) $this->get360SkillService()),
805 // reminder/notification
806 "reminder_status" => array("integer", $this->getReminderStatus()),
807 "reminder_start" => array("datetime", $rmd_start),
808 "reminder_end" => array("datetime", $rmd_end),
809 "reminder_frequency" => array("integer", $this->getReminderFrequency()),
810 "reminder_target" => array("integer", $this->getReminderTarget()),
811 "reminder_last_sent" => array("datetime", $this->getReminderLastSent()),
812 "reminder_tmpl" => array("text", $this->getReminderTemplate()),
813 "tutor_ntf_status" => array("integer", $this->getTutorNotificationStatus()),
814 "tutor_ntf_reci" => array("text", implode(";", (array)$this->getTutorNotificationRecipients())),
815 "tutor_ntf_target" => array("integer", $this->getTutorNotificationTarget()),
816 "own_results_view" => array("integer", $this->hasViewOwnResults()),
817 "own_results_mail" => array("integer", $this->hasMailOwnResults()),
818 "confirmation_mail" => array("integer", $this->hasMailConfirmation()),
819 "anon_user_list" => array("integer", $this->hasAnonymousUserList())
820 ), array(
821 "survey_id" => array("integer", $this->getSurveyId())
822 ));
823 }
824 if ($affectedRows)
825 {
826 // save questions to db
827 $this->saveQuestionsToDb();
828 }
829
830 // moved activation to ilObjectActivation
831 if($this->ref_id)
832 {
833 include_once "./Services/Object/classes/class.ilObjectActivation.php";
834 ilObjectActivation::getItem($this->ref_id);
835
836 $item = new ilObjectActivation;
837 if(!$this->isActivationLimited())
838 {
840 }
841 else
842 {
843 $item->setTimingType(ilObjectActivation::TIMINGS_ACTIVATION);
844 $item->setTimingStart($this->getActivationStartDate());
845 $item->setTimingEnd($this->getActivationEndDate());
846 $item->toggleVisible($this->getActivationVisibility());
847 }
848
849 $item->update($this->ref_id);
850 }
851 }
852
860 {
861 global $ilDB;
862
863 $this->log->debug("save questions");
864
865 // gather old questions state
866 $old_questions = array();
867 $result = $ilDB->queryF("SELECT survey_question_id,question_fi,sequence".
868 " FROM svy_svy_qst WHERE survey_fi = %s",
869 array('integer'),
870 array($this->getSurveyId())
871 );
872 while($row = $ilDB->fetchAssoc($result))
873 {
874 $old_questions[$row["question_fi"]] = $row; // problem, as soon as duplicates exist, they will be hidden here
875 }
876
877 // #15231 - diff with current questions state
878 $insert = $update = $delete = array();
879 foreach($this->questions as $seq => $fi)
880 {
881 if(!array_key_exists($fi, $old_questions)) // really new fi IDs
882 {
883 $insert[] = $fi; // this should be ok, should not create duplicates here
884 }
885 else if($old_questions[$fi]["sequence"] != $seq) // we are updating one of the duplicates (if any)
886 {
887 $update[$fi] = $old_questions[$fi]["survey_question_id"];
888 }
889 // keep track of still relevant questions
890 unset($old_questions[$fi]); // deleting old question, if they are not in current array
891 }
892
893 // delete obsolete question relations
894 if(sizeof($old_questions))
895 {
896 $del_ids = array();
897 foreach($old_questions as $fi => $old)
898 {
899 $del_ids[] = $old["survey_question_id"];
900 }
901 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst".
902 " WHERE ".$ilDB->in("survey_question_id", $del_ids, "", "integer"));
903 $this->log->debug("delete: ".$q);
904 }
905 unset($old_questions);
906
907 // create/update question relations
908 foreach($this->questions as $seq => $fi)
909 {
910 if(in_array($fi, $insert))
911 {
912 // check if question is not already in the survey, see #22018
913 if (!$this->isQuestionInSurvey($fi))
914 {
915 $next_id = $ilDB->nextId('svy_svy_qst');
916 $ilDB->manipulateF("INSERT INTO svy_svy_qst" .
917 " (survey_question_id, survey_fi, question_fi, heading, sequence, tstamp)" .
918 " VALUES (%s, %s, %s, %s, %s, %s)",
919 array('integer', 'integer', 'integer', 'text', 'integer', 'integer'),
920 array($next_id, $this->getSurveyId(), $fi, null, $seq, time())
921 );
922 $this->log->debug("insert svy_svy_qst, id:" . $next_id . ", fi: " . $fi . ", seq:" . $seq);
923 }
924 }
925 else if(array_key_exists($fi, $update))
926 {
927 $ilDB->manipulate("UPDATE svy_svy_qst".
928 " SET sequence = ".$ilDB->quote($seq, "integer").
929 ", tstamp = ".$ilDB->quote(time(), "integer").
930 " WHERE survey_question_id = ".$ilDB->quote($update[$fi], "integer"));
931 $this->log->debug("update svy_svy_qst, id:".$update[$fi].", fi: ".$fi.", seq:".$seq);
932 }
933 }
934 }
935
944 {
945 global $ilDB;
946 $result = $ilDB->queryF("SELECT anonymous_id FROM svy_finished WHERE anonymous_id = %s",
947 array('text'),
948 array($id)
949 );
950 if ($result->numRows())
951 {
952 $row = $ilDB->fetchAssoc($result);
953 return $row["anonymous_id"];
954 }
955 else
956 {
957 return "";
958 }
959 }
960
967 function getQuestionGUI($questiontype, $question_id)
968 {
969 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestionGUI.php";
970 return SurveyQuestionGUI::_getQuestionGUI($questiontype, $question_id);
971 }
972
980 function getQuestionType($question_id)
981 {
982 global $ilDB;
983 if ($question_id < 1) return -1;
984 $result = $ilDB->queryF("SELECT type_tag FROM svy_question, svy_qtype WHERE svy_question.question_id = %s AND " .
985 "svy_question.questiontype_fi = svy_qtype.questiontype_id",
986 array('integer'),
987 array($question_id)
988 );
989 if ($result->numRows() == 1)
990 {
991 $data = $ilDB->fetchAssoc($result);
992 return $data["type_tag"];
993 }
994 else
995 {
996 return "";
997 }
998 }
999
1006 function getSurveyId()
1007 {
1008 return $this->survey_id;
1009 }
1010
1014 function setAnonymize($a_anonymize)
1015 {
1016 switch ($a_anonymize)
1017 {
1019 case self::ANONYMIZE_ON:
1022 $this->anonymize = $a_anonymize;
1023 break;
1024 default:
1025 $this->anonymize = self::ANONYMIZE_OFF;
1026 break;
1027 }
1028 }
1029
1035 function getAnonymize()
1036 {
1037 return ($this->anonymize) ? $this->anonymize : 0;
1038 }
1039
1046 {
1047 return ($this->getAnonymize() == self::ANONYMIZE_OFF ||
1048 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1049 }
1050
1057 {
1058 return ($this->getAnonymize() == self::ANONYMIZE_ON ||
1059 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS);
1060 }
1061
1067 function loadFromDb()
1068 {
1069 global $ilDB;
1070 $result = $ilDB->queryF("SELECT * FROM svy_svy WHERE obj_fi = %s",
1071 array('integer'),
1072 array($this->getId())
1073 );
1074 if ($result->numRows() == 1)
1075 {
1076 $data = $ilDB->fetchAssoc($result);
1077 $this->setSurveyId($data["survey_id"]);
1078 $this->setAuthor($data["author"]);
1079 include_once("./Services/RTE/classes/class.ilRTE.php");
1080 $this->setIntroduction(ilRTE::_replaceMediaObjectImageSrc($data["introduction"], 1));
1081 if (strcmp($data["outro"], "survey_finished") == 0)
1082 {
1083 $this->setOutro($this->lng->txt("survey_finished"));
1084 }
1085 else
1086 {
1088 }
1089 $this->setInvitation($data["invitation"]);
1090 $this->setInvitationMode($data["invitation_mode"]);
1091 $this->setShowQuestionTitles($data["show_question_titles"]);
1092 $this->setStartDate($data["startdate"]);
1093 $this->setEndDate($data["enddate"]);
1094 $this->setAnonymize($data["anonymize"]);
1095 $this->setEvaluationAccess($data["evaluation_access"]);
1096 $this->loadQuestionsFromDb();
1097 $this->setStatus($data["status"]);
1098 $this->setMailNotification($data['mailnotification']);
1099 $this->setMailAddresses($data['mailaddresses']);
1100 $this->setMailParticipantData($data['mailparticipantdata']);
1101 $this->setTemplate($data['template_id']);
1102 $this->setPoolUsage($data['pool_usage']);
1103 // 360°
1104 $this->set360Mode($data['mode_360']);
1105 $this->set360SelfEvaluation($data['mode_360_self_eval']);
1106 $this->set360SelfRaters($data['mode_360_self_rate']);
1107 $this->set360SelfAppraisee($data['mode_360_self_appr']);
1108 $this->set360Results($data['mode_360_results']);
1109 $this->set360SkillService($data['mode_360_skill_service']);
1110 // reminder/notification
1111 $this->setReminderStatus($data["reminder_status"]);
1112 $this->setReminderStart($data["reminder_start"] ? new ilDate($data["reminder_start"], IL_CAL_DATE) : null);
1113 $this->setReminderEnd($data["reminder_end"] ? new ilDate($data["reminder_end"], IL_CAL_DATE) : null);
1114 $this->setReminderFrequency($data["reminder_frequency"]);
1115 $this->setReminderTarget($data["reminder_target"]);
1116 $this->setReminderLastSent($data["reminder_last_sent"]);
1117 $this->setReminderTemplate($data["reminder_tmpl"]);
1118 $this->setTutorNotificationStatus($data["tutor_ntf_status"]);
1119 $this->setTutorNotificationRecipients(explode(";", $data["tutor_ntf_reci"]));
1120 $this->setTutorNotificationTarget($data["tutor_ntf_target"]);
1121
1122 $this->setViewOwnResults($data["own_results_view"]);
1123 $this->setMailOwnResults($data["own_results_mail"]);
1124 $this->setMailConfirmation($data["confirmation_mail"]);
1125
1126 $this->setAnonymousUserList($data["anon_user_list"]);
1127 }
1128
1129 // moved activation to ilObjectActivation
1130 if($this->ref_id)
1131 {
1132 include_once "./Services/Object/classes/class.ilObjectActivation.php";
1133 $activation = ilObjectActivation::getItem($this->ref_id);
1134 switch($activation["timing_type"])
1135 {
1137 $this->setActivationLimited(true);
1138 $this->setActivationStartDate($activation["timing_start"]);
1139 $this->setActivationEndDate($activation["timing_end"]);
1140 $this->setActivationVisibility($activation["visible"]);
1141 break;
1142
1143 default:
1144 $this->setActivationLimited(false);
1145 break;
1146 }
1147 }
1148 }
1149
1157 {
1158 global $ilDB;
1159 $this->questions = array();
1160 $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1161 array('integer'),
1162 array($this->getSurveyId())
1163 );
1164 while ($data = $ilDB->fetchAssoc($result))
1165 {
1166 $this->questions[$data["sequence"]] = $data["question_fi"];
1167 }
1168 }
1169
1174 {
1175 global $DIC;
1176
1177 $ilDB = $DIC->database();
1178//return;
1179 // we keep all survey question ids with their lowest sequence
1180 $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
1181 array('integer'),
1182 array($this->getSurveyId())
1183 );
1184
1185 // step 1: find duplicates -> $to_delete_ids
1186 $fis = array();
1187 $to_delete_ids = array();
1188 while ($data = $ilDB->fetchAssoc($result))
1189 {
1190 if (in_array($data["question_fi"], $fis)) // found a duplicate
1191 {
1192 $to_delete_ids[] = $data["survey_question_id"];
1193 }
1194 else
1195 {
1196 $fis[] = $data["question_fi"];
1197 }
1198 }
1199
1200 // step 2: we delete the duplicates
1201 if (count($to_delete_ids) > 0)
1202 {
1203 $ilDB->manipulate($q = "DELETE FROM svy_svy_qst" .
1204 " WHERE " . $ilDB->in("survey_question_id", $to_delete_ids, false, "integer") .
1205 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1206 $this->log->debug("delete: " . $q);
1207
1208 $ilDB->manipulate($q = "DELETE FROM svy_qblk_qst " .
1209 " WHERE " . $ilDB->in("question_fi", $fis, true, "integer") .
1210 " AND survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer"));
1211 $this->log->debug("delete: " . $q);
1212 }
1213
1214 // step 3: we fix the sequence
1215 $set = $ilDB->query("SELECT * FROM svy_svy_qst ".
1216 " WHERE survey_fi = " . $ilDB->quote($this->getSurveyId(), "integer")." ORDER BY sequence");
1217 $seq = 0;
1218 while ($rec = $ilDB->fetchAssoc($set))
1219 {
1220 $ilDB->manipulate($q = "UPDATE svy_svy_qst SET ".
1221 " sequence = ".$ilDB->quote($seq++ , "integer").
1222 " WHERE survey_question_id = ".$ilDB->quote($rec["survey_question_id"], "integer")
1223 );
1224 $this->log->debug("update: " . $q);
1225 }
1226 }
1227
1228
1236 function setAuthor($author = "")
1237 {
1238 $this->author = $author;
1239 }
1240
1250 function saveAuthorToMetadata($a_author = "")
1251 {
1252 $md = new ilMD($this->getId(), 0, $this->getType());
1253 $md_life =& $md->getLifecycle();
1254 if (!$md_life)
1255 {
1256 if (strlen($a_author) == 0)
1257 {
1258 global $ilUser;
1259 $a_author = $ilUser->getFullname();
1260 }
1261
1262 $md_life =& $md->addLifecycle();
1263 $md_life->save();
1264 $con =& $md_life->addContribute();
1265 $con->setRole("Author");
1266 $con->save();
1267 $ent =& $con->addEntity();
1268 $ent->setEntity($a_author);
1269 $ent->save();
1270 }
1271 }
1272
1280 function getAuthor()
1281 {
1282 $author = array();
1283 include_once "./Services/MetaData/classes/class.ilMD.php";
1284 $md = new ilMD($this->getId(), 0, $this->getType());
1285 $md_life =& $md->getLifecycle();
1286 if ($md_life)
1287 {
1288 $ids =& $md_life->getContributeIds();
1289 foreach ($ids as $id)
1290 {
1291 $md_cont =& $md_life->getContribute($id);
1292 if (strcmp($md_cont->getRole(), "Author") == 0)
1293 {
1294 $entids =& $md_cont->getEntityIds();
1295 foreach ($entids as $entid)
1296 {
1297 $md_ent =& $md_cont->getEntity($entid);
1298 array_push($author, $md_ent->getEntity());
1299 }
1300 }
1301 }
1302 }
1303 return join($author, ",");
1304 }
1305
1312 public function getShowQuestionTitles()
1313 {
1314 return ($this->display_question_titles) ? 1 : 0;
1315 }
1316
1323 public function setShowQuestionTitles($a_show)
1324 {
1325 $this->display_question_titles = ($a_show) ? 1 : 0;
1326 }
1327
1335 {
1336 $this->display_question_titles = 1;
1337 }
1338
1346 {
1347 $this->display_question_titles = 0;
1348 }
1349
1358 {
1359 global $ilDB, $ilAccess;
1360
1361 $this->invitation = $invitation;
1363 {
1364 $this->disinviteAllUsers();
1365 }
1366 else if ($invitation == self::INVITATION_ON)
1367 {
1368 if ($this->getInvitationMode() == self::MODE_UNLIMITED)
1369 {
1370 $result = $ilDB->query("SELECT usr_id FROM usr_data");
1371 while ($row = $ilDB->fetchAssoc($result))
1372 {
1373 if ($ilAccess->checkAccessOfUser($row["usr_id"], "read", "", $this->getRefId(), "svy", $this->getId()))
1374 {
1375 $this->inviteUser($row['usr_id']);
1376 }
1377 }
1378 }
1379 }
1380 }
1381
1389 function setInvitationMode($invitation_mode = 0)
1390 {
1391 $this->invitation_mode = $invitation_mode;
1392 }
1393
1403 {
1404 $this->invitation_mode = $invitation_mode;
1405 $this->setInvitation($invitation);
1406 }
1407
1414 public function setIntroduction($introduction = "")
1415 {
1416 $this->introduction = $introduction;
1417 }
1418
1425 public function setOutro($outro = "")
1426 {
1427 $this->outro = $outro;
1428 }
1429
1437 function getInvitation()
1438 {
1439 return ($this->invitation) ? $this->invitation : self::INVITATION_OFF;
1440 }
1441
1450 {
1451 include_once "./Services/Administration/classes/class.ilSetting.php";
1452 $surveySetting = new ilSetting("survey");
1453 $unlimited_invitation = $surveySetting->get("unlimited_invitation");
1454 if (!$unlimited_invitation && $this->invitation_mode == self::MODE_UNLIMITED)
1455 {
1457 }
1458 else
1459 {
1460 return ($this->invitation_mode) ? $this->invitation_mode : self::MODE_UNLIMITED;
1461 }
1462 }
1463
1471 function getStatus()
1472 {
1473 return ($this->status) ? $this->status : self::STATUS_OFFLINE;
1474 }
1475
1483 function isOnline()
1484 {
1485 return ($this->status == self::STATUS_ONLINE) ? true : false;
1486 }
1487
1495 function isOffline()
1496 {
1497 return ($this->status == self::STATUS_OFFLINE) ? true : false;
1498 }
1499
1508 function setStatus($status = self::STATUS_OFFLINE)
1509 {
1510 $result = "";
1511 if (($status == self::STATUS_ONLINE) && (count($this->questions) == 0))
1512 {
1513 $this->status = self::STATUS_OFFLINE;
1514 $result = $this->lng->txt("cannot_switch_to_online_no_questions");
1515 }
1516 else
1517 {
1518 $this->status = $status;
1519 }
1520 return $result;
1521 }
1522
1530 function getStartDate()
1531 {
1532 return (strlen($this->start_date)) ? $this->start_date : NULL;
1533 }
1534
1541 function canStartSurvey($anonymous_id = NULL, $a_no_rbac = false)
1542 {
1543 global $ilAccess;
1544
1545 $result = TRUE;
1546 $messages = array();
1547 $edit_settings = false;
1548 // check start date
1549 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches))
1550 {
1551 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1552 $now = time();
1553 if ($now < $epoch_time)
1554 {
1555 array_push($messages,$this->lng->txt('start_date_not_reached').' ('.
1557 $result = FALSE;
1558 $edit_settings = true;
1559 }
1560 }
1561 // check end date
1562 if (preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches))
1563 {
1564 $epoch_time = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
1565 $now = time();
1566 if ($now > $epoch_time)
1567 {
1568 array_push($messages,$this->lng->txt('end_date_reached').' ('.
1570 $result = FALSE;
1571 $edit_settings = true;
1572 }
1573 }
1574
1575 // check online status
1576 if ($this->getStatus() == self::STATUS_OFFLINE)
1577 {
1578 array_push($messages, $this->lng->txt("survey_is_offline"));
1579 $result = FALSE;
1580 $edit_settings = true;
1581 }
1582 // check rbac permissions
1583 if (!$a_no_rbac && !$ilAccess->checkAccess("read", "", $this->ref_id))
1584 {
1585 array_push($messages, $this->lng->txt("cannot_participate_survey"));
1586 $result = FALSE;
1587 }
1588 /*
1589 // 2. check previous access
1590 if (!$result["error"])
1591 {
1592 global $ilUser;
1593 $survey_started = $this->isSurveyStarted($ilUser->getId(), $anonymous_id);
1594 if ($survey_started === 1)
1595 {
1596 array_push($messages, $this->lng->txt("already_completed_survey"));
1597 $result = FALSE;
1598 }
1599 }
1600 */
1601 return array(
1602 "result" => $result,
1603 "messages" => $messages,
1604 "edit_settings" => $edit_settings
1605 );
1606 }
1607
1616 {
1617 $this->start_date = $start_date;
1618 }
1619
1628 function setStartDateAndTime($start_date = "", $start_time)
1629 {
1630 $y = ''; $m = ''; $d = ''; $h = ''; $i = ''; $s = '';
1631 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $start_date, $matches))
1632 {
1633 $y = $matches[1];
1634 $m = $matches[2];
1635 $d = $matches[3];
1636 }
1637 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $start_time, $matches))
1638 {
1639 $h = $matches[1];
1640 $i = $matches[2];
1641 $s = $matches[3];
1642 }
1643 $this->start_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1644 }
1645
1653 function getEndDate()
1654 {
1655 return (strlen($this->end_date)) ? $this->end_date : NULL;
1656 }
1657
1665 function setEndDate($end_date = "")
1666 {
1667 $this->end_date = $end_date;
1668 }
1669
1678 function setEndDateAndTime($end_date = "", $end_time)
1679 {
1680 $y = ''; $m = ''; $d = ''; $h = ''; $i = ''; $s = '';
1681 if (preg_match("/(\d{4})-(\d{2})-(\d{2})/", $end_date, $matches))
1682 {
1683 $y = $matches[1];
1684 $m = $matches[2];
1685 $d = $matches[3];
1686 }
1687 if (preg_match("/(\d{2}):(\d{2}):(\d{2})/", $end_time, $matches))
1688 {
1689 $h = $matches[1];
1690 $i = $matches[2];
1691 $s = $matches[3];
1692 }
1693 $this->end_date = sprintf('%04d%02d%02d%02d%02d%02d', $y, $m, $d, $h, $i, $s);
1694 }
1695
1704 {
1705 return ($this->evaluation_access) ? $this->evaluation_access : self::EVALUATION_ACCESS_OFF;
1706 }
1707
1715 function setEvaluationAccess($evaluation_access = self::EVALUATION_ACCESS_OFF)
1716 {
1717 $this->evaluation_access = ($evaluation_access) ? $evaluation_access : self::EVALUATION_ACCESS_OFF;
1718 }
1719
1720 function setActivationVisibility($a_value)
1721 {
1722 $this->activation_visibility = (bool) $a_value;
1723 }
1724
1726 {
1728 }
1729
1731 {
1732 return (bool)$this->activation_limited;
1733 }
1734
1735 function setActivationLimited($a_value)
1736 {
1737 $this->activation_limited = (bool)$a_value;
1738 }
1739
1748 {
1749 return (strlen($this->introduction)) ? $this->introduction : NULL;
1750 }
1751
1759 function getOutro()
1760 {
1761 return (strlen($this->outro)) ? $this->outro : NULL;
1762 }
1763
1771 {
1772 global $ilDB;
1773 $existing_questions = array();
1774 $result = $ilDB->queryF("SELECT svy_question.original_id FROM svy_question, svy_svy_qst WHERE " .
1775 "svy_svy_qst.survey_fi = %s AND svy_svy_qst.question_fi = svy_question.question_id",
1776 array('integer'),
1777 array($this->getSurveyId())
1778 );
1779 while ($data = $ilDB->fetchAssoc($result))
1780 {
1781 if($data["original_id"])
1782 {
1783 array_push($existing_questions, $data["original_id"]);
1784 }
1785 }
1786 return $existing_questions;
1787 }
1788
1795 function &getQuestionpoolTitles($could_be_offline = FALSE, $showPath = FALSE)
1796 {
1797 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
1798 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_object_id = TRUE, $could_be_offline, $showPath);
1799 }
1800
1809 function moveQuestions($move_questions, $target_index, $insert_mode)
1810 {
1811 $array_pos = array_search($target_index, $this->questions);
1812 if ($insert_mode == 0)
1813 {
1814 $part1 = array_slice($this->questions, 0, $array_pos);
1815 $part2 = array_slice($this->questions, $array_pos);
1816 }
1817 else if ($insert_mode == 1)
1818 {
1819 $part1 = array_slice($this->questions, 0, $array_pos + 1);
1820 $part2 = array_slice($this->questions, $array_pos + 1);
1821 }
1822 foreach ($move_questions as $question_id)
1823 {
1824 if (!(array_search($question_id, $part1) === FALSE))
1825 {
1826 unset($part1[array_search($question_id, $part1)]);
1827 }
1828 if (!(array_search($question_id, $part2) === FALSE))
1829 {
1830 unset($part2[array_search($question_id, $part2)]);
1831 }
1832 }
1833 $part1 = array_values($part1);
1834 $part2 = array_values($part2);
1835 $this->questions = array_values(array_merge($part1, $move_questions, $part2));
1836 foreach ($move_questions as $question_id)
1837 {
1838 $constraints = $this->getConstraints($question_id);
1839 foreach ($constraints as $idx => $constraint)
1840 {
1841 foreach ($part2 as $next_question_id)
1842 {
1843 if ($constraint["question"] == $next_question_id)
1844 {
1845 // constraint concerning a question that follows -> delete constraint
1846 $this->deleteConstraint($constraint["id"]);
1847 }
1848 }
1849 }
1850 }
1851 $this->saveQuestionsToDb();
1852 }
1853
1860 function removeQuestion($question_id)
1861 {
1862 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
1863 $question = self::_instanciateQuestion($question_id);
1864 #20610 if no question found, do nothing.
1865 if($question)
1866 {
1867 $question->delete($question_id);
1868 $this->removeConstraintsConcerningQuestion($question_id);
1869 }
1870 }
1871
1879 {
1880 global $ilDB;
1881 $result = $ilDB->queryF("SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1882 array('integer','integer'),
1883 array($question_id, $this->getSurveyId())
1884 );
1885 if ($result->numRows() > 0)
1886 {
1887 $remove_constraints = array();
1888 while ($row = $ilDB->fetchAssoc($result))
1889 {
1890 array_push($remove_constraints, $row["constraint_fi"]);
1891 }
1892 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
1893 array('integer','integer'),
1894 array($question_id, $this->getSurveyId())
1895 );
1896 foreach ($remove_constraints as $key => $constraint_id)
1897 {
1898 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_constraint WHERE constraint_id = %s",
1899 array('integer'),
1900 array($constraint_id)
1901 );
1902 }
1903 }
1904 }
1905
1913 function removeQuestions($remove_questions, $remove_questionblocks)
1914 {
1915 global $ilDB;
1916
1917 $block_sizes = array();
1918 foreach ($this->getSurveyQuestions() as $question_id => $data)
1919 {
1920 if (in_array($question_id, $remove_questions) or in_array($data["questionblock_id"], $remove_questionblocks))
1921 {
1922 unset($this->questions[array_search($question_id, $this->questions)]);
1923 $this->removeQuestion($question_id);
1924 }
1925 else if($data["questionblock_id"])
1926 {
1927 $block_sizes[$data["questionblock_id"]]++;
1928 }
1929 }
1930
1931 // blocks with just 1 question need to be deleted
1932 foreach($block_sizes as $block_id => $size)
1933 {
1934 if($size < 2)
1935 {
1936 $remove_questionblocks[] = $block_id;
1937 }
1938 }
1939
1940 foreach (array_unique($remove_questionblocks) as $questionblock_id)
1941 {
1942 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk WHERE questionblock_id = %s",
1943 array('integer'),
1944 array($questionblock_id)
1945 );
1946 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1947 array('integer','integer'),
1948 array($questionblock_id, $this->getSurveyId())
1949 );
1950 }
1951
1952 $this->questions = array_values($this->questions);
1953 $this->saveQuestionsToDb();
1954 }
1955
1962 function unfoldQuestionblocks($questionblocks)
1963 {
1964 global $ilDB;
1965 foreach ($questionblocks as $index)
1966 {
1967 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk WHERE questionblock_id = %s",
1968 array('integer'),
1969 array($index)
1970 );
1971 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s",
1972 array('integer','integer'),
1973 array($index, $this->getSurveyId())
1974 );
1975 }
1976 }
1977
1978 function removeQuestionFromBlock($question_id, $questionblock_id)
1979 {
1980 global $ilDB;
1981
1982 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qblk_qst WHERE questionblock_fi = %s AND survey_fi = %s AND question_fi = %s",
1983 array('integer','integer','integer'),
1984 array($questionblock_id, $this->getSurveyId(), $question_id)
1985 );
1986 }
1987
1988 function addQuestionToBlock($question_id, $questionblock_id)
1989 {
1990 global $ilDB;
1991
1992 // see #22018
1993 if (!$this->isQuestionInAnyBlock($question_id))
1994 {
1995 $next_id = $ilDB->nextId('svy_qblk_qst');
1996 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
1997 "question_fi) VALUES (%s, %s, %s, %s)",
1998 array('integer', 'integer', 'integer', 'integer'),
1999 array($next_id, $this->getSurveyId(), $questionblock_id, $question_id)
2000 );
2001
2002 $this->deleteConstraints($question_id); // #13713
2003 }
2004 }
2005
2012 function isQuestionInAnyBlock($a_question_fi)
2013 {
2014 global $DIC;
2015
2016 $ilDB = $DIC->database();
2017
2018 $set = $ilDB->query("SELECT * FROM svy_qblk_qst ".
2019 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
2020 " AND question_fi = ".$ilDB->quote($a_question_fi, "integer"));
2021 if ($rec = $ilDB->fetchAssoc($set))
2022 {
2023 return true;
2024 }
2025 return false;
2026 }
2027
2028
2035 function &getQuestionblockQuestions($questionblock_id)
2036 {
2037 global $ilDB;
2038 $titles = array();
2039 $result = $ilDB->queryF("SELECT svy_question.title, svy_qblk_qst.question_fi, svy_qblk_qst.survey_fi FROM ".
2040 "svy_qblk, svy_qblk_qst, svy_question WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND " .
2041 "svy_question.question_id = svy_qblk_qst.question_fi AND svy_qblk.questionblock_id = %s",
2042 array('integer'),
2043 array($questionblock_id)
2044 );
2045 $survey_id = "";
2046 while ($row = $ilDB->fetchAssoc($result))
2047 {
2048 $titles[$row["question_fi"]] = $row["title"];
2049 $survey_id = $row["survey_fi"];
2050 }
2051 $result = $ilDB->queryF("SELECT question_fi, sequence FROM svy_svy_qst WHERE survey_fi = %s ORDER BY sequence",
2052 array('integer'),
2053 array($survey_id)
2054 );
2055 $resultarray = array();
2056 $counter = 1;
2057 while ($row = $ilDB->fetchAssoc($result))
2058 {
2059 if (array_key_exists($row["question_fi"], $titles))
2060 {
2061 $resultarray[$counter++] = $titles[$row["question_fi"]];
2062 }
2063 }
2064 return $resultarray;
2065 }
2066
2073 function &getQuestionblockQuestionIds($questionblock_id)
2074 {
2075 global $ilDB;
2076
2077 // we need a correct order here, see #22011
2078 $result = $ilDB->queryF("SELECT a.question_fi FROM svy_qblk_qst a JOIN svy_svy_qst b ON (a.question_fi = b.question_fi) ".
2079 " WHERE a.questionblock_fi = %s ORDER BY b.sequence",
2080 array("integer"),
2081 array($questionblock_id)
2082 );
2083 $ids = array();
2084 if ($result->numRows())
2085 {
2086 while ($data = $ilDB->fetchAssoc($result))
2087 {
2088 if (!in_array($data['question_fi'], $ids)) // no duplicates, see #22018
2089 {
2090 array_push($ids, $data['question_fi']);
2091 }
2092 }
2093 }
2094
2095 return $ids;
2096 }
2097
2105 static function _getQuestionblock($questionblock_id)
2106 {
2107 global $ilDB;
2108 $result = $ilDB->queryF("SELECT * FROM svy_qblk WHERE questionblock_id = %s",
2109 array('integer'),
2110 array($questionblock_id)
2111 );
2112 $row = $ilDB->fetchAssoc($result);
2113 return $row;
2114 }
2115
2124 static function _addQuestionblock($title = "", $owner = 0, $show_questiontext = true, $show_blocktitle = false)
2125 {
2126 global $ilDB;
2127 $next_id = $ilDB->nextId('svy_qblk');
2128 $ilDB->manipulateF("INSERT INTO svy_qblk (questionblock_id, title, show_questiontext,".
2129 " show_blocktitle, owner_fi, tstamp) " .
2130 "VALUES (%s, %s, %s, %s, %s, %s)",
2131 array('integer','text','integer','integer','integer','integer'),
2132 array($next_id, $title, $show_questiontext, $show_blocktitle, $owner, time())
2133 );
2134 return $next_id;
2135 }
2136
2144 function createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
2145 {
2146 global $ilDB;
2147
2148 // if the selected questions are not in a continous selection, move all questions of the
2149 // questionblock at the position of the first selected question
2150 $this->moveQuestions($questions, $questions[0], 0);
2151
2152 // now save the question block
2153 global $ilUser;
2154 $next_id = $ilDB->nextId('svy_qblk');
2155 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk (questionblock_id, title, show_questiontext,".
2156 " show_blocktitle, owner_fi, tstamp) VALUES (%s, %s, %s, %s, %s, %s)",
2157 array('integer','text','text','text','integer','integer'),
2158 array($next_id, $title, $show_questiontext, $show_blocktitle, $ilUser->getId(), time())
2159 );
2160 if ($affectedRows)
2161 {
2162 $questionblock_id = $next_id;
2163 foreach ($questions as $index)
2164 {
2165 if (!$this->isQuestionInAnyBlock($index))
2166 {
2167 $next_id = $ilDB->nextId('svy_qblk_qst'); // #22018
2168 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, " .
2169 "question_fi) VALUES (%s, %s, %s, %s)",
2170 array('integer', 'integer', 'integer', 'integer'),
2171 array($next_id, $this->getSurveyId(), $questionblock_id, $index)
2172 );
2173 $this->deleteConstraints($index);
2174 }
2175 }
2176 }
2177 }
2178
2186 function modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
2187 {
2188 global $ilDB;
2189 $affectedRows = $ilDB->manipulateF("UPDATE svy_qblk SET title = %s, show_questiontext = %s,".
2190 " show_blocktitle = %s WHERE questionblock_id = %s",
2191 array('text','text','text','integer'),
2192 array($title, $show_questiontext, $show_blocktitle, $questionblock_id)
2193 );
2194 }
2195
2202 function deleteConstraints($question_id)
2203 {
2204 global $ilDB;
2205 $result = $ilDB->queryF("SELECT constraint_fi FROM svy_qst_constraint WHERE question_fi = %s AND survey_fi = %s",
2206 array('integer','integer'),
2207 array($question_id, $this->getSurveyId())
2208 );
2209 $constraints = array();
2210 while ($row = $ilDB->fetchAssoc($result))
2211 {
2212 array_push($constraints, $row["constraint_fi"]);
2213 }
2214 foreach ($constraints as $constraint_id)
2215 {
2216 $this->deleteConstraint($constraint_id);
2217 }
2218 }
2219
2227 function deleteConstraint($constraint_id)
2228 {
2229 global $ilDB;
2230 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_constraint WHERE constraint_id = %s",
2231 array('integer'),
2232 array($constraint_id)
2233 );
2234 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_qst_constraint WHERE constraint_fi = %s",
2235 array('integer'),
2236 array($constraint_id)
2237 );
2238 }
2239
2245 public function &getSurveyQuestions($with_answers = false)
2246 {
2247 global $ilDB;
2248 // get questionblocks
2249 $all_questions = array();
2250 $result = $ilDB->queryF("SELECT svy_qtype.type_tag, svy_qtype.plugin, svy_question.question_id, ".
2251 "svy_svy_qst.heading FROM svy_qtype, svy_question, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2252 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id " .
2253 "ORDER BY svy_svy_qst.sequence",
2254 array('integer'),
2255 array($this->getSurveyId())
2256 );
2257 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2258 while ($row = $ilDB->fetchAssoc($result))
2259 {
2260 $add = true;
2261 if ($row["plugin"])
2262 {
2263 if (!$this->isPluginActive($row["type_tag"]))
2264 {
2265 $add = false;
2266 }
2267 }
2268 if ($add)
2269 {
2270 $question = self::_instanciateQuestion($row["question_id"]);
2271 $questionrow = $question->getQuestionDataArray($row["question_id"]);
2272 foreach ($row as $key => $value)
2273 {
2274 $questionrow[$key] = $value;
2275 }
2276 $all_questions[$row["question_id"]] = $questionrow;
2277 $all_questions[$row["question_id"]]["usableForPrecondition"] = $question->usableForPrecondition();
2278 $all_questions[$row["question_id"]]["availableRelations"] = $question->getAvailableRelations();
2279 }
2280 }
2281 // get all questionblocks
2282 $questionblocks = array();
2283 if (count($all_questions))
2284 {
2285 $result = $ilDB->queryF("SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst WHERE " .
2286 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s " .
2287 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2288 array('integer'),
2289 array($this->getSurveyId())
2290 );
2291 while ($row = $ilDB->fetchAssoc($result))
2292 {
2293 $questionblocks[$row['question_fi']] = $row;
2294 }
2295 }
2296
2297 foreach ($all_questions as $question_id => $row)
2298 {
2299 $constraints = $this->getConstraints($question_id);
2300 if (isset($questionblocks[$question_id]))
2301 {
2302 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2303 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2304 $all_questions[$question_id]["constraints"] = $constraints;
2305 }
2306 else
2307 {
2308 $all_questions[$question_id]["questionblock_title"] = "";
2309 $all_questions[$question_id]["questionblock_id"] = "";
2310 $all_questions[$question_id]["constraints"] = $constraints;
2311 }
2312 if ($with_answers)
2313 {
2314 $answers = array();
2315 $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable, svy_category " .
2316 "WHERE svy_variable.question_fi = %s AND svy_variable.category_fi = svy_category.category_id ".
2317 "ORDER BY sequence ASC",
2318 array('integer'),
2319 array($question_id)
2320 );
2321 if ($result->numRows() > 0)
2322 {
2323 while ($data = $ilDB->fetchAssoc($result))
2324 {
2325 array_push($answers, $data["title"]);
2326 }
2327 }
2328 $all_questions[$question_id]["answers"] = $answers;
2329 }
2330 }
2331 return $all_questions;
2332 }
2333
2340 function setObligatoryStates($obligatory_questions)
2341 {
2342 global $ilDB;
2343 $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE survey_fi = %s",
2344 array('integer'),
2345 array($this->getSurveyId())
2346 );
2347 if ($result->numRows())
2348 {
2349 while ($row = $ilDB->fetchAssoc($result))
2350 {
2351 if (!array_key_exists($row["question_fi"], $obligatory_questions))
2352 {
2353 $obligatory_questions[$row["question_fi"]] = 0;
2354 }
2355 }
2356 }
2357
2358 // set the obligatory states in the database
2359 foreach ($obligatory_questions as $question_fi => $obligatory)
2360 {
2361 // #12420
2362 $ilDB->manipulate("UPDATE svy_question".
2363 " SET obligatory = ".$ilDB->quote($obligatory, "integer").
2364 " WHERE question_id = ".$ilDB->quote($question_fi, "integer"));
2365 }
2366 }
2367
2373 function &getSurveyPages()
2374 {
2375 global $ilDB;
2376 // get questionblocks
2377 $all_questions = array();
2378 $result = $ilDB->queryF("SELECT svy_question.*, svy_qtype.type_tag, svy_svy_qst.heading FROM " .
2379 "svy_question, svy_qtype, svy_svy_qst WHERE svy_svy_qst.survey_fi = %s AND " .
2380 "svy_svy_qst.question_fi = svy_question.question_id AND svy_question.questiontype_fi = svy_qtype.questiontype_id ".
2381 "ORDER BY svy_svy_qst.sequence",
2382 array('integer'),
2383 array($this->getSurveyId())
2384 );
2385 while ($row = $ilDB->fetchAssoc($result))
2386 {
2387 $all_questions[$row["question_id"]] = $row;
2388 }
2389 // get all questionblocks
2390 $questionblocks = array();
2391 if (count($all_questions))
2392 {
2393 $result = $ilDB->queryF("SELECT svy_qblk.*, svy_qblk_qst.question_fi FROM svy_qblk, svy_qblk_qst ".
2394 "WHERE svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_qblk_qst.survey_fi = %s ".
2395 "AND " . $ilDB->in('svy_qblk_qst.question_fi', array_keys($all_questions), false, 'integer'),
2396 array('integer'),
2397 array($this->getSurveyId())
2398 );
2399 while ($row = $ilDB->fetchAssoc($result))
2400 {
2401 $questionblocks[$row['question_fi']] = $row;
2402 }
2403 }
2404
2405 $all_pages = array();
2406 $pageindex = -1;
2407 $currentblock = "";
2408 foreach ($all_questions as $question_id => $row)
2409 {
2410 $constraints = array();
2411 if (isset($questionblocks[$question_id]))
2412 {
2413 if (!$currentblock or ($currentblock != $questionblocks[$question_id]['questionblock_id']))
2414 {
2415 $pageindex++;
2416 }
2417 $all_questions[$question_id]['page'] = $pageindex;
2418 $all_questions[$question_id]["questionblock_title"] = $questionblocks[$question_id]['title'];
2419 $all_questions[$question_id]["questionblock_id"] = $questionblocks[$question_id]['questionblock_id'];
2420 $all_questions[$question_id]["questionblock_show_questiontext"] = $questionblocks[$question_id]['show_questiontext'];
2421 $all_questions[$question_id]["questionblock_show_blocktitle"] = $questionblocks[$question_id]['show_blocktitle'];
2422 $currentblock = $questionblocks[$question_id]['questionblock_id'];
2423 $constraints = $this->getConstraints($question_id);
2424 $all_questions[$question_id]["constraints"] = $constraints;
2425 }
2426 else
2427 {
2428 $pageindex++;
2429 $all_questions[$question_id]['page'] = $pageindex;
2430 $all_questions[$question_id]["questionblock_title"] = "";
2431 $all_questions[$question_id]["questionblock_id"] = "";
2432 $all_questions[$question_id]["questionblock_show_questiontext"] = 1;
2433 $all_questions[$question_id]["questionblock_show_blocktitle"] = 1;
2434 $currentblock = "";
2435 $constraints = $this->getConstraints($question_id);
2436 $all_questions[$question_id]["constraints"] = $constraints;
2437 }
2438 if (!isset($all_pages[$pageindex]))
2439 {
2440 $all_pages[$pageindex] = array();
2441 }
2442 array_push($all_pages[$pageindex], $all_questions[$question_id]);
2443 }
2444 // calculate position percentage for every page
2445 $max = count($all_pages);
2446 $counter = 1;
2447 foreach ($all_pages as $index => $block)
2448 {
2449 foreach ($block as $blockindex => $question)
2450 {
2451 $all_pages[$index][$blockindex]["position"] = $counter / $max;
2452 }
2453 $counter++;
2454 }
2455
2456 return $all_pages;
2457 }
2458
2467 function getNextPage($active_page_question_id, $direction)
2468 {
2469 $foundpage = -1;
2470 $pages =& $this->getSurveyPages();
2471 if (strcmp($active_page_question_id, "") == 0)
2472 {
2473 return $pages[0];
2474 }
2475 foreach ($pages as $key => $question_array)
2476 {
2477 foreach ($question_array as $question)
2478 {
2479 if ($active_page_question_id == $question["question_id"])
2480 {
2481 $foundpage = $key;
2482 }
2483 }
2484 }
2485 if ($foundpage == -1)
2486 {
2487 // error: page not found
2488 }
2489 else
2490 {
2491 $foundpage += $direction;
2492 if ($foundpage < 0)
2493 {
2494 return 0;
2495 }
2496 if ($foundpage >= count($pages))
2497 {
2498 return 1;
2499 }
2500 return $pages[$foundpage];
2501 }
2502 }
2503
2510 function &getAvailableQuestionpools($use_obj_id = false, $could_be_offline = false, $showPath = FALSE, $permission = "read")
2511 {
2512 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
2513 return ilObjSurveyQuestionPool::_getAvailableQuestionpools($use_obj_id, $could_be_offline, $showPath, $permission);
2514 }
2515
2522 {
2523 global $ilDB;
2524
2525 $result_array = array();
2526 $result = $ilDB->queryF("SELECT svy_constraint.*, svy_relation.*, svy_qst_constraint.question_fi ref_question_fi FROM svy_qst_constraint, svy_constraint, ".
2527 "svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id AND ".
2528 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_constraint.constraint_id = %s",
2529 array('integer'),
2530 array($id)
2531 );
2532 $pc = array();
2533 if ($result->numRows())
2534 {
2535 $pc = $ilDB->fetchAssoc($result);
2536 }
2537 return $pc;
2538 }
2539
2545 function getConstraints($question_id)
2546 {
2547 global $ilDB;
2548
2549 $result_array = array();
2550 $result = $ilDB->queryF("SELECT svy_constraint.*, svy_relation.* FROM svy_qst_constraint, svy_constraint, svy_relation ".
2551 "WHERE svy_constraint.relation_fi = svy_relation.relation_id AND ".
2552 "svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.question_fi = %s ".
2553 "AND svy_qst_constraint.survey_fi = %s",
2554 array('integer','integer'),
2555 array($question_id, $this->getSurveyId())
2556 );
2557 while ($row = $ilDB->fetchAssoc($result))
2558 {
2559 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
2560 $question_type = SurveyQuestion::_getQuestionType($row["question_fi"]);
2561 SurveyQuestion::_includeClass($question_type);
2562 $question = new $question_type();
2563 $question->loadFromDb($row["question_fi"]);
2564 $valueoutput = $question->getPreconditionValueOutput($row["value"]);
2565 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));
2566 }
2567 return $result_array;
2568 }
2569
2576 {
2577 global $ilDB;
2578 $result_array = array();
2579 $result = $ilDB->queryF("SELECT svy_qst_constraint.question_fi as for_question, svy_constraint.*, svy_relation.* ".
2580 "FROM svy_qst_constraint, svy_constraint, svy_relation WHERE svy_constraint.relation_fi = svy_relation.relation_id ".
2581 "AND svy_qst_constraint.constraint_fi = svy_constraint.constraint_id AND svy_qst_constraint.survey_fi = %s",
2582 array('integer'),
2583 array($survey_id)
2584 );
2585 while ($row = $ilDB->fetchAssoc($result))
2586 {
2587 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']));
2588 }
2589 return $result_array;
2590 }
2591
2592
2598 function &getVariables($question_id)
2599 {
2600 global $ilDB;
2601
2602 $result_array = array();
2603 $result = $ilDB->queryF("SELECT svy_variable.*, svy_category.title FROM svy_variable LEFT JOIN ".
2604 "svy_category ON svy_variable.category_fi = svy_category.category_id WHERE svy_variable.question_fi = %s ".
2605 "ORDER BY svy_variable.sequence",
2606 array('integer'),
2607 array($question_id)
2608 );
2609 while ($row = $ilDB->fetchObject($result))
2610 {
2611 $result_array[$row->sequence] = $row;
2612 }
2613 return $result_array;
2614 }
2615
2624 function addConstraint($if_question_id, $relation, $value, $conjunction)
2625 {
2626 global $ilDB;
2627
2628 $next_id = $ilDB->nextId('svy_constraint');
2629 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_constraint (constraint_id, question_fi, relation_fi, value, conjunction) VALUES ".
2630 "(%s, %s, %s, %s, %s)",
2631 array('integer','integer','integer','float', 'integer'),
2632 array($next_id, $if_question_id, $relation, $value, $conjunction)
2633 );
2634 if ($affectedRows)
2635 {
2636 return $next_id;
2637 }
2638 else
2639 {
2640 return null;
2641 }
2642 }
2643
2644
2651 public function addConstraintToQuestion($to_question_id, $constraint_id)
2652 {
2653 global $ilDB;
2654
2655 $next_id = $ilDB->nextId('svy_qst_constraint');
2656 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qst_constraint (question_constraint_id, survey_fi, question_fi, ".
2657 "constraint_fi) VALUES (%s, %s, %s, %s)",
2658 array('integer','integer','integer','integer'),
2659 array($next_id, $this->getSurveyId(), $to_question_id, $constraint_id)
2660 );
2661 }
2662
2673 function updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
2674 {
2675 global $ilDB;
2676 $affectedRows = $ilDB->manipulateF("UPDATE svy_constraint SET question_fi = %s, relation_fi = %s, value = %s, conjunction = %s ".
2677 "WHERE constraint_id = %s",
2678 array('integer','integer','float','integer','integer'),
2679 array($if_question_id, $relation, $value, $conjunction, $precondition_id)
2680 );
2681 }
2682
2683 public function updateConjunctionForQuestions($questions, $conjunction)
2684 {
2685 global $ilDB;
2686 foreach ($questions as $question_id)
2687 {
2688 $affectedRows = $ilDB->manipulateF("UPDATE svy_constraint SET conjunction = %s ".
2689 "WHERE constraint_id IN (SELECT constraint_fi FROM svy_qst_constraint WHERE svy_qst_constraint.question_fi = %s)",
2690 array('integer','integer'),
2691 array($conjunction, $question_id)
2692 );
2693 }
2694 }
2695
2701 function getAllRelations($short_as_key = false)
2702 {
2703 global $ilDB;
2704
2705 // #7987
2706 $custom_order = array("equal", "not_equal", "less", "less_or_equal", "more", "more_or_equal");
2707 $custom_order = array_flip($custom_order);
2708
2709 $result_array = array();
2710 $result = $ilDB->query("SELECT * FROM svy_relation");
2711 while ($row = $ilDB->fetchAssoc($result))
2712 {
2713 if ($short_as_key)
2714 {
2715 $result_array[$row["shortname"]] = array("short" => $row["shortname"], "long" => $row["longname"], "id" => $row["relation_id"], "order" => $custom_order[$row["longname"]]);
2716 }
2717 else
2718 {
2719 $result_array[$row["relation_id"]] = array("short" => $row["shortname"], "long" => $row["longname"], "order" => $custom_order[$row["longname"]]);
2720 }
2721 }
2722
2723 $result_array = ilUtil::sortArray($result_array, "order", "ASC", true, true);
2724 foreach($result_array as $idx => $item)
2725 {
2726 unset($result_array[$idx]["order"]);
2727 }
2728
2729 return $result_array;
2730 }
2731
2735 public function disinviteAllUsers()
2736 {
2737 global $ilDB;
2738 $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2739 array('integer'),
2740 array($this->getSurveyId())
2741 );
2742 while ($row = $ilDB->fetchAssoc($result))
2743 {
2744 $this->disinviteUser($row['user_fi']);
2745 }
2746 }
2747
2753 public function disinviteUser($user_id)
2754 {
2755 global $ilDB;
2756
2757 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_inv_usr WHERE survey_fi = %s AND user_fi = %s",
2758 array('integer','integer'),
2759 array($this->getSurveyId(), $user_id)
2760 );
2761 include_once './Services/User/classes/class.ilObjUser.php';
2762 ilObjUser::_dropDesktopItem($user_id, $this->getRefId(), "svy");
2763 }
2764
2771 function inviteUser($user_id)
2772 {
2773 global $ilDB;
2774
2775 $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE user_fi = %s AND survey_fi = %s",
2776 array('integer','integer'),
2777 array($user_id, $this->getSurveyId())
2778 );
2779 if ($result->numRows() < 1)
2780 {
2781 $next_id = $ilDB->nextId('svy_inv_usr');
2782 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_inv_usr (invited_user_id, survey_fi, user_fi, tstamp) " .
2783 "VALUES (%s, %s, %s, %s)",
2784 array('integer','integer','integer','integer'),
2785 array($next_id, $this->getSurveyId(), $user_id, time())
2786 );
2787 }
2788 if ($this->getInvitation() == self::INVITATION_ON)
2789 {
2790 include_once './Services/User/classes/class.ilObjUser.php';
2791 ilObjUser::_addDesktopItem($user_id, $this->getRefId(), "svy");
2792 }
2793 }
2794
2802 {
2803 global $ilDB;
2804
2805 $result_array = array();
2806 $result = $ilDB->queryF("SELECT user_fi FROM svy_inv_usr WHERE survey_fi = %s",
2807 array('integer'),
2808 array($this->getSurveyId())
2809 );
2810 while ($row = $ilDB->fetchAssoc($result))
2811 {
2812 array_push($result_array, $row["user_fi"]);
2813 }
2814 return $result_array;
2815 }
2816
2824 function deleteWorkingData($question_id, $active_id)
2825 {
2826 global $ilDB;
2827
2828 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2829 array('integer','integer'),
2830 array($question_id, $active_id)
2831 );
2832 }
2833
2842 function loadWorkingData($question_id, $active_id)
2843 {
2844 global $ilDB;
2845 $result_array = array();
2846 $result = $ilDB->queryF("SELECT * FROM svy_answer WHERE question_fi = %s AND active_fi = %s",
2847 array('integer','integer'),
2848 array($question_id, $active_id)
2849 );
2850 if ($result->numRows() >= 1)
2851 {
2852 while ($row = $ilDB->fetchAssoc($result))
2853 {
2854 array_push($result_array, $row);
2855 }
2856 return $result_array;
2857 }
2858 else
2859 {
2860 return $result_array;
2861 }
2862 }
2863
2870 function startSurvey($user_id, $anonymous_id, $appraisee_id)
2871 {
2872 global $ilDB;
2873
2874 if ($this->getAnonymize() && (strlen($anonymous_id) == 0)) return;
2875
2876 if (strcmp($user_id, "") == 0)
2877 {
2878 if ($user_id == ANONYMOUS_USER_ID)
2879 {
2880 $user_id = 0;
2881 }
2882 }
2883 $next_id = $ilDB->nextId('svy_finished');
2884 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_finished (finished_id, survey_fi, user_fi, anonymous_id, state, tstamp, appr_id) ".
2885 "VALUES (%s, %s, %s, %s, %s, %s, %s)",
2886 array('integer','integer','integer','text','text','integer','integer'),
2887 array($next_id, $this->getSurveyId(), $user_id, $anonymous_id, 0, time(), $appraisee_id)
2888 );
2889 return $next_id;
2890 }
2891
2898 function finishSurvey($finished_id)
2899 {
2900 global $ilDB;
2901
2902 $ilDB->manipulateF("UPDATE svy_finished SET state = %s, tstamp = %s".
2903 " WHERE survey_fi = %s AND finished_id = %s",
2904 array('text','integer','integer','integer'),
2905 array(1, time(), $this->getSurveyId(), $finished_id)
2906 );
2907
2908 $this->checkTutorNotification();
2909 }
2910
2918 function setPage($finished_id, $page_id)
2919 {
2920 global $ilDB;
2921
2922 $affectedRows = $ilDB->manipulateF("UPDATE svy_finished SET lastpage = %s WHERE finished_id = %s",
2923 array('integer','integer'),
2924 array(($page_id) ? $page_id : 0, $finished_id)
2925 );
2926 }
2927
2928 function sendNotificationMail($user_id, $anonymize_id, $appr_id)
2929 {
2930 include_once "./Services/User/classes/class.ilObjUser.php";
2931 include_once "./Services/User/classes/class.ilUserUtil.php";
2932
2933 // #12755
2934 $placeholders = array(
2935 "FIRST_NAME" => "firstname",
2936 "LAST_NAME" => "lastname",
2937 "LOGIN" => "login",
2938 // old style
2939 "firstname" => "firstname"
2940 );
2941
2942 $recipients = preg_split('/,/', $this->mailaddresses);
2943 foreach ($recipients as $recipient)
2944 {
2945 // #11298
2946 include_once "./Services/Notification/classes/class.ilSystemNotification.php";
2947 $ntf = new ilSystemNotification();
2948 $ntf->setLangModules(array("survey"));
2949 $ntf->setRefId($this->getRefId());
2950 $ntf->setSubjectLangId('finished_mail_subject');
2951
2952 $messagetext = $this->mailparticipantdata;
2953 if(trim($messagetext))
2954 {
2955 if (!$this->hasAnonymizedResults())
2956 {
2957 $data = ilObjUser::_getUserData(array($user_id));
2958 $data = $data[0];
2959 }
2960 foreach ($placeholders as $key => $mapping)
2961 {
2962 if ($this->hasAnonymizedResults()) // #16480
2963 {
2964 $messagetext = str_replace('[' . $key . ']', '', $messagetext);
2965 }
2966 else
2967 {
2968 $messagetext = str_replace('[' . $key . ']', trim($data[$mapping]), $messagetext);
2969 }
2970 }
2971 $ntf->setIntroductionDirect($messagetext);
2972 }
2973 else
2974 {
2975 $ntf->setIntroductionLangId('survey_notification_finished_introduction');
2976 }
2977
2978 // 360°? add appraisee data
2979 if($appr_id)
2980 {
2981 $ntf->addAdditionalInfo('survey_360_appraisee',
2983 }
2984
2985 $active_id = $this->getActiveID($user_id, $anonymize_id, $appr_id);
2986 $ntf->addAdditionalInfo('results',
2987 $this->getParticipantTextResults($active_id), true);
2988
2989 $ntf->setGotoLangId('survey_notification_tutor_link');
2990 $ntf->setReasonLangId('survey_notification_finished_reason');
2991
2992 $ntf->sendMail(array($recipient), null, null);
2993 }
2994 }
2995
2996 protected function getParticipantTextResults($active_id)
2997 {
2998 $textresult = "";
2999 $userResults =& $this->getUserSpecificResults(array($active_id));
3000 $questions =& $this->getSurveyQuestions(true);
3001 $questioncounter = 1;
3002 foreach ($questions as $question_id => $question_data)
3003 {
3004 $textresult .= $questioncounter++ . ". " . $question_data["title"] . "\n";
3005 $found = $userResults[$question_id][$active_id];
3006 $text = "";
3007 if (is_array($found))
3008 {
3009 $text = implode("\n", $found);
3010 }
3011 else
3012 {
3013 $text = $found;
3014 }
3015 if (strlen($text) == 0) $text = self::getSurveySkippedValue();
3016 $text = str_replace("<br />", "\n", $text);
3017 $textresult .= $text . "\n\n";
3018 }
3019 return $textresult;
3020 }
3021
3029 function isSurveyStarted($user_id, $anonymize_id, $appr_id = 0)
3030 {
3031 global $ilDB;
3032
3033 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
3034 if($anonymize_id)
3035 {
3036 $result = $ilDB->queryF("SELECT * FROM svy_finished".
3037 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3038 array('integer','text','integer'),
3039 array($this->getSurveyId(), $anonymize_id, $appr_id)
3040 );
3041 }
3042 else
3043 {
3044 $result = $ilDB->queryF("SELECT * FROM svy_finished".
3045 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3046 array('integer','integer','integer'),
3047 array($this->getSurveyId(), $user_id, $appr_id)
3048 );
3049 }
3050 if ($result->numRows() == 0)
3051 {
3052 return false;
3053 }
3054 else
3055 {
3056 $row = $ilDB->fetchAssoc($result);
3057 // yes, we are doing it this way
3058 $_SESSION["finished_id"][$this->getId()] = $row["finished_id"];
3059
3060 return (int)$row["state"];
3061 }
3062 }
3063
3071 function getActiveID($user_id, $anonymize_id, $appr_id)
3072 {
3073 global $ilDB;
3074
3075 // see self::isSurveyStarted()
3076
3077 // #15031 - should not matter if code was used by registered or anonymous (each code must be unique)
3078 if($anonymize_id)
3079 {
3080 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3081 " WHERE survey_fi = %s AND anonymous_id = %s AND appr_id = %s",
3082 array('integer','text','integer'),
3083 array($this->getSurveyId(), $anonymize_id, $appr_id)
3084 );
3085 }
3086 else
3087 {
3088 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished".
3089 " WHERE survey_fi = %s AND user_fi = %s AND appr_id = %s",
3090 array('integer','integer','integer'),
3091 array($this->getSurveyId(), $user_id, $appr_id)
3092 );
3093 }
3094 if ($result->numRows() == 0)
3095 {
3096 return false;
3097 }
3098 else
3099 {
3100 $row = $ilDB->fetchAssoc($result);
3101 return $row["finished_id"];
3102 }
3103 }
3104
3112 function getLastActivePage($active_id)
3113 {
3114 global $ilDB;
3115 $result = $ilDB->queryF("SELECT lastpage FROM svy_finished WHERE finished_id = %s",
3116 array('integer'),
3117 array($active_id)
3118 );
3119 if ($result->numRows() == 0)
3120 {
3121 return "";
3122 }
3123 else
3124 {
3125 $row = $ilDB->fetchAssoc($result);
3126 return ($row["lastpage"]) ? $row["lastpage"] : '';
3127 }
3128 }
3129
3138 function checkConstraint($constraint_data, $working_data)
3139 {
3140 if (count($working_data) == 0)
3141 {
3142 return 0;
3143 }
3144
3145 if ((count($working_data) == 1) and (strcmp($working_data[0]["value"], "") == 0))
3146 {
3147 return 0;
3148 }
3149
3150 $found = false;
3151 foreach ($working_data as $data)
3152 {
3153 switch ($constraint_data["short"])
3154 {
3155 case "<":
3156 if ($data["value"] < $constraint_data["value"])
3157 {
3158 $found = true;
3159 }
3160 break;
3161
3162 case "<=":
3163 if ($data["value"] <= $constraint_data["value"])
3164 {
3165 $found = true;
3166 }
3167 break;
3168
3169 case "=":
3170 if ($data["value"] == $constraint_data["value"])
3171 {
3172 $found = true;
3173 }
3174 break;
3175
3176 case "<>":
3177 if ($data["value"] <> $constraint_data["value"])
3178 {
3179 $found = true;
3180 }
3181 break;
3182
3183 case ">=":
3184 if ($data["value"] >= $constraint_data["value"])
3185 {
3186 $found = true;
3187 }
3188 break;
3189
3190 case ">":
3191 if ($data["value"] > $constraint_data["value"])
3192 {
3193 $found = true;
3194 }
3195 break;
3196 }
3197 if ($found)
3198 {
3199 break;
3200 }
3201 }
3202
3203 return (int)$found;
3204 }
3205
3206 static function _hasDatasets($survey_id)
3207 {
3208 global $ilDB;
3209
3210 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s",
3211 array('integer'),
3212 array($survey_id)
3213 );
3214 return ($result->numRows()) ? true : false;
3215 }
3216
3224 {
3225 global $ilDB, $ilLog;
3226
3227 $users = array();
3228 $result = $ilDB->queryF("SELECT * FROM svy_finished WHERE survey_fi = %s",
3229 array('integer'),
3230 array($this->getSurveyId())
3231 );
3232 if ($result->numRows())
3233 {
3234 while ($row = $ilDB->fetchAssoc($result))
3235 {
3236 array_push($users, $row["finished_id"]);
3237 }
3238 }
3239 return $users;
3240 }
3241
3248 function getUserSpecificResults($finished_ids)
3249 {
3250 $evaluation = array();
3251
3252 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3253 foreach (array_keys($this->getSurveyQuestions()) as $question_id)
3254 {
3255 // get question instance
3256 $question_type = SurveyQuestion::_getQuestionType($question_id);
3257 SurveyQuestion::_includeClass($question_type);
3258 $question = new $question_type();
3259 $question->loadFromDb($question_id);
3260
3261 $q_eval = SurveyQuestion::_instanciateQuestionEvaluation($question_id, $finished_ids);
3262 $q_res = $q_eval->getResults();
3263
3264 $data = array();
3265 foreach($finished_ids as $user_id)
3266 {
3267 $data[$user_id] = $q_eval->parseUserSpecificResults($q_res, $user_id);
3268 }
3269
3270 $evaluation[$question_id] = $data;
3271 }
3272
3273 return $evaluation;
3274 }
3275
3283 function getUserDataFromActiveId($active_id, $force_non_anonymous = false)
3284 {
3285 global $ilDB;
3286
3287 $surveySetting = new ilSetting("survey");
3288 $use_anonymous_id = array_key_exists("use_anonymous_id", $_GET) ? $_GET["use_anonymous_id"] : $surveySetting->get("use_anonymous_id");
3289 $result = $ilDB->queryF("SELECT * FROM svy_finished WHERE finished_id = %s",
3290 array('integer'),
3291 array($active_id)
3292 );
3293 $row = array();
3294 $foundrows = $result->numRows();
3295 if ($foundrows)
3296 {
3297 $row = $ilDB->fetchAssoc($result);
3298 }
3299 $name = ($use_anonymous_id) ? $row["anonymous_id"] : $this->lng->txt("anonymous");
3300 $userdata = array(
3301 "fullname" => $name,
3302 "sortname" => $name,
3303 "firstname" => "",
3304 "lastname" => "",
3305 "login" => "",
3306 "gender" => "",
3307 "active_id" => "$active_id"
3308 );
3309 if ($foundrows)
3310 {
3311 if (($row["user_fi"] > 0) &&
3312 (($row["user_fi"] != ANONYMOUS_USER_ID &&
3313 !$this->hasAnonymizedResults() &&
3314 !$this->get360Mode()) || // 360° uses ANONYMIZE_CODE_ALL which is wrong - see ilObjSurveyGUI::afterSave()
3315 (bool)$force_non_anonymous))
3316 {
3317 include_once './Services/User/classes/class.ilObjUser.php';
3318 if (strlen(ilObjUser::_lookupLogin($row["user_fi"])) == 0)
3319 {
3320 $userdata["fullname"] = $userdata["sortname"] = $this->lng->txt("deleted_user");
3321 }
3322 else
3323 {
3324 $user = new ilObjUser($row["user_fi"]);
3325 $userdata["fullname"] = $user->getFullname();
3326 $gender = $user->getGender();
3327 if (strlen($gender) == 1) $gender = $this->lng->txt("gender_$gender");
3328 $userdata["gender"] = $gender;
3329 $userdata["firstname"] = $user->getFirstname();
3330 $userdata["lastname"] = $user->getLastname();
3331 $userdata["sortname"] = $user->getLastname() . ", " . $user->getFirstname();
3332 $userdata["login"] = $user->getLogin();
3333 }
3334 }
3335 }
3336 return $userdata;
3337 }
3338
3348 function &getEvaluationByUser($questions, $active_id)
3349 {
3350 global $ilDB;
3351
3352 // collect all answers
3353 $answers = array();
3354 $result = $ilDB->queryF("SELECT * FROM svy_answer WHERE active_fi = %s",
3355 array('integer'),
3356 array($active_id)
3357 );
3358 while ($row = $ilDB->fetchAssoc($result))
3359 {
3360 if (!is_array($answers[$row["question_fi"]]))
3361 {
3362 $answers[$row["question_fi"]] = array();
3363 }
3364 array_push($answers[$row["question_fi"]], $row);
3365 }
3366 $userdata = $this->getUserDataFromActiveId($active_id);
3367 $resultset = array(
3368 "name" => $userdata["fullname"],
3369 "firstname" => $userdata["firstname"],
3370 "lastname" => $userdata["lastname"],
3371 "login" => $userdata["login"],
3372 "gender" => $userdata["gender"],
3373 "answers" => array()
3374 );
3375 foreach ($questions as $key => $question)
3376 {
3377 if (array_key_exists($key, $answers))
3378 {
3379 $resultset["answers"][$key] = $answers[$key];
3380 }
3381 else
3382 {
3383 $resultset["answers"][$key] = array();
3384 }
3385 sort($resultset["answers"][$key]);
3386 }
3387 return $resultset;
3388 }
3389
3395 function getQuestionsTable($arrFilter)
3396 {
3397 global $ilUser;
3398 global $ilDB;
3399 $where = "";
3400 if (is_array($arrFilter))
3401 {
3402 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title']))
3403 {
3404 $where .= " AND " . $ilDB->like('svy_question.title', 'text', "%%" . $arrFilter['title'] . "%%");
3405 }
3406 if (array_key_exists('description', $arrFilter) && strlen($arrFilter['description']))
3407 {
3408 $where .= " AND " . $ilDB->like('svy_question.description', 'text', "%%" . $arrFilter['description'] . "%%");
3409 }
3410 if (array_key_exists('author', $arrFilter) && strlen($arrFilter['author']))
3411 {
3412 $where .= " AND " . $ilDB->like('svy_question.author', 'text', "%%" . $arrFilter['author'] . "%%");
3413 }
3414 if (array_key_exists('type', $arrFilter) && strlen($arrFilter['type']))
3415 {
3416 $where .= " AND svy_qtype.type_tag = " . $ilDB->quote($arrFilter['type'], 'text');
3417 }
3418 if (array_key_exists('spl', $arrFilter) && strlen($arrFilter['spl']))
3419 {
3420 $where .= " AND svy_question.obj_fi = " . $ilDB->quote($arrFilter['spl'], 'integer');
3421 }
3422 }
3423
3424 $spls =& $this->getAvailableQuestionpools($use_obj_id = TRUE, $could_be_offline = FALSE, $showPath = FALSE);
3425 $forbidden = "";
3426 $forbidden = " AND " . $ilDB->in('svy_question.obj_fi', array_keys($spls), false, 'integer');
3427 $forbidden .= " AND svy_question.complete = " . $ilDB->quote("1", 'text');
3428 $existing = "";
3429 $existing_questions =& $this->getExistingQuestions();
3430 if (count($existing_questions))
3431 {
3432 $existing = " AND " . $ilDB->in('svy_question.question_id', $existing_questions, true, 'integer');
3433 }
3434
3435 include_once "./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPool.php";
3437
3438 $query_result = $ilDB->query("SELECT svy_question.*, svy_qtype.type_tag, svy_qtype.plugin, object_reference.ref_id".
3439 " FROM svy_question, svy_qtype, object_reference".
3440 " WHERE svy_question.original_id IS NULL".$forbidden.$existing.
3441 " AND svy_question.obj_fi = object_reference.obj_id AND svy_question.tstamp > 0".
3442 " AND svy_question.questiontype_fi = svy_qtype.questiontype_id " . $where);
3443
3444 $rows = array();
3445 if ($query_result->numRows())
3446 {
3447 while ($row = $ilDB->fetchAssoc($query_result))
3448 {
3449 if (array_key_exists('spl_txt', $arrFilter) && strlen($arrFilter['spl_txt']))
3450 {
3451 if(!stristr($spls[$row["obj_fi"]], $arrFilter['spl_txt']))
3452 {
3453 continue;
3454 }
3455 }
3456
3457 $row['ttype'] = $trans[$row['type_tag']];
3458 if ($row["plugin"])
3459 {
3460 if ($this->isPluginActive($row["type_tag"]))
3461 {
3462 array_push($rows, $row);
3463 }
3464 }
3465 else
3466 {
3467 array_push($rows, $row);
3468 }
3469 }
3470 }
3471 return $rows;
3472 }
3473
3479 function getQuestionblocksTable($arrFilter)
3480 {
3481 global $ilUser, $ilDB;
3482
3483 $where = "";
3484 if (is_array($arrFilter))
3485 {
3486 if (array_key_exists('title', $arrFilter) && strlen($arrFilter['title']))
3487 {
3488 $where .= " AND " . $ilDB->like('svy_qblk.title', 'text', "%%" . $arrFilter['title'] . "%%");
3489 }
3490 }
3491
3492 $query_result = $ilDB->query("SELECT svy_qblk.*, svy_svy.obj_fi FROM svy_qblk , svy_qblk_qst, svy_svy WHERE ".
3493 "svy_qblk.questionblock_id = svy_qblk_qst.questionblock_fi AND svy_svy.survey_id = svy_qblk_qst.survey_fi ".
3494 "$where GROUP BY svy_qblk.questionblock_id, svy_qblk.title, svy_qblk.show_questiontext, svy_qblk.show_blocktitle, ".
3495 "svy_qblk.owner_fi, svy_qblk.tstamp, svy_svy.obj_fi");
3496 $rows = array();
3497 if ($query_result->numRows())
3498 {
3499 $survey_ref_ids = ilUtil::_getObjectsByOperations("svy", "write");
3500 $surveytitles = array();
3501 foreach ($survey_ref_ids as $survey_ref_id)
3502 {
3503 $survey_id = ilObject::_lookupObjId($survey_ref_id);
3504 $surveytitles[$survey_id] = ilObject::_lookupTitle($survey_id);
3505 }
3506 while ($row = $ilDB->fetchAssoc($query_result))
3507 {
3508 $questions_array =& $this->getQuestionblockQuestions($row["questionblock_id"]);
3509 $counter = 1;
3510 foreach ($questions_array as $key => $value)
3511 {
3512 $questions_array[$key] = "$counter. $value";
3513 $counter++;
3514 }
3515 if (strlen($surveytitles[$row["obj_fi"]])) // only questionpools which are not in trash
3516 {
3517 $rows[$row["questionblock_id"]] = array(
3518 "questionblock_id" => $row["questionblock_id"],
3519 "title" => $row["title"],
3520 "svy" => $surveytitles[$row["obj_fi"]],
3521 "contains" => join($questions_array, ", "),
3522 "owner" => $row["owner_fi"]
3523 );
3524 }
3525 }
3526 }
3527 return $rows;
3528 }
3529
3536 function toXML()
3537 {
3538 include_once("./Services/Xml/classes/class.ilXmlWriter.php");
3539 $a_xml_writer = new ilXmlWriter;
3540 // set xml header
3541 $a_xml_writer->xmlHeader();
3542 $attrs = array(
3543 "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
3544 "xsi:noNamespaceSchemaLocation" => "http://www.ilias.de/download/xsd/ilias_survey_4_2.xsd"
3545 );
3546 $a_xml_writer->xmlStartTag("surveyobject", $attrs);
3547 $attrs = array(
3548 "id" => $this->getSurveyId(),
3549 "title" => $this->getTitle()
3550 );
3551 $a_xml_writer->xmlStartTag("survey", $attrs);
3552
3553 $a_xml_writer->xmlElement("description", NULL, $this->getDescription());
3554 $a_xml_writer->xmlElement("author", NULL, $this->getAuthor());
3555 $a_xml_writer->xmlStartTag("objectives");
3556 $attrs = array(
3557 "label" => "introduction"
3558 );
3559 $this->addMaterialTag($a_xml_writer, $this->getIntroduction(), TRUE, TRUE, $attrs);
3560 $attrs = array(
3561 "label" => "outro"
3562 );
3563 $this->addMaterialTag($a_xml_writer, $this->getOutro(), TRUE, TRUE, $attrs);
3564 $a_xml_writer->xmlEndTag("objectives");
3565
3566 if ($this->getAnonymize())
3567 {
3568 $attribs = array("enabled" => "1");
3569 }
3570 else
3571 {
3572 $attribs = array("enabled" => "0");
3573 }
3574 $a_xml_writer->xmlElement("anonymisation", $attribs);
3575 $a_xml_writer->xmlStartTag("restrictions");
3576 if ($this->getAnonymize() == 2)
3577 {
3578 $attribs = array("type" => "free");
3579 }
3580 else
3581 {
3582 $attribs = array("type" => "restricted");
3583 }
3584 $a_xml_writer->xmlElement("access", $attribs);
3585 if ($this->getStartDate())
3586 {
3587 $attrs = array("type" => "date");
3588 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getStartDate(), $matches);
3589 $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]));
3590 }
3591 if ($this->getEndDate())
3592 {
3593 $attrs = array("type" => "date");
3594 preg_match("/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/", $this->getEndDate(), $matches);
3595 $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]));
3596
3597 }
3598 $a_xml_writer->xmlEndTag("restrictions");
3599
3600 // constraints
3601 $pages =& $this->getSurveyPages();
3602 $hasconstraints = FALSE;
3603 foreach ($pages as $question_array)
3604 {
3605 foreach ($question_array as $question)
3606 {
3607 if (count($question["constraints"]))
3608 {
3609 $hasconstraints = TRUE;
3610 }
3611 }
3612 }
3613
3614 if ($hasconstraints)
3615 {
3616 $a_xml_writer->xmlStartTag("constraints");
3617 foreach ($pages as $question_array)
3618 {
3619 foreach ($question_array as $question)
3620 {
3621 if (count($question["constraints"]))
3622 {
3623 // found constraints
3624 foreach ($question["constraints"] as $constraint)
3625 {
3626 $attribs = array(
3627 "sourceref" => $question["question_id"],
3628 "destref" => $constraint["question"],
3629 "relation" => $constraint["short"],
3630 "value" => $constraint["value"],
3631 "conjunction" => $constraint["conjunction"]
3632 );
3633 $a_xml_writer->xmlElement("constraint", $attribs);
3634 }
3635 }
3636 }
3637 }
3638 $a_xml_writer->xmlEndTag("constraints");
3639 }
3640
3641 // add the rest of the preferences in qtimetadata tags, because there is no correspondent definition in QTI
3642 $a_xml_writer->xmlStartTag("metadata");
3643
3644 $custom_properties = array();
3645 $custom_properties["evaluation_access"] = $this->getEvaluationAccess();
3646 $custom_properties["status"] = $this->getStatus();
3647 $custom_properties["display_question_titles"] = $this->getShowQuestionTitles();
3648 $custom_properties["pool_usage"] = (int)$this->getPoolUsage();
3649
3650 $custom_properties["own_results_view"] = (int)$this->hasViewOwnResults();
3651 $custom_properties["own_results_mail"] = (int)$this->hasMailOwnResults();
3652 $custom_properties["confirmation_mail"] = (int)$this->hasMailConfirmation();
3653
3654 $custom_properties["anon_user_list"] = (int)$this->hasAnonymousUserList();
3655
3656 $custom_properties["mode_360"] = (int)$this->get360Mode();
3657 $custom_properties["mode_360_self_eval"] = (int)$this->get360SelfEvaluation();
3658 $custom_properties["mode_360_self_rate"] = (int)$this->get360SelfRaters();
3659 $custom_properties["mode_360_self_appr"] = (int)$this->get360SelfAppraisee();
3660 $custom_properties["mode_360_results"] = $this->get360Results();
3661 $custom_properties["mode_360_skill_service"] = (int)$this->get360SkillService();
3662
3663
3664 // :TODO: skills?
3665
3666 // reminder/tutor notification are (currently?) not exportable
3667
3668 foreach($custom_properties as $label => $value)
3669 {
3670 $a_xml_writer->xmlStartTag("metadatafield");
3671 $a_xml_writer->xmlElement("fieldlabel", NULL, $label);
3672 $a_xml_writer->xmlElement("fieldentry", NULL, $value);
3673 $a_xml_writer->xmlEndTag("metadatafield");
3674 }
3675
3676 $a_xml_writer->xmlStartTag("metadatafield");
3677 $a_xml_writer->xmlElement("fieldlabel", NULL, "SCORM");
3678 include_once "./Services/MetaData/classes/class.ilMD.php";
3679 $md = new ilMD($this->getId(),0, $this->getType());
3680 $writer = new ilXmlWriter();
3681 $md->toXml($writer);
3682 $metadata = $writer->xmlDumpMem();
3683 $a_xml_writer->xmlElement("fieldentry", NULL, $metadata);
3684 $a_xml_writer->xmlEndTag("metadatafield");
3685
3686 $a_xml_writer->xmlEndTag("metadata");
3687 $a_xml_writer->xmlEndTag("survey");
3688
3689 $attribs = array("id" => $this->getId());
3690 $a_xml_writer->xmlStartTag("surveyquestions", $attribs);
3691 // add questionblock descriptions
3692 foreach ($pages as $question_array)
3693 {
3694 if (count($question_array) > 1)
3695 {
3696 $attribs = array("id" => $question_array[0]["question_id"]);
3697 $attribs = array("showQuestiontext" => $question_array[0]["questionblock_show_questiontext"],
3698 "showBlocktitle" => $question_array[0]["questionblock_show_blocktitle"]);
3699 $a_xml_writer->xmlStartTag("questionblock", $attribs);
3700 if (strlen($question_array[0]["questionblock_title"]))
3701 {
3702 $a_xml_writer->xmlElement("questionblocktitle", NULL, $question_array[0]["questionblock_title"]);
3703 }
3704 }
3705 foreach ($question_array as $question)
3706 {
3707 if (strlen($question["heading"]))
3708 {
3709 $a_xml_writer->xmlElement("textblock", NULL, $question["heading"]);
3710 }
3711 $questionObject = self::_instanciateQuestion($question["question_id"]);
3712 //questionObject contains all the fields from the database. (loadFromDb)
3713 //we don't need the value from svy_qst_oblig table, we already have the values from svy_question table.
3714 //if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE, $obligatory_states[$question["question_id"]]);
3715 if ($questionObject !== FALSE) $questionObject->insertXML($a_xml_writer, FALSE);
3716 }
3717 if (count($question_array) > 1)
3718 {
3719 $a_xml_writer->xmlEndTag("questionblock");
3720 }
3721 }
3722
3723 $a_xml_writer->xmlEndTag("surveyquestions");
3724 $a_xml_writer->xmlEndTag("surveyobject");
3725 $xml = $a_xml_writer->xmlDumpMem(FALSE);
3726 return $xml;
3727 }
3728
3736 static function _instanciateQuestion($question_id)
3737 {
3738 if ($question_id < 1) return FALSE;
3739 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
3740 $question_type = SurveyQuestion::_getQuestionType($question_id);
3741 if (strlen($question_type) == 0) return FALSE;
3742 SurveyQuestion::_includeClass($question_type);
3743 $question = new $question_type();
3744 $question->loadFromDb($question_id);
3745 return $question;
3746 }
3747
3754 function locateImportFiles($a_dir)
3755 {
3756 if (!is_dir($a_dir) || is_int(strpos($a_dir, "..")))
3757 {
3758 return;
3759 }
3760 $importDirectory = "";
3761 $xmlFile = "";
3762
3763 $current_dir = opendir($a_dir);
3764 $files = array();
3765 while($entryname = readdir($current_dir))
3766 {
3767 $files[] = $entryname;
3768 }
3769
3770 foreach($files as $file)
3771 {
3772 if(is_dir($a_dir."/".$file) and ($file != "." and $file!=".."))
3773 {
3774 // found directory created by zip
3775 $importDirectory = $a_dir."/".$file;
3776 }
3777 }
3778 closedir($current_dir);
3779 if (strlen($importDirectory))
3780 {
3781 // find the xml file
3782 $current_dir = opendir($importDirectory);
3783 $files = array();
3784 while($entryname = readdir($current_dir))
3785 {
3786 $files[] = $entryname;
3787 }
3788 foreach($files as $file)
3789 {
3790 if(@is_file($importDirectory."/".$file) &&
3791 ($file != "." && $file!="..") &&
3792 (preg_match("/^[0-9]{10}__[0-9]+__(svy_)*[0-9]+\.[A-Za-z]{1,3}$/", $file) ||
3793 preg_match("/^[0-9]{10}__[0-9]+__(survey__)*[0-9]+\.[A-Za-z]{1,3}$/", $file)))
3794 {
3795 // found xml file
3796 $xmlFile = $importDirectory."/".$file;
3797 }
3798 }
3799 }
3800 return array("dir" => $importDirectory, "xml" => $xmlFile);
3801 }
3802
3811 function importObject($file_info, $svy_qpl_id)
3812 {
3813 if ($svy_qpl_id < 1) $svy_qpl_id = -1;
3814 // check if file was uploaded
3815 $source = $file_info["tmp_name"];
3816 $error = "";
3817 if (($source == 'none') || (!$source) || $file_info["error"] > UPLOAD_ERR_OK)
3818 {
3819 $error = $this->lng->txt("import_no_file_selected");
3820 }
3821 // check correct file type
3822 $isXml = FALSE;
3823 $isZip = FALSE;
3824 if ((strcmp($file_info["type"], "text/xml") == 0) || (strcmp($file_info["type"], "application/xml") == 0))
3825 {
3826 $this->log->debug("isXML");
3827 $isXml = TRUE;
3828 }
3829 // too many different mime-types, so we use the suffix
3830 $suffix = pathinfo($file_info["name"]);
3831 if (strcmp(strtolower($suffix["extension"]), "zip") == 0)
3832 {
3833 $this->log->debug("isZip");
3834 $isZip = TRUE;
3835 }
3836 if (!$isXml && !$isZip)
3837 {
3838 $error = $this->lng->txt("import_wrong_file_type");
3839 $this->log->debug("Survey: Import error. Filetype was \"" . $file_info["type"] ."\"");
3840 }
3841 if (strlen($error) == 0)
3842 {
3843 // import file as a survey
3844 $import_dir = $this->getImportDirectory();
3845 $import_subdir = "";
3846 $importfile = "";
3847 if ($isZip)
3848 {
3849 $importfile = $import_dir."/".$file_info["name"];
3850 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3851 ilUtil::unzip($importfile);
3852 $found = $this->locateImportFiles($import_dir);
3853 if (!((strlen($found["dir"]) > 0) && (strlen($found["xml"]) > 0)))
3854 {
3855 $error = $this->lng->txt("wrong_import_file_structure");
3856 return $error;
3857 }
3858 $importfile = $found["xml"];
3859 $import_subdir = $found["dir"];
3860 }
3861 else
3862 {
3863 $importfile = tempnam($import_dir, "survey_import");
3864 ilUtil::moveUploadedFile($source, $file_info["name"], $importfile);
3865 }
3866
3867 $this->log->debug("Import file = $importfile");
3868 $this->log->debug("Import subdir = $import_subdir");
3869
3870 $fh = fopen($importfile, "r");
3871 if (!$fh)
3872 {
3873 $error = $this->lng->txt("import_error_opening_file");
3874 return $error;
3875 }
3876 $xml = fread($fh, filesize($importfile));
3877 $result = fclose($fh);
3878 if (!$result)
3879 {
3880 $error = $this->lng->txt("import_error_closing_file");
3881 return $error;
3882 }
3883
3884 unset($_SESSION["import_mob_xhtml"]);
3885 if (strpos($xml, "questestinterop"))
3886 {
3887 include_once("./Modules/Survey/exceptions/class.ilInvalidSurveyImportFileException.php");
3888 throw new ilInvalidSurveyImportFileException("Unsupported survey version (< 3.8) found.");
3889 /*
3890 include_once "./Services/Survey/classes/class.SurveyImportParserPre38.php";
3891 $import = new SurveyImportParserPre38($svy_qpl_id, "", TRUE);
3892 $import->setSurveyObject($this);
3893 $import->setXMLContent($xml);
3894 $import->startParsing();*/
3895 }
3896 else
3897 {
3898 $this->log->debug("survey id = ".$this->getId());
3899 $this->log->debug("question pool id = ".$svy_qpl_id);
3900
3901 include_once("./Services/Export/classes/class.ilImport.php");
3902 $imp = new ilImport();
3903 $config = $imp->getConfig("Modules/Survey");
3904 $config->setQuestionPoolID($svy_qpl_id);
3905 $imp->getMapping()->addMapping("Modules/Survey", "svy", 0, $this->getId());
3906 $imp->importFromDirectory($import_subdir, "svy", "Modules/Survey");
3907 $this->log->debug("config(Modules/survey)->getQuestionPoolId =".$config->getQuestionPoolID());
3908 return "";
3909
3910 //old code
3911 include_once "./Services/Survey/classes/class.SurveyImportParser.php";
3912 $import = new SurveyImportParser($svy_qpl_id, "", TRUE);
3913 $import->setSurveyObject($this);
3914 $import->setXMLContent($xml);
3915 $import->startParsing();
3916 }
3917
3918 if (is_array($_SESSION["import_mob_xhtml"]))
3919 {
3920 include_once "./Services/MediaObjects/classes/class.ilObjMediaObject.php";
3921 include_once "./Services/RTE/classes/class.ilRTE.php";
3922 include_once "./Modules/TestQuestionPool/classes/class.ilObjQuestionPool.php";
3923 foreach ($_SESSION["import_mob_xhtml"] as $mob)
3924 {
3925 $importfile = $import_subdir . "/" . $mob["uri"];
3926 if (file_exists($importfile))
3927 {
3928 if (!$mob["type"])
3929 {
3930 $mob["type"] = "svy:html";
3931 }
3932
3933 $media_object = ilObjMediaObject::_saveTempFileAsMediaObject(basename($importfile), $importfile, FALSE);
3934
3935 // survey mob
3936 if ($mob["type"] == "svy:html")
3937 {
3938 ilObjMediaObject::_saveUsage($media_object->getId(), "svy:html", $this->getId());
3939 $this->setIntroduction(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getIntroduction()));
3940 $this->setOutro(str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $this->getOutro()));
3941 }
3942 // question mob
3943 else if($import->questions[$mob["id"]])
3944 {
3945 $new_qid = $import->questions[$mob["id"]];
3946 ilObjMediaObject::_saveUsage($media_object->getId(), $mob["type"], $new_qid);
3947 $new_question = SurveyQuestion::_instanciateQuestion($new_qid);
3948 $qtext = $new_question->getQuestiontext();
3949 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 0);
3950 $qtext = str_replace("src=\"" . $mob["mob"] . "\"", "src=\"" . "il_" . IL_INST_ID . "_mob_" . $media_object->getId() . "\"", $qtext);
3951 $qtext = ilRTE::_replaceMediaObjectImageSrc($qtext, 1);
3952 $new_question->setQuestiontext($qtext);
3953 $new_question->saveToDb();
3954
3955 // also fix existing original in pool
3956 if($new_question->getOriginalId())
3957 {
3958 $pool_question = SurveyQuestion::_instanciateQuestion($new_question->getOriginalId());
3959 $pool_question->setQuestiontext($qtext);
3960 $pool_question->saveToDb();
3961 }
3962 }
3963 }
3964 else
3965 {
3966 global $ilLog;
3967 $ilLog->write("Error: Could not open XHTML mob file for test introduction during test import. File $importfile does not exist!");
3968 }
3969 }
3972 $this->saveToDb();
3973 }
3974
3975 // delete import directory
3977 }
3978 return $error;
3979 }
3980
3989 public function cloneObject($a_target_id,$a_copy_id = 0, $a_omit_tree = false)
3990 {
3991 global $ilDB;
3992
3993 $this->loadFromDb();
3994
3995 // Copy settings
3996 $newObj = parent::cloneObject($a_target_id,$a_copy_id, $a_omit_tree);
3997 $this->cloneMetaData($newObj);
3998 $newObj->updateMetaData();
3999
4000 $newObj->setAuthor($this->getAuthor());
4001 $newObj->setIntroduction($this->getIntroduction());
4002 $newObj->setOutro($this->getOutro());
4003 $newObj->setEvaluationAccess($this->getEvaluationAccess());
4004 $newObj->setStartDate($this->getStartDate());
4005 $newObj->setEndDate($this->getEndDate());
4006 $newObj->setInvitation($this->getInvitation());
4007 $newObj->setInvitationMode($this->getInvitationMode());
4008 $newObj->setAnonymize($this->getAnonymize());
4009 $newObj->setShowQuestionTitles($this->getShowQuestionTitles());
4010 $newObj->setTemplate($this->getTemplate());
4011 $newObj->setPoolUsage($this->getPoolUsage());
4012 $newObj->setViewOwnResults($this->hasViewOwnResults());
4013 $newObj->setMailOwnResults($this->hasMailOwnResults());
4014 $newObj->setMailConfirmation($this->hasMailConfirmation());
4015 $newObj->setAnonymousUserList($this->hasAnonymousUserList());
4016
4017 // #12661
4018 if($this->get360Mode())
4019 {
4020 $newObj->set360Mode(true);
4021 $newObj->set360SelfEvaluation($this->get360SelfEvaluation());
4022 $newObj->set360SelfAppraisee($this->get360SelfAppraisee());
4023 $newObj->set360SelfRaters($this->get360SelfRaters());
4024 $newObj->set360Results($this->get360Results());
4025 $newObj->set360SkillService($this->get360SkillService());
4026 }
4027
4028 // reminder/notification
4029 $newObj->setReminderStatus($this->getReminderStatus());
4030 $newObj->setReminderStart($this->getReminderStart());
4031 $newObj->setReminderEnd($this->getReminderEnd());
4032 $newObj->setReminderFrequency($this->getReminderFrequency());
4033 $newObj->setReminderTarget($this->getReminderTarget());
4034 $newObj->setReminderTemplate($this->getReminderTemplate());
4035 // reminder_last_sent must not be copied!
4036 $newObj->setTutorNotificationStatus($this->getTutorNotificationStatus());
4037 $newObj->setTutorNotificationRecipients($this->getTutorNotificationRecipients());
4038 $newObj->setTutorNotificationTarget($this->getTutorNotificationTarget());
4039
4040 $question_pointer = array();
4041 // clone the questions
4042 $mapping = array();
4043 include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
4044
4045 foreach ($this->questions as $key => $question_id)
4046 {
4047 $question = self::_instanciateQuestion($question_id);
4048 if($question) // #10824
4049 {
4050 $question->id = -1;
4051 $original_id = SurveyQuestion::_getOriginalId($question_id, false);
4052 $question->saveToDb($original_id);
4053 $newObj->questions[$key] = $question->getId();
4054 $question_pointer[$question_id] = $question->getId();
4055 $mapping[$question_id] = $question->getId();
4056 }
4057 }
4058
4059 //copy online status if object is not the root copy object
4060 $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
4061
4062 if(!$cp_options->isRootNode($this->getRefId()))
4063 {
4064 $newObj->setStatus($this->isOnline()?self::STATUS_ONLINE: self::STATUS_OFFLINE);
4065 }
4066
4067 $newObj->saveToDb();
4068 $newObj->cloneTextblocks($mapping);
4069
4070 // #14929
4071 if($this->get360Mode() &&
4072 $this->get360SkillService())
4073 {
4074 include_once "./Modules/Survey/classes/class.ilSurveySkill.php";
4075 $src_skills = new ilSurveySkill($this);
4076 $tgt_skills = new ilSurveySkill($newObj);
4077
4078 foreach($mapping as $src_qst_id => $tgt_qst_id)
4079 {
4080 $qst_skill = $src_skills->getSkillForQuestion($src_qst_id);
4081 if($qst_skill)
4082 {
4083 $tgt_skills->addQuestionSkillAssignment($tgt_qst_id, $qst_skill["base_skill_id"], $qst_skill["tref_id"]);
4084 }
4085 }
4086 }
4087
4088 // clone the questionblocks
4089 $questionblocks = array();
4090 $questionblock_questions = array();
4091 $result = $ilDB->queryF("SELECT * FROM svy_qblk_qst WHERE survey_fi = %s",
4092 array('integer'),
4093 array($this->getSurveyId())
4094 );
4095 if ($result->numRows() > 0)
4096 {
4097 while ($row = $ilDB->fetchAssoc($result))
4098 {
4099 array_push($questionblock_questions, $row);
4100 $questionblocks[$row["questionblock_fi"]] = $row["questionblock_fi"];
4101 }
4102 }
4103 // create new questionblocks
4104 foreach ($questionblocks as $key => $value)
4105 {
4106 $questionblock = self::_getQuestionblock($key);
4107 $questionblock_id = self::_addQuestionblock($questionblock["title"], $questionblock["owner_fi"], $questionblock["show_questiontext"], $questionblock["show_blocktitle"]);
4108 $questionblocks[$key] = $questionblock_id;
4109 }
4110 // create new questionblock questions
4111 foreach ($questionblock_questions as $key => $value)
4112 {
4113 if($questionblocks[$value["questionblock_fi"]] &&
4114 $question_pointer[$value["question_fi"]])
4115 {
4116 $next_id = $ilDB->nextId('svy_qblk_qst');
4117 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_qblk_qst (qblk_qst_id, survey_fi, questionblock_fi, question_fi) ".
4118 "VALUES (%s, %s, %s, %s)",
4119 array('integer','integer','integer','integer'),
4120 array($next_id, $newObj->getSurveyId(), $questionblocks[$value["questionblock_fi"]], $question_pointer[$value["question_fi"]])
4121 );
4122 }
4123 }
4124
4125 // clone the constraints
4126 $constraints = self::_getConstraints($this->getSurveyId());
4127 $newConstraints = array();
4128 foreach ($constraints as $key => $constraint)
4129 {
4130 if ($question_pointer[$constraint["for_question"]] &&
4131 $question_pointer[$constraint["question"]])
4132 {
4133 if (!array_key_exists($constraint['id'], $newConstraints))
4134 {
4135 $constraint_id = $newObj->addConstraint($question_pointer[$constraint["question"]], $constraint["relation_id"], $constraint["value"], $constraint['conjunction']);
4136 $newConstraints[$constraint['id']] = $constraint_id;
4137 }
4138 $newObj->addConstraintToQuestion($question_pointer[$constraint["for_question"]], $newConstraints[$constraint['id']]);
4139 }
4140 }
4141
4142 // #16210 - clone LP settings
4143 include_once('./Services/Tracking/classes/class.ilLPObjSettings.php');
4144 $obj_settings = new ilLPObjSettings($this->getId());
4145 $obj_settings->cloneSettings($newObj->getId());
4146 unset($obj_settings);
4147
4148 return $newObj;
4149 }
4150
4151 function getTextblock($question_id)
4152 {
4153 global $ilDB;
4154 $result = $ilDB->queryF("SELECT * FROM svy_svy_qst WHERE question_fi = %s",
4155 array('integer'),
4156 array($question_id)
4157 );
4158 if ($result->numRows())
4159 {
4160 $row = $ilDB->fetchAssoc($result);
4161 return $row["heading"];
4162 }
4163 else
4164 {
4165 return "";
4166 }
4167 }
4168
4174 function cloneTextblocks($mapping)
4175 {
4176 foreach ($mapping as $original_id => $new_id)
4177 {
4178 $textblock = $this->getTextblock($original_id);
4179 include_once "./Services/AdvancedEditing/classes/class.ilObjAdvancedEditing.php";
4180 $this->saveHeading(ilUtil::stripSlashes($textblock, TRUE, ilObjAdvancedEditing::_getUsedHTMLTagsAsString("survey")), $new_id);
4181 }
4182 }
4183
4192 {
4193 $svy_data_dir = ilUtil::getDataDir()."/svy_data";
4194 ilUtil::makeDir($svy_data_dir);
4195 if(!is_writable($svy_data_dir))
4196 {
4197 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4198 throw new ilSurveyException("Survey Data Directory (".$svy_data_dir.") not writeable.");
4199 }
4200
4201 // create learning module directory (data_dir/lm_data/lm_<id>)
4202 $svy_dir = $svy_data_dir."/svy_".$this->getId();
4203 ilUtil::makeDir($svy_dir);
4204 if(!@is_dir($svy_dir))
4205 {
4206 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4207 throw new ilSurveyException("Creation of Survey Directory failed.");
4208 }
4209 // create Export subdirectory (data_dir/lm_data/lm_<id>/Export)
4210 $export_dir = $svy_dir."/export";
4211 ilUtil::makeDir($export_dir);
4212 if(!@is_dir($export_dir))
4213 {
4214 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4215 throw new ilSurveyException("Creation of Export Directory failed.");
4216 }
4217 }
4218
4223 {
4224 $export_dir = ilUtil::getDataDir()."/svy_data"."/svy_".$this->getId()."/export";
4225
4226 return $export_dir;
4227 }
4228
4237 {
4238 $svy_data_dir = ilUtil::getDataDir()."/svy_data";
4239 ilUtil::makeDir($svy_data_dir);
4240
4241 if(!is_writable($svy_data_dir))
4242 {
4243 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4244 throw new ilSurveyException("Survey Data Directory (".$svy_data_dir.") not writeable.");
4245 }
4246
4247 // create test directory (data_dir/svy_data/svy_<id>)
4248 $svy_dir = $svy_data_dir."/svy_".$this->getId();
4249 ilUtil::makeDir($svy_dir);
4250 if(!@is_dir($svy_dir))
4251 {
4252 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4253 throw new ilSurveyException("Creation of Survey Directory failed.");
4254 }
4255
4256 // create import subdirectory (data_dir/svy_data/svy_<id>/import)
4257 $import_dir = $svy_dir."/import";
4258 ilUtil::makeDir($import_dir);
4259 if(!@is_dir($import_dir))
4260 {
4261 include_once "Modules/Survey/exceptions/class.ilSurveyException.php";
4262 throw new ilSurveyException("Creation of Import Directory failed.");
4263 }
4264 }
4265
4270 {
4271 $import_dir = ilUtil::getDataDir()."/svy_data".
4272 "/svy_".$this->getId()."/import";
4273 if (!is_dir($import_dir))
4274 {
4275 ilUtil::makeDirParents($import_dir);
4276 }
4277 if(@is_dir($import_dir))
4278 {
4279 return $import_dir;
4280 }
4281 else
4282 {
4283 return false;
4284 }
4285 }
4286
4287 function saveHeading($heading = "", $insertbefore)
4288 {
4289 global $ilDB;
4290 if ($heading)
4291 {
4292 $affectedRows = $ilDB->manipulateF("UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4293 array('text','integer','integer'),
4294 array($heading, $this->getSurveyId(), $insertbefore)
4295 );
4296 }
4297 else
4298 {
4299 $affectedRows = $ilDB->manipulateF("UPDATE svy_svy_qst SET heading=%s WHERE survey_fi=%s AND question_fi=%s",
4300 array('text','integer','integer'),
4301 array(NULL, $this->getSurveyId(), $insertbefore)
4302 );
4303 }
4304 }
4305
4306 function isAnonymousKey($key)
4307 {
4308 global $ilDB;
4309
4310 $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_key = %s AND survey_fi = %s",
4311 array('text','integer'),
4312 array($key, $this->getSurveyId())
4313 );
4314 return ($result->numRows() == 1) ? true : false;
4315 }
4316
4317 function bindSurveyCodeToUser($user_id, $code)
4318 {
4319 global $ilDB;
4320
4321 if($user_id == ANONYMOUS_USER_ID)
4322 {
4323 return;
4324 }
4325
4326 if($this->checkSurveyCode($code))
4327 {
4328 $ilDB->manipulate("UPDATE svy_anonymous".
4329 " SET user_key = ".$ilDB->quote(md5($user_id), "text").
4330 " WHERE survey_key = ".$ilDB->quote($code, "text"));
4331 }
4332 }
4333
4335 {
4336 global $ilDB;
4337
4338 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE anonymous_id = %s AND survey_fi = %s",
4339 array('text','integer'),
4340 array($key, $this->getSurveyId())
4341 );
4342 return ($result->numRows() == 1) ? true : false;
4343 }
4344
4346 {
4347 if ($this->isAnonymousKey($code))
4348 {
4349 if ($this->isSurveyStarted("", $code) == 1)
4350 {
4351 return false;
4352 }
4353 else
4354 {
4355 return true;
4356 }
4357 }
4358 else
4359 {
4360 return false;
4361 }
4362 }
4363
4371 function getSurveyCodesForExport(array $a_codes = null, array $a_ids = null)
4372 {
4373 global $ilDB, $ilUser, $lng;
4374
4375 include_once "./Services/Link/classes/class.ilLink.php";
4376
4377 $sql = "SELECT svy_anonymous.*, svy_finished.state".
4378 " FROM svy_anonymous".
4379 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)".
4380 " WHERE svy_anonymous.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
4381 " AND svy_anonymous.user_key IS NULL";
4382
4383 if($a_codes)
4384 {
4385 $sql .= " AND ".$ilDB->in("svy_anonymous.survey_key", $a_codes, "", "text");
4386 }
4387 else if($a_ids)
4388 {
4389 $sql .= " AND ".$ilDB->in("svy_anonymous.anonymous_id", $a_ids, "", "text");
4390 }
4391
4392 $export = array();
4393
4394 // #14905
4395 $titles = array();
4396 $titles[] = '"'.$lng->txt("survey_code").'"';
4397 $titles[] = '"'.$lng->txt("email").'"';
4398 $titles[] = '"'.$lng->txt("lastname").'"';
4399 $titles[] = '"'.$lng->txt("firstname").'"';
4400 $titles[] = '"'.$lng->txt("create_date").'"';
4401 $titles[] = '"'.$lng->txt("used").'"';
4402 $titles[] = '"'.$lng->txt("mail_sent_short").'"';
4403 $titles[] = '"'.$lng->txt("survey_code_url").'"';
4404 $export[] = implode(";", $titles);
4405
4406 $result = $ilDB->query($sql);
4407 $default_lang = $ilUser->getPref("survey_code_language");
4408 while ($row = $ilDB->fetchAssoc($result))
4409 {
4410 $item = array();
4411 $item[] = $row["survey_key"];
4412
4413 if($row["externaldata"])
4414 {
4415 $ext = unserialize($row["externaldata"]);
4416 $item[] = $ext["email"];
4417 $item[] = $ext["lastname"];
4418 $item[] = $ext["firstname"];
4419 }
4420 else
4421 {
4422 $item[] = "";
4423 $item[] = "";
4424 $item[] = "";
4425 }
4426
4427 // No relative (today, tomorrow...) dates in export.
4428 $date = new ilDateTime($row['tstamp'],IL_CAL_UNIX);
4429 $item[] = $date->get(IL_CAL_DATETIME);
4430
4431 $item[] = ($this->isSurveyCodeUsed($row["survey_key"])) ? 1 : 0;
4432 $item[] = ($row["sent"]) ? 1 : 0;
4433
4434 $params = array("accesscode" => $row["survey_key"]);
4435 if ($default_lang)
4436 {
4437 $params["lang"] = $default_lang;
4438 }
4439 $item[] = ilLink::_getLink($this->getRefId(), "svy", $params);
4440
4441 $export[] = '"'.implode('";"', $item).'"';
4442 }
4443 return implode("\n", $export);
4444 }
4445
4453 public function getSurveyCodesTableData(array $ids = null, $lang = null)
4454 {
4455 global $ilDB;
4456
4457 include_once "./Services/Link/classes/class.ilLink.php";
4458
4459 $codes = array();
4460
4461 $sql = "SELECT svy_anonymous.*, svy_finished.state".
4462 " FROM svy_anonymous".
4463 " LEFT JOIN svy_finished ON (svy_anonymous.survey_key = svy_finished.anonymous_id)".
4464 " WHERE svy_anonymous.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer") /*.
4465 " AND svy_anonymous.user_key IS NULL" */; // #15860
4466
4467 if($ids)
4468 {
4469 $sql .= " AND ".$ilDB->in("svy_anonymous.anonymous_id", $ids, "", "integer");
4470 }
4471
4472 $sql .= " ORDER BY tstamp, survey_key ASC";
4473 $result = $ilDB->query($sql);
4474 if ($result->numRows() > 0)
4475 {
4476 while ($row = $ilDB->fetchAssoc($result))
4477 {
4478 $href = "";
4479 $used = false;
4480 if ($this->isSurveyCodeUsed($row["survey_key"]))
4481 {
4482 $used = true;
4483 }
4484 else
4485 {
4486 $params = array("accesscode" => $row["survey_key"]);
4487 if ($lang)
4488 {
4489 $params["lang"] = $lang;
4490 }
4491 $href = ilLink::_getLink($this->getRefId(), "svy", $params);
4492 }
4493
4494
4495 $item = array(
4496 'id' => $row["anonymous_id"],
4497 'code' => $row["survey_key"],
4498 'date' => $row["tstamp"],
4499 'used' => $used,
4500 'sent' => $row['sent'],
4501 'href' => $href,
4502 'email' => '',
4503 'last_name' => '',
4504 'first_name' => ''
4505 );
4506
4507 if($row["externaldata"])
4508 {
4509 $ext = unserialize($row["externaldata"]);
4510 $item['email'] = $ext['email'];
4511 $item['last_name'] = $ext['lastname'];
4512 $item['first_name'] = $ext['firstname'];
4513 }
4514
4515 array_push($codes, $item);
4516 }
4517 }
4518 return $codes;
4519 }
4520
4522 {
4523 global $ilDB;
4524 $result = $ilDB->queryF("SELECT finished_id FROM svy_finished WHERE survey_fi = %s AND anonymous_id = %s",
4525 array('integer','text'),
4526 array($this->getSurveyId(), $code)
4527 );
4528 return ($result->numRows() > 0) ? true : false;
4529 }
4530
4532 {
4533 global $ilDB;
4534 $result = $ilDB->queryF("SELECT anonymous_id FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4535 array('integer','text'),
4536 array($this->getSurveyId(), $code)
4537 );
4538 return ($result->numRows() > 0) ? false : true;
4539 }
4540
4541 function createSurveyCodes($nrOfCodes)
4542 {
4543 global $ilDB;
4544
4545 $res = array();
4546
4547 for ($i = 0; $i < $nrOfCodes; $i++)
4548 {
4549 $next_id = $ilDB->nextId('svy_anonymous');
4550 $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, tstamp) ".
4551 "VALUES (%s, %s, %s, %s)",
4552 array('integer','text','integer','integer'),
4553 array($next_id, $this->createNewAccessCode(), $this->getSurveyId(), time())
4554 );
4555 $res[] = $next_id;
4556 }
4557
4558 return $res;
4559 }
4560
4561 function importSurveyCode($a_anonymize_key, $a_created, $a_data)
4562 {
4563 global $ilDB;
4564
4565 $next_id = $ilDB->nextId('svy_anonymous');
4566 $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) ".
4567 "VALUES (%s, %s, %s, %s, %s)",
4568 array('integer','text','integer','text','integer'),
4569 array($next_id, $a_anonymize_key, $this->getSurveyId(), serialize($a_data), $a_created)
4570 );
4571 }
4572
4574 {
4575 global $ilDB;
4576
4577 $ids = array();
4578 foreach ($data as $dataset)
4579 {
4580 $anonymize_key = $this->createNewAccessCode();
4581 $next_id = $ilDB->nextId('svy_anonymous');
4582 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, externaldata, tstamp) ".
4583 "VALUES (%s, %s, %s, %s, %s)",
4584 array('integer','text','integer','text','integer'),
4585 array($next_id, $anonymize_key, $this->getSurveyId(), serialize($dataset), time())
4586 );
4587 $ids[] = $next_id;
4588 }
4589 return $ids;
4590 }
4591
4592 function sendCodes($not_sent, $subject, $message, $lang)
4593 {
4594 global $DIC;
4595 /*
4596 * 0 = all
4597 * 1 = not sent
4598 * 2 = finished
4599 * 3 = not finished
4600 */
4601 $check_finished = ($not_sent > 1);
4602
4603 include_once "./Services/Mail/classes/class.ilMail.php";
4604 include_once "./Services/Link/classes/class.ilLink.php";
4605
4606 #19956
4607 $user_id = $DIC->user()->getId();
4608 $mail = new ilMail($user_id);
4609 $recipients = $this->getExternalCodeRecipients($check_finished);
4610 foreach ($recipients as $data)
4611 {
4612 if($data['email'] && $data['code'])
4613 {
4614 $do_send = false;
4615 switch ((int)$not_sent)
4616 {
4617 case 1:
4618 $do_send = !(bool)$data['sent'];
4619 break;
4620
4621 case 2:
4622 $do_send = $data['finished'];
4623 break;
4624
4625 case 3:
4626 $do_send = !$data['finished'];
4627 break;
4628
4629 default:
4630 $do_send = true;
4631 break;
4632 }
4633 if ($do_send)
4634 {
4635 // build text
4636 $messagetext = $message;
4637 $url = ilLink::_getLink($this->getRefId(), "svy",
4638 array(
4639 "accesscode" => $data["code"],
4640 "lang" => $lang
4641 ));
4642 $messagetext = str_replace('[url]', $url, $messagetext);
4643 foreach ($data as $key => $value)
4644 {
4645 $messagetext = str_replace('[' . $key . ']', $value, $messagetext);
4646 }
4647
4648 // send mail
4649 $mail->sendMail(
4650 $data['email'], // to
4651 "", // cc
4652 "", // bcc
4653 $subject, // subject
4654 $messagetext, // message
4655 array(), // attachments
4656 array('normal') // type
4657 );
4658 }
4659 }
4660 }
4661
4662 global $ilDB;
4663 $ilDB->manipulateF("UPDATE svy_anonymous SET sent = %s WHERE survey_fi = %s AND externaldata IS NOT NULL",
4664 array('integer','integer'),
4665 array(1, $this->getSurveyId())
4666 );
4667 }
4668
4669 function getExternalCodeRecipients($a_check_finished = false)
4670 {
4671 global $ilDB;
4672 $result = $ilDB->queryF("SELECT survey_key code, externaldata, sent FROM svy_anonymous WHERE survey_fi = %s",
4673 array('integer'),
4674 array($this->getSurveyId())
4675 );
4676 $res = array();
4677 while ($row = $ilDB->fetchAssoc($result))
4678 {
4679 if(!$row['externaldata'])
4680 {
4681 continue;
4682 }
4683
4684 $externaldata = unserialize($row['externaldata']);
4685 if(!$externaldata['email'])
4686 {
4687 continue;
4688 }
4689
4690 $externaldata['code'] = $row['code'];
4691 $externaldata['sent'] = $row['sent'];
4692
4693 if($a_check_finished)
4694 {
4695 $externaldata['finished'] = $this->isSurveyCodeUsed($row['code']);
4696 }
4697
4698 array_push($res, $externaldata);
4699 }
4700 return $res;
4701 }
4702
4708 function deleteSurveyCode($survey_code)
4709 {
4710 global $ilDB;
4711
4712 if (strlen($survey_code) > 0)
4713 {
4714 $affectedRows = $ilDB->manipulateF("DELETE FROM svy_anonymous WHERE survey_fi = %s AND survey_key = %s",
4715 array('integer', 'text'),
4716 array($this->getSurveyId(), $survey_code)
4717 );
4718 }
4719 }
4720
4727 function getUserAccessCode($user_id)
4728 {
4729 global $ilDB;
4730 $access_code = "";
4731 $result = $ilDB->queryF("SELECT survey_key FROM svy_anonymous WHERE survey_fi = %s AND user_key = %s",
4732 array('integer','text'),
4733 array($this->getSurveyId(), md5($user_id))
4734 );
4735 if ($result->numRows())
4736 {
4737 $row = $ilDB->fetchAssoc($result);
4738 $access_code = $row["survey_key"];
4739 }
4740 return $access_code;
4741 }
4742
4749 function saveUserAccessCode($user_id, $access_code)
4750 {
4751 global $ilDB;
4752
4753 // not really sure what to do about ANONYMOUS_USER_ID
4754
4755 $next_id = $ilDB->nextId('svy_anonymous');
4756 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_anonymous (anonymous_id, survey_key, survey_fi, user_key, tstamp) ".
4757 "VALUES (%s, %s, %s, %s, %s)",
4758 array('integer','text', 'integer', 'text', 'integer'),
4759 array($next_id, $access_code, $this->getSurveyId(), md5($user_id), time())
4760 );
4761 }
4762
4769 {
4770 // create a 5 character code
4771 $codestring = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4772 mt_srand();
4773 $code = "";
4774 for ($i = 1; $i <=5; $i++)
4775 {
4776 $index = mt_rand(0, strlen($codestring)-1);
4777 $code .= substr($codestring, $index, 1);
4778 }
4779 // verify it against the database
4780 while (!$this->isSurveyCodeUnique($code))
4781 {
4782 $code = $this->createNewAccessCode();
4783 }
4784 return $code;
4785 }
4786
4787 function getLastAccess($finished_id)
4788 {
4789 global $ilDB;
4790
4791 $result = $ilDB->queryF("SELECT tstamp FROM svy_answer WHERE active_fi = %s ORDER BY tstamp DESC",
4792 array('integer'),
4793 array($finished_id)
4794 );
4795 if ($result->numRows())
4796 {
4797 $row = $ilDB->fetchAssoc($result);
4798 return $row["tstamp"];
4799 }
4800 else
4801 {
4802 $result = $ilDB->queryF("SELECT tstamp FROM svy_finished WHERE finished_id = %s",
4803 array('integer'),
4804 array($finished_id)
4805 );
4806 if ($result->numRows())
4807 {
4808 $row = $ilDB->fetchAssoc($result);
4809 return $row["tstamp"];
4810 }
4811 }
4812 return "";
4813 }
4814
4821 function prepareTextareaOutput($txt_output)
4822 {
4823 return ilUtil::prepareTextareaOutput($txt_output, $prepare_for_latex_output);
4824 }
4825
4833 function isHTML($a_text)
4834 {
4835 if (preg_match("/<[^>]*?>/", $a_text))
4836 {
4837 return TRUE;
4838 }
4839 else
4840 {
4841 return FALSE;
4842 }
4843 }
4844
4853 function addMaterialTag(&$a_xml_writer, $a_material, $close_material_tag = TRUE, $add_mobs = TRUE, $attribs = NULL)
4854 {
4855 include_once "./Services/RTE/classes/class.ilRTE.php";
4856 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
4857
4858 $a_xml_writer->xmlStartTag("material", $attribs);
4859 $attrs = array(
4860 "type" => "text/plain"
4861 );
4862 if ($this->isHTML($a_material))
4863 {
4864 $attrs["type"] = "text/xhtml";
4865 }
4866 $mattext = ilRTE::_replaceMediaObjectImageSrc($a_material, 0);
4867 $a_xml_writer->xmlElement("mattext", $attrs, $mattext);
4868
4869 if ($add_mobs)
4870 {
4871 $mobs = ilObjMediaObject::_getMobsOfObject("svy:html", $this->getId());
4872 foreach ($mobs as $mob)
4873 {
4874 $mob_id = "il_" . IL_INST_ID . "_mob_" . $mob;
4875 if (strpos($mattext, $mob_id) !== FALSE)
4876 {
4877 $mob_obj = new ilObjMediaObject($mob);
4878 $imgattrs = array(
4879 "label" => $mob_id,
4880 "uri" => "objects/" . "il_" . IL_INST_ID . "_mob_" . $mob . "/" . $mob_obj->getTitle(),
4881 "type" => "svy:html",
4882 "id" => $this->getId()
4883 );
4884 $a_xml_writer->xmlElement("matimage", $imgattrs, NULL);
4885 }
4886 }
4887 }
4888 if ($close_material_tag) $a_xml_writer->xmlEndTag("material");
4889 }
4890
4900 {
4901 if ($this->getAnonymize() != self::ANONYMIZE_OFF)
4902 {
4903 if ($this->surveyCodeSecurity == FALSE)
4904 {
4905 return TRUE;
4906 }
4907 }
4908 return FALSE;
4909 }
4910
4918 function processPrintoutput2FO($print_output)
4919 {
4920 global $ilLog;
4921 if (extension_loaded("tidy"))
4922 {
4923 $config = array(
4924 "indent" => false,
4925 "output-xml" => true,
4926 "numeric-entities" => true
4927 );
4928 $tidy = new tidy();
4929 $tidy->parseString($print_output, $config, 'utf8');
4930 $tidy->cleanRepair();
4931 $print_output = tidy_get_output($tidy);
4932 $print_output = preg_replace("/^.*?(<html)/", "\\1", $print_output);
4933 }
4934 else
4935 {
4936 $print_output = str_replace("&nbsp;", "&#160;", $print_output);
4937 $print_output = str_replace("&otimes;", "X", $print_output);
4938
4939 // #17680 - metric questions use &#160; in print view
4940 $print_output = str_replace("&gt;", "~|gt|~", $print_output); // see #21550
4941 $print_output = str_replace("&lt;", "~|lt|~", $print_output);
4942 $print_output = str_replace("&#160;", "~|nbsp|~", $print_output);
4943 $print_output = preg_replace('/&(?!amp)/', '&amp;', $print_output);
4944 $print_output = str_replace("~|nbsp|~", "&#160;", $print_output);
4945 $print_output = str_replace( "~|gt|~", "&gt;", $print_output);
4946 $print_output = str_replace( "~|lt|~", "&lt;", $print_output);
4947 }
4948 $xsl = file_get_contents("./Modules/Survey/xml/question2fo.xsl");
4949
4950 // additional font support
4951 $xsl = str_replace(
4952 'font-family="Helvetica, unifont"',
4953 'font-family="'.$GLOBALS['ilSetting']->get('rpc_pdf_font','Helvetica, unifont').'"',
4954 $xsl
4955 );
4956 $args = array( '/_xml' => $print_output, '/_xsl' => $xsl );
4957 $xh = xslt_create();
4958 $params = array();
4959 try
4960 {
4961 $output = xslt_process($xh, "arg:/_xml", "arg:/_xsl", null, $args, $params);
4962 }
4963 catch (Exception $e)
4964 {
4965 $this->log->error("Print XSLT failed:");
4966 $this->log->error("Content: ".$print_output);
4967 $this->log->error("Xsl: ".$xsl);
4968 throw ($e);
4969 }
4970 xslt_error($xh);
4971 xslt_free($xh);
4972 $ilLog->write($output);
4973 return $output;
4974 }
4975
4982 function deliverPDFfromFO($fo)
4983 {
4984 global $ilLog;
4985
4986 $fo_file = ilUtil::ilTempnam() . ".fo";
4987 $fp = fopen($fo_file, "w"); fwrite($fp, $fo); fclose($fp);
4988
4989 include_once './Services/WebServices/RPC/classes/class.ilRpcClientFactory.php';
4990 try
4991 {
4992 $pdf_base64 = ilRpcClientFactory::factory('RPCTransformationHandler')->ilFO2PDF($fo);
4993 ilUtil::deliverData($pdf_base64->scalar, ilUtil::getASCIIFilename($this->getTitle()) . ".pdf", "application/pdf");
4994 return true;
4995 }
4996 catch(Exception $e)
4997 {
4998 $ilLog->write(__METHOD__.': '.$e->getMessage());
4999 return false;
5000 }
5001 }
5002
5009 function isPluginActive($a_pname)
5010 {
5011 global $ilPluginAdmin;
5012 if ($ilPluginAdmin->isActive(IL_COMP_MODULE, "SurveyQuestionPool", "svyq", $a_pname))
5013 {
5014 return TRUE;
5015 }
5016 else
5017 {
5018 return FALSE;
5019 }
5020 }
5021
5027 public function setSurveyId($survey_id)
5028 {
5029 $this->survey_id = $survey_id;
5030 }
5031
5038 public function &getUserData($ids)
5039 {
5040 global $ilDB;
5041
5042 if (!is_array($ids) || count($ids) ==0) return array();
5043
5044 $result = $ilDB->query("SELECT usr_id, login, lastname, firstname FROM usr_data WHERE " . $ilDB->in('usr_id', $ids, false, 'integer') . " ORDER BY login");
5045 $result_array = array();
5046 while ($row = $ilDB->fetchAssoc($result))
5047 {
5048 $result_array[$row["usr_id"]]= $row;
5049 }
5050 return $result_array;
5051 }
5052
5054 {
5056 }
5057
5058 function setMailNotification($a_notification)
5059 {
5060 $this->mailnotification = ($a_notification) ? true : false;
5061 }
5062
5064 {
5065 return $this->mailaddresses;
5066 }
5067
5068 function setMailAddresses($a_addresses)
5069 {
5070 $this->mailaddresses = $a_addresses;
5071 }
5072
5074 {
5076 }
5077
5078 function setMailParticipantData($a_data)
5079 {
5080 $this->mailparticipantdata = $a_data;
5081 }
5082
5083 function setStartTime($finished_id, $first_question)
5084 {
5085 global $ilDB;
5086 $time = time();
5087 //primary for table svy_times
5088 $id = $ilDB->nextId('svy_times');
5089 $_SESSION['svy_entered_page'] = $time;
5090 $affectedRows = $ilDB->manipulateF("INSERT INTO svy_times (id, finished_fi, entered_page, left_page, first_question) VALUES (%s, %s, %s, %s,%s)",
5091 array('integer','integer', 'integer', 'integer', 'integer'),
5092 array($id, $finished_id, $time, NULL, $first_question)
5093 );
5094 }
5095
5096 function setEndTime($finished_id)
5097 {
5098 global $ilDB;
5099 $time = time();
5100 $affectedRows = $ilDB->manipulateF("UPDATE svy_times SET left_page = %s WHERE finished_fi = %s AND entered_page = %s",
5101 array('integer', 'integer', 'integer'),
5102 array($time, $finished_id, $_SESSION['svy_entered_page'])
5103 );
5104 unset($_SESSION['svy_entered_page']);
5105 }
5106
5107 function getWorkingtimeForParticipant($finished_id)
5108 {
5109 global $ilDB;
5110
5111 $result = $ilDB->queryF("SELECT * FROM svy_times WHERE finished_fi = %s",
5112 array('integer'),
5113 array($finished_id)
5114 );
5115 $total = 0;
5116 while ($row = $ilDB->fetchAssoc($result))
5117 {
5118 if ($row['left_page'] > 0 && $row['entered_page'] > 0)
5119 $total += $row['left_page'] - $row['entered_page'];
5120 }
5121 return $total;
5122 }
5123
5125 {
5126 $this->template_id = (int)$template_id;
5127 }
5128
5129 function getTemplate()
5130 {
5131 return $this->template_id;
5132 }
5133
5134 function updateOrder(array $a_order)
5135 {
5136 if(sizeof($this->questions) == sizeof($a_order))
5137 {
5138 $this->questions = array_flip($a_order);
5139 $this->saveQuestionsToDB();
5140 }
5141 }
5142
5143 function getPoolUsage()
5144 {
5145 return $this->pool_usage;
5146 }
5147
5148 function setPoolUsage($a_value)
5149 {
5150 $this->pool_usage = (bool)$a_value;
5151 }
5152
5158 function isPoolActive()
5159 {
5160 $use_pool = (bool)$this->getPoolUsage();
5161 $template_settings = $this->getTemplate();
5162 if($template_settings)
5163 {
5164 include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
5165 $template_settings = new ilSettingsTemplate($template_settings);
5166 $template_settings = $template_settings->getSettings();
5167 $template_settings = $template_settings["use_pool"];
5168 if($template_settings && $template_settings["hide"])
5169 {
5170 $use_pool = (bool)$template_settings["value"];
5171 }
5172 }
5173 return $use_pool;
5174 }
5175
5182 {
5183 if(!$template_id)
5184 {
5185 return;
5186 }
5187
5188 include_once "Services/Administration/classes/class.ilSettingsTemplate.php";
5189 $template = new ilSettingsTemplate($template_id);
5190 $template_settings = $template->getSettings();
5191 if($template_settings)
5192 {
5193 if($template_settings["show_question_titles"] !== NULL)
5194 {
5195 if($template_settings["show_question_titles"]["value"])
5196 {
5197 $this->setShowQuestionTitles(true);
5198 }
5199 else
5200 {
5201 $this->setShowQuestionTitles(false);
5202 }
5203 }
5204
5205 if($template_settings["use_pool"] !== NULL)
5206 {
5207 if($template_settings["use_pool"]["value"])
5208 {
5209 $this->setPoolUsage(true);
5210 }
5211 else
5212 {
5213 $this->setPoolUsage(false);
5214 }
5215 }
5216
5217 if($template_settings["anonymization_options"]["value"])
5218 {
5219 $anon_map = array('personalized' => self::ANONYMIZE_OFF,
5220 'anonymize_with_code' => self::ANONYMIZE_ON,
5221 'anonymize_without_code' => self::ANONYMIZE_FREEACCESS);
5222 $this->setAnonymize($anon_map[$template_settings["anonymization_options"]["value"]]);
5223 }
5224
5225 /* other settings: not needed here
5226 * - enabled_end_date
5227 * - enabled_start_date
5228 * - rte_switch
5229 */
5230 }
5231
5232 $this->setTemplate($template_id);
5233 $this->saveToDb();
5234 }
5235
5236 public function updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
5237 {
5238 global $ilDB;
5239
5240 $a_email = trim($a_email);
5241
5242 // :TODO:
5243 if(($a_email && !ilUtil::is_email($a_email)) || $a_email == "")
5244 {
5245 return false;
5246 }
5247
5248 $data = array("email" => $a_email,
5249 "lastname" => trim($a_last_name),
5250 "firstname" => trim($a_first_name));
5251
5252 $fields = array(
5253 "externaldata" => array("text", serialize($data)),
5254 "sent" => array("integer", $a_sent)
5255 );
5256
5257 $ilDB->update("svy_anonymous", $fields,
5258 array("anonymous_id" => array("integer", $a_id)));
5259
5260 return true;
5261 }
5262
5263
5264 //
5265 // 360°
5266 //
5267
5268 public function set360Mode($a_value)
5269 {
5270 $this->mode_360 = (bool)$a_value;
5271 }
5272
5273 public function get360Mode()
5274 {
5275 return (bool)$this->mode_360;
5276 }
5277
5278 public function set360SelfEvaluation($a_value)
5279 {
5280 $this->mode_360_self_eval = (bool)$a_value;
5281 }
5282
5283 public function get360SelfEvaluation()
5284 {
5285 return (bool)$this->mode_360_self_eval;
5286 }
5287
5288 public function set360SelfAppraisee($a_value)
5289 {
5290 $this->mode_360_self_appr = (bool)$a_value;
5291 }
5292
5293 public function get360SelfAppraisee()
5294 {
5295 return (bool)$this->mode_360_self_appr;
5296 }
5297
5298 public function set360SelfRaters($a_value)
5299 {
5300 $this->mode_360_self_rate = (bool)$a_value;
5301 }
5302
5303 public function get360SelfRaters()
5304 {
5305 return (bool)$this->mode_360_self_rate;
5306 }
5307
5308 public function set360Results($a_value)
5309 {
5310 $this->mode_360_results = (int)$a_value;
5311 }
5312
5313 public function get360Results()
5314 {
5315 return (int)$this->mode_360_results;
5316 }
5317
5318 public function addAppraisee($a_user_id)
5319 {
5320 global $ilDB;
5321
5322 if(!$this->isAppraisee($a_user_id) &&
5323 $a_user_id != ANONYMOUS_USER_ID)
5324 {
5325 $fields = array(
5326 "obj_id" => array("integer", $this->getSurveyId()),
5327 "user_id" => array("integer", $a_user_id)
5328 );
5329 $ilDB->insert("svy_360_appr", $fields);
5330 }
5331 }
5332
5333 public function isAppraisee($a_user_id)
5334 {
5335 global $ilDB;
5336
5337 $set = $ilDB->query("SELECT user_id".
5338 " FROM svy_360_appr".
5339 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5340 " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5341 return (bool)$ilDB->numRows($set);
5342 }
5343
5344 public function isAppraiseeClosed($a_user_id)
5345 {
5346 global $ilDB;
5347
5348 $set = $ilDB->query("SELECT has_closed".
5349 " FROM svy_360_appr".
5350 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5351 " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5352 $row = $ilDB->fetchAssoc($set);
5353 return $row["has_closed"];
5354 }
5355
5356 public function deleteAppraisee($a_user_id)
5357 {
5358 global $ilDB;
5359
5360 $ilDB->manipulate("DELETE FROM svy_360_appr".
5361 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5362 " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5363
5364 $set = $ilDB->query("SELECT user_id".
5365 " FROM svy_360_rater".
5366 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5367 " AND appr_id = ".$ilDB->quote($a_user_id, "integer"));
5368 while($row = $ilDB->fetchAssoc($set))
5369 {
5370 $this->deleteRater($a_user_id, $row["user_id"]);
5371 }
5372 // appraisee will not be part of raters table
5373 if($this->get360SelfEvaluation())
5374 {
5375 $this->deleteRater($a_user_id, $a_user_id);
5376 }
5377 }
5378
5379 public function getAppraiseesData()
5380 {
5381 global $ilDB;
5382
5383 $res = array();
5384
5385 $set = $ilDB->query("SELECT * FROM svy_360_appr".
5386 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer"));
5387 while($row = $ilDB->fetchAssoc($set))
5388 {
5389 $name = ilObjUser::_lookupName($row["user_id"]);
5390 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5391 $name["name"] = $name["lastname"].", ".$name["firstname"];
5392 $res[$row["user_id"]] = $name;
5393
5394 $finished = 0;
5395 $raters = $this->getRatersData($row["user_id"]);
5396 foreach($raters as $rater)
5397 {
5398 if($rater["finished"])
5399 {
5400 $finished++;
5401 }
5402 }
5403 $res[$row["user_id"]]["finished"] = $finished."/".sizeof($raters);
5404 $res[$row["user_id"]]["closed"] = $row["has_closed"];
5405 }
5406
5407 return $res;
5408 }
5409
5410 public function addRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5411 {
5412 global $ilDB;
5413
5414 if($this->isAppraisee($a_appraisee_id) &&
5415 !$this->isRater($a_appraisee_id, $a_user_id, $a_anonymous_id))
5416 {
5417 $fields = array(
5418 "obj_id" => array("integer", $this->getSurveyId()),
5419 "appr_id" => array("integer", $a_appraisee_id),
5420 "user_id" => array("integer", $a_user_id),
5421 "anonymous_id" => array("integer", $a_anonymous_id)
5422 );
5423 $ilDB->insert("svy_360_rater", $fields);
5424 }
5425 }
5426
5427 public function isRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5428 {
5429 global $ilDB;
5430
5431 // user is rater if already appraisee and active self-evaluation
5432 if($this->isAppraisee($a_user_id) &&
5433 $this->get360SelfEvaluation() &&
5434 (!$a_appraisee_id || $a_appraisee_id == $a_user_id))
5435 {
5436 return true;
5437 }
5438
5439 // :TODO: should we get rid of code as well?
5440
5441 $sql = "SELECT user_id".
5442 " FROM svy_360_rater".
5443 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5444 " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5445 " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer");
5446 if($a_appraisee_id)
5447 {
5448 $sql .= " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer");
5449 }
5450 $set = $ilDB->query($sql);
5451 return (bool)$ilDB->numRows($set);
5452 }
5453
5454 public function deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id = 0)
5455 {
5456 global $ilDB;
5457
5458 $finished_id = $this->getFinishedIdForAppraiseeIdAndRaterId($a_appraisee_id, $a_user_id);
5459 if($finished_id)
5460 {
5461 $this->removeSelectedSurveyResults(array($finished_id));
5462 }
5463
5464 $ilDB->manipulate("DELETE FROM svy_360_rater".
5465 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5466 " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer").
5467 " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5468 " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer"));
5469 }
5470
5471 public function getRatersData($a_appraisee_id)
5472 {
5473 global $ilDB;
5474
5475 $res = $anonymous_ids = array();
5476
5477 $set = $ilDB->query("SELECT * FROM svy_360_rater".
5478 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5479 " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer"));
5480 while($row = $ilDB->fetchAssoc($set))
5481 {
5482 if($row["anonymous_id"])
5483 {
5484 $res["a".$row["anonymous_id"]] = array(
5485 "lastname" => "unknown code ".$row["anonymous_id"],
5486 "sent" => $row["mail_sent"],
5487 "finished" => null
5488 );
5489 $anonymous_ids[] = $row["anonymous_id"];
5490 }
5491 else
5492 {
5493 $name = ilObjUser::_lookupName($row["user_id"]);
5494 $name["name"] = $name["lastname"].", ".$name["firstname"];
5495 $name["user_id"] = "u".$name["user_id"];
5496 $name["email"] = ilObjUser::_lookupEmail($row["user_id"]);
5497 $name["sent"] = $row["mail_sent"];
5498 $name["finished"] = (bool)$this->is360SurveyStarted($a_appraisee_id, $row["user_id"]);
5499 $res["u".$row["user_id"]] = $name;
5500 }
5501 }
5502
5503 if(sizeof($anonymous_ids))
5504 {
5505 $data = $this->getSurveyCodesTableData($anonymous_ids);
5506 foreach($data as $item)
5507 {
5508 if(isset($res["a".$item["id"]]))
5509 {
5510 $res["a".$item["id"]] = array(
5511 "user_id" => "a".$item["id"],
5512 "lastname" => $item["last_name"],
5513 "firstname" => $item["first_name"],
5514 "name" => $item["last_name"].", ".$item["first_name"],
5515 "login" => "",
5516 "email" => $item["email"],
5517 "code" => $item["code"],
5518 "href" => $item["href"],
5519 "sent" => $res["a".$item["id"]]["sent"],
5520 "finished" => (bool)$this->is360SurveyStarted($a_appraisee_id, null, $item["code"])
5521 );
5522 }
5523 }
5524 }
5525
5526 return $res;
5527 }
5528
5529 public function getAppraiseesToRate($a_user_id, $a_anonymous_id = null)
5530 {
5531 global $ilDB;
5532
5533 $res = array();
5534
5535 $sql = "SELECT appr_id FROM svy_360_rater".
5536 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer");
5537
5538 if($a_user_id)
5539 {
5540 $sql .= " AND user_id = ".$ilDB->quote($a_user_id, "integer");
5541 }
5542 else
5543 {
5544 $sql .= " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer");
5545 }
5546
5547 $set = $ilDB->query($sql);
5548 while($row = $ilDB->fetchAssoc($set))
5549 {
5550 $res[] = $row["appr_id"];
5551 }
5552
5553 // user may evaluate himself if already appraisee
5554 if($this->get360SelfEvaluation() &&
5555 $this->isAppraisee($a_user_id) &&
5556 !in_array($a_user_id, $res))
5557 {
5558 $res[] = $a_user_id;
5559 }
5560
5561 return $res;
5562 }
5563
5564 public function getAnonymousIdByCode($a_code)
5565 {
5566 global $ilDB;
5567
5568 $set = $ilDB->query("SELECT anonymous_id FROM svy_anonymous".
5569 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
5570 " AND survey_key = ".$ilDB->quote($a_code, "text"));
5571 $res = $ilDB->fetchAssoc($set);
5572 return $res["anonymous_id"];
5573 }
5574
5575 function is360SurveyStarted($appr_id, $user_id, $anonymous_code = null)
5576 {
5577 global $ilDB;
5578
5579 $sql = "SELECT * FROM svy_finished".
5580 " WHERE survey_fi =".$ilDB->quote($this->getSurveyId(), "integer").
5581 " AND appr_id = ".$ilDB->quote($appr_id, "integer");
5582 if ($user_id)
5583 {
5584 $sql .= " AND user_fi = ".$ilDB->quote($user_id, "integer");
5585 }
5586 else
5587 {
5588 $sql .= " AND anonymous_id = ".$ilDB->quote($anonymous_code, "text");
5589 }
5590 $result = $ilDB->query($sql);
5591 if ($result->numRows() == 0)
5592 {
5593 return false;
5594 }
5595 else
5596 {
5597 $row = $ilDB->fetchAssoc($result);
5598 return (int)$row["state"];
5599 }
5600 }
5601
5602 function getUserSurveyExecutionStatus($a_code = null)
5603 {
5604 global $ilUser, $ilDB;
5605
5606 $user_id = $ilUser->getId();
5607
5608 // code is obligatory?
5609 if(!$this->isAccessibleWithoutCode())
5610 {
5611 if(!$a_code)
5612 {
5613 // registered raters do not need code
5614 if($this->get360Mode() &&
5615 $user_id != ANONYMOUS_USER_ID &&
5616 $this->isRater(0, $user_id))
5617 {
5618 // auto-generate code
5619 $a_code = $this->createNewAccessCode();
5620 $this->saveUserAccessCode($user_id, $a_code);
5621 }
5622 else
5623 {
5624 return null;
5625 }
5626 }
5627 }
5628 else if($user_id == ANONYMOUS_USER_ID ||
5629 $this->getAnonymize() == self::ANONYMIZE_FREEACCESS)
5630 {
5631 if(!$a_code)
5632 {
5633 // auto-generate code
5634 $a_code = $this->createNewAccessCode();
5635 $this->saveUserAccessCode($user_id, $a_code);
5636 }
5637 }
5638 else
5639 {
5640 $a_code = null;
5641 }
5642
5643 $res = array();
5644
5645 $sql = "SELECT * FROM svy_finished".
5646 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer");
5647 // if proper user id is given, use it or current code
5648 if($user_id != ANONYMOUS_USER_ID)
5649 {
5650 $sql .= " AND (user_fi = ".$ilDB->quote($user_id, "integer").
5651 " OR anonymous_id = ".$ilDB->quote($a_code, "text").")";
5652 }
5653 // use anonymous code to find finished id(s)
5654 else
5655 {
5656 $sql .= " AND anonymous_id = ".$ilDB->quote($a_code, "text");
5657 }
5658 $set = $ilDB->query($sql);
5659 while($row = $ilDB->fetchAssoc($set))
5660 {
5661 $res[$row["finished_id"]] = array("appr_id" => $row["appr_id"],
5662 "user_id" => $row["user_fi"],
5663 "code" => $row["anonymous_id"],
5664 "finished" => (bool)$row["state"]);
5665 }
5666
5667 return array("code"=>$a_code, "runs"=>$res);
5668 }
5669
5670 function findCodeForUser($a_user_id)
5671 {
5672 global $ilDB;
5673
5674 if($a_user_id != ANONYMOUS_USER_ID)
5675 {
5676 $set = $ilDB->query("SELECT sf.anonymous_id FROM svy_finished sf".
5677 " WHERE sf.survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
5678 " AND sf.user_fi = ".$ilDB->quote($a_user_id, "integer"));
5679 $a_code = $ilDB->fetchAssoc($set);
5680 return $a_code["anonymous_id"];
5681 }
5682 }
5683
5684 function isUnusedCode($a_code, $a_user_id)
5685 {
5686 global $ilDB;
5687
5688 $set = $ilDB->query("SELECT user_fi FROM svy_finished".
5689 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
5690 " AND anonymous_id = ".$ilDB->quote($a_code, "text"));
5691 $user_id = $ilDB->fetchAssoc($set);
5692 $user_id = $user_id["user_fi"];
5693
5694 if($user_id && ($user_id != $a_user_id || $user_id == ANONYMOUS_USER_ID))
5695 {
5696 return false;
5697 }
5698 return true;
5699 }
5700
5701 function getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee = false)
5702 {
5703 global $ilDB;
5704
5705 $res = array();
5706
5707 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished".
5708 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
5709 " AND appr_id = ".$ilDB->quote($a_appr_id, "integer"));
5710 while($row = $ilDB->fetchAssoc($set))
5711 {
5712 if ($a_exclude_appraisee && $row["user_fi"] == $a_appr_id)
5713 {
5714 continue;
5715 }
5716 $res[] = $row["finished_id"];
5717 }
5718
5719 return $res;
5720 }
5721
5729 function getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
5730 {
5731 global $ilDB;
5732
5733 $set = $ilDB->query("SELECT finished_id, user_fi FROM svy_finished".
5734 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
5735 " AND appr_id = ".$ilDB->quote($a_appr_id, "integer").
5736 " AND user_fi = ".$ilDB->quote($a_rat_id, "integer"));
5737 $row = $ilDB->fetchAssoc($set);
5738 return $row["finished_id"];
5739 }
5740
5741
5742 // 360° using competence/skill service
5743
5749 function set360SkillService($a_val)
5750 {
5751 $this->mode_360_skill_service = $a_val;
5752 }
5753
5760 {
5762 }
5763
5764 function set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp = null)
5765 {
5766 global $ilDB;
5767
5768 if(!$a_tstamp)
5769 {
5770 $a_tstamp = time();
5771 }
5772
5773 $ilDB->manipulate("UPDATE svy_360_rater".
5774 " SET mail_sent = ".$ilDB->quote($a_tstamp, "integer").
5775 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5776 " AND appr_id = ".$ilDB->quote($a_appraisee_id, "integer").
5777 " AND user_id = ".$ilDB->quote($a_user_id, "integer").
5778 " AND anonymous_id = ".$ilDB->quote($a_anonymous_id, "integer"));
5779 }
5780
5781 function closeAppraisee($a_user_id)
5782 {
5783 global $ilDB;
5784
5785 // close the appraisee
5786 $ilDB->manipulate("UPDATE svy_360_appr".
5787 " SET has_closed = ".$ilDB->quote(time(), "integer").
5788 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer").
5789 " AND user_id = ".$ilDB->quote($a_user_id, "integer"));
5790
5791 // write competences
5792 include_once("./Services/Skill/classes/class.ilSkillManagementSettings.php");
5793 $skmg_set = new ilSkillManagementSettings();
5794 if ($this->get360SkillService() && $skmg_set->isActivated())
5795 {
5796 include_once("./Modules/Survey/classes/class.ilSurveySkill.php");
5797 $sskill = new ilSurveySkill($this);
5798 $sskill->writeAppraiseeSkills($a_user_id);
5799 }
5800 }
5801
5803 {
5804 global $ilDB;
5805
5806 $ilDB->manipulate("UPDATE svy_360_appr".
5807 " SET has_closed = ".$ilDB->quote(null, "integer").
5808 " WHERE obj_id = ".$ilDB->quote($this->getSurveyId(), "integer"));
5809 }
5810
5811 public static function validateExternalRaterCode($a_ref_id, $a_code)
5812 {
5813 if(!isset($_SESSION["360_extrtr"][$a_ref_id]))
5814 {
5815 $svy = new self($a_ref_id);
5816 $svy->loadFromDB();
5817
5818 if($svy->canStartSurvey(null, true) &&
5819 $svy->get360Mode() &&
5820 $svy->isAnonymousKey($a_code))
5821 {
5822 $anonymous_id = $svy->getAnonymousIdByCode($a_code);
5823 if($anonymous_id)
5824 {
5825 if(sizeof($svy->getAppraiseesToRate(null, $anonymous_id)))
5826 {
5827 $_SESSION["360_extrtr"][$a_ref_id] = true;
5828 return true;
5829 }
5830 }
5831 }
5832
5833 $_SESSION["360_extrtr"][$a_ref_id] = false;
5834 return false;
5835 }
5836
5837 return $_SESSION["360_extrtr"][$a_ref_id];
5838 }
5839
5840
5841 //
5842 // reminder/notification
5843 //
5844
5845 public function getReminderStatus()
5846 {
5847 return (bool)$this->reminder_status;
5848 }
5849
5850 public function setReminderStatus($a_value)
5851 {
5852 $this->reminder_status = (bool)$a_value;
5853 }
5854
5855 public function getReminderStart()
5856 {
5857 return $this->reminder_start;
5858 }
5859
5860 public function setReminderStart(ilDate $a_value = null)
5861 {
5862 $this->reminder_start = $a_value;
5863 }
5864
5865 public function getReminderEnd()
5866 {
5867 return $this->reminder_end;
5868 }
5869
5870 public function setReminderEnd(ilDate $a_value = null)
5871 {
5872 $this->reminder_end = $a_value;
5873 }
5874
5875 public function getReminderFrequency()
5876 {
5878 }
5879
5880 public function setReminderFrequency($a_value)
5881 {
5882 $this->reminder_frequency = (int)$a_value;
5883 }
5884
5885 public function getReminderTarget()
5886 {
5888 }
5889
5890 public function setReminderTarget($a_value)
5891 {
5892 $this->reminder_target = (int)$a_value;
5893 }
5894
5895 public function getReminderLastSent()
5896 {
5898 }
5899
5900 public function setReminderLastSent($a_value)
5901 {
5902 $this->reminder_last_sent = $a_value;
5903 }
5904
5905 public function getReminderTemplate()
5906 {
5907 return $this->reminder_tmpl;
5908 }
5909
5910 public function setReminderTemplate($a_value)
5911 {
5912 $this->reminder_tmpl = $a_value;
5913 }
5914
5916 {
5917 return (bool)$this->tutor_ntf_status;
5918 }
5919
5920 public function setTutorNotificationStatus($a_value)
5921 {
5922 $this->tutor_ntf_status = (bool)$a_value;
5923 }
5924
5926 {
5928 }
5929
5930 public function setTutorNotificationRecipients(array $a_value)
5931 {
5932 $this->tutor_ntf_recipients = $a_value;
5933 }
5934
5936 {
5938 }
5939
5940 public function setTutorNotificationTarget($a_value)
5941 {
5942 $this->tutor_ntf_target = (int)$a_value;
5943 }
5944
5945 protected function checkTutorNotification()
5946 {
5947 global $ilDB;
5948
5949 if($this->getTutorNotificationStatus())
5950 {
5951 $user_ids = $this->getNotificationTargetUserIds(($this->getTutorNotificationTarget() == self::NOTIFICATION_INVITED_USERS));
5952 if($user_ids)
5953 {
5954 $set = $ilDB->query("SELECT COUNT(*) numall FROM svy_finished".
5955 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
5956 " AND state = ".$ilDB->quote(1, "integer").
5957 " AND ".$ilDB->in("user_fi", $user_ids, "", "integer"));
5958 $row = $ilDB->fetchAssoc($set);
5959 if($row["numall"] == sizeof($user_ids))
5960 {
5961 $this->sendTutorNotification();
5962 }
5963 }
5964 }
5965 }
5966
5967 public function getNotificationTargetUserIds($a_use_invited)
5968 {
5969 global $tree;
5970
5971 if((bool)$a_use_invited)
5972 {
5973 $user_ids = $this->getInvitedUsers();
5974 }
5975 else
5976 {
5977 $parent_grp_ref_id = $tree->checkForParentType($this->getRefId(), "grp");
5978 if($parent_grp_ref_id)
5979 {
5980 include_once "Modules/Group/classes/class.ilGroupParticipants.php";
5981 $part = new ilGroupParticipants(ilObject::_lookupObjId($parent_grp_ref_id));
5982 $user_ids = $part->getMembers();
5983 }
5984 else
5985 {
5986 $parent_crs_ref_id = $tree->checkForParentType($this->getRefId(), "crs");
5987 if($parent_crs_ref_id)
5988 {
5989 include_once "Modules/Course/classes/class.ilCourseParticipants.php";
5990 $part = new ilCourseParticipants(ilObject::_lookupObjId($parent_crs_ref_id));
5991 $user_ids = $part->getMembers();
5992 }
5993 }
5994 }
5995 return $user_ids;
5996 }
5997
5998 protected function sendTutorNotification()
5999 {
6000 include_once "./Services/Mail/classes/class.ilMail.php";
6001 include_once "./Services/User/classes/class.ilObjUser.php";
6002 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6003 include_once "./Services/User/classes/class.ilUserUtil.php";
6004 include_once "./Services/Link/classes/class.ilLink.php";
6005 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6006
6007 foreach($this->getTutorNotificationRecipients() as $user_id)
6008 {
6009 // use language of recipient to compose message
6010 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6011 $ulng->loadLanguageModule('survey');
6012
6013 $subject = sprintf($ulng->txt('survey_notification_tutor_subject'), $this->getTitle());
6014 $message = sprintf($ulng->txt('survey_notification_tutor_salutation'), ilObjUser::_lookupFullname($user_id))."\n\n";
6015
6016 $message .= $ulng->txt('survey_notification_tutor_body').":\n\n";
6017 $message .= $ulng->txt('obj_svy').": ". $this->getTitle()."\n";
6018 $message .= "\n".$ulng->txt('survey_notification_tutor_link').": ".$link;
6019
6020 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6021 $mail_obj->appendInstallationSignature(true);
6022 $mail_obj->sendMail(ilObjUser::_lookupLogin($user_id),
6023 "", "", $subject, $message, array(), array("system"));
6024 }
6025 }
6026
6027 public function checkReminder()
6028 {
6029 global $ilDB, $ilAccess;
6030
6031 $now = time();
6032 $now_with_format = date("YmdHis", $now);
6033 $today = date("Y-m-d");
6034
6035 // object settings / participation period
6036 if($this->isOffline() ||
6037 !$this->getReminderStatus() ||
6038 ($this->getStartDate() && $now_with_format < $this->getStartDate()) ||
6039 ($this->getEndDate() && $now_with_format > $this->getEndDate()))
6040 {
6041 return false;
6042 }
6043
6044 // reminder period
6045 $start = $this->getReminderStart();
6046 if($start)
6047 {
6048 $start = $start->get(IL_CAL_DATE);
6049 }
6050 $end = $this->getReminderEnd();
6051 if($end)
6052 {
6053 $end = $end->get(IL_CAL_DATE);
6054 }
6055 if($today < $start ||
6056 ($end && $today > $end))
6057 {
6058 return false;
6059 }
6060
6061 // object access period
6062 include_once "Services/Object/classes/class.ilObjectActivation.php";
6063 $item_data = ilObjectActivation::getItem($this->getRefId());
6064 if($item_data["timing_type"] == ilObjectActivation::TIMINGS_ACTIVATION &&
6065 ($now < $item_data["timing_start"] ||
6066 $now > $item_data["timing_end"]))
6067 {
6068 return false;
6069 }
6070
6071 // check frequency
6072 $cut = new ilDate($today, IL_CAL_DATE);
6073 $cut->increment(IL_CAL_DAY, $this->getReminderFrequency()*-1);
6074 if(!$this->getReminderLastSent() ||
6075 $cut->get(IL_CAL_DATE) >= substr($this->getReminderLastSent(), 0, 10))
6076 {
6077 $missing_ids = array();
6078
6079 // #16871
6080 $user_ids = $this->getNotificationTargetUserIds(($this->getReminderTarget() == self::NOTIFICATION_INVITED_USERS));
6081 if($user_ids)
6082 {
6083 // gather participants who already finished
6084 $finished_ids = array();
6085 $set = $ilDB->query("SELECT user_fi FROM svy_finished".
6086 " WHERE survey_fi = ".$ilDB->quote($this->getSurveyId(), "integer").
6087 " AND state = ".$ilDB->quote(1, "text").
6088 " AND ".$ilDB->in("user_fi", $user_ids, "", "integer"));
6089 while($row = $ilDB->fetchAssoc($set))
6090 {
6091 $finished_ids[] = $row["user_fi"];
6092 }
6093
6094 // some users missing out?
6095 $missing_ids = array_diff($user_ids, $finished_ids);
6096 if($missing_ids)
6097 {
6098 foreach($missing_ids as $idx => $user_id)
6099 {
6100 // should be able to participate
6101 if(!$ilAccess->checkAccessOfUser($user_id, "read", "", $this->getRefId(), "svy", $this->getId()))
6102 {
6103 unset($missing_ids[$idx]);
6104 }
6105 }
6106 }
6107 if($missing_ids)
6108 {
6109 $this->sentReminder($missing_ids);
6110 }
6111 }
6112
6113 $this->setReminderLastSent($today);
6114 $this->saveToDb();
6115
6116 return sizeof($missing_ids);
6117 }
6118
6119 return false;
6120 }
6121
6122 protected function sentReminder(array $a_recipient_ids)
6123 {
6124 include_once "./Services/Mail/classes/class.ilMail.php";
6125
6126 // use mail template
6127 if($this->getReminderTemplate() &&
6128 array_key_exists($this->getReminderTemplate(), $this->getReminderMailTemplates()))
6129 {
6130 $prov = new ilMailTemplateDataProvider();
6131 $tmpl = $prov->getTemplateById($this->getReminderTemplate());
6132
6133 $tmpl_params = array(
6134 "ref_id" => $this->getRefId(),
6135 "ts" => time()
6136 );
6137 }
6138 else
6139 {
6140 $tmpl = null;
6141
6142 include_once "./Services/Link/classes/class.ilLink.php";
6143 $link = ilLink::_getStaticLink($this->getRefId(), "svy");
6144
6145 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
6146 }
6147
6148 foreach($a_recipient_ids as $user_id)
6149 {
6150 if($tmpl)
6151 {
6152 $subject = $tmpl->getSubject();
6153 $message = $this->sentReminderPlaceholders($tmpl->getMessage(), $user_id, $tmpl_params);
6154 }
6155 // use lng
6156 else
6157 {
6158 // use language of recipient to compose message
6159 $ulng = ilLanguageFactory::_getLanguageOfUser($user_id);
6160 $ulng->loadLanguageModule('survey');
6161
6162 $subject = sprintf($ulng->txt('survey_reminder_subject'), $this->getTitle());
6163 $message = sprintf($ulng->txt('survey_reminder_salutation'), ilObjUser::_lookupFullname($user_id))."\n\n";
6164
6165 $message .= $ulng->txt('survey_reminder_body').":\n\n";
6166 $message .= $ulng->txt('obj_svy').": ". $this->getTitle()."\n";
6167 $message .= "\n".$ulng->txt('survey_reminder_link').": ".$link;
6168 }
6169
6170 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
6171 $mail_obj->appendInstallationSignature(true);
6172 $mail_obj->sendMail(ilObjUser::_lookupLogin($user_id),
6173 "", "", $subject, $message, array(), array("system"));
6174 }
6175 }
6176
6177 function setActivationStartDate($starting_time = NULL)
6178 {
6179 $this->activation_starting_time = $starting_time;
6180 }
6181
6182 function setActivationEndDate($ending_time = NULL)
6183 {
6184 $this->activation_ending_time = $ending_time;
6185 }
6186
6188 {
6189 return (strlen($this->activation_starting_time)) ? $this->activation_starting_time : NULL;
6190 }
6191
6193 {
6194 return (strlen($this->activation_ending_time)) ? $this->activation_ending_time : NULL;
6195 }
6196
6197 function setViewOwnResults($a_value)
6198 {
6199 $this->view_own_results = (bool)$a_value;
6200 }
6201
6203 {
6205 }
6206
6207 function setMailOwnResults($a_value)
6208 {
6209 $this->mail_own_results = (bool)$a_value;
6210 }
6211
6213 {
6215 }
6216
6217 function setMailConfirmation($a_value)
6218 {
6219 $this->mail_confirmation = (bool)$a_value;
6220 }
6221
6223 {
6225 }
6226
6227 function setAnonymousUserList($a_value)
6228 {
6229 $this->anon_user_list = (bool)$a_value;
6230 }
6231
6233 {
6234 return $this->anon_user_list;
6235 }
6236
6237 public static function getSurveySkippedValue()
6238 {
6239 global $lng;
6240
6241 // #13541
6242
6243 include_once "./Services/Administration/classes/class.ilSetting.php";
6244 $surveySetting = new ilSetting("survey");
6245 if(!$surveySetting->get("skipped_is_custom", false))
6246 {
6247 return $lng->txt("skipped");
6248 }
6249 else
6250 {
6251 return $surveySetting->get("skipped_custom_value", "");
6252 }
6253 }
6254
6256 {
6257 $res = array();
6258
6259 include_once "Services/Mail/classes/class.ilMailTemplateDataProvider.php";
6260 include_once "Modules/Survey/classes/class.ilSurveyMailTemplateReminderContext.php";
6261 $mprov = new ilMailTemplateDataProvider();
6262 foreach($mprov->getTemplateByContexId(ilSurveyMailTemplateReminderContext::ID) as $tmpl)
6263 {
6264 $res[$tmpl->getTplId()] = $tmpl->getTitle();
6265 }
6266
6267 return $res;
6268 }
6269
6270 protected function sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
6271 {
6272 // see ilMail::replacePlaceholders()
6273 include_once "Modules/Survey/classes/class.ilSurveyMailTemplateReminderContext.php";
6274
6275 try
6276 {
6277 require_once 'Services/Mail/classes/class.ilMailTemplateService.php';
6279
6280 $user = new ilObjUser($a_user_id);
6281
6282 require_once 'Services/Mail/classes/class.ilMailTemplatePlaceholderResolver.php';
6283 require_once 'Services/Mail/classes/class.ilMailFormCall.php';
6284 $processor = new ilMailTemplatePlaceholderResolver($context, $a_message);
6285 $a_message = $processor->resolve($user, ilMailFormCall::getContextParameters());
6286
6287 }
6288 catch(Exception $e)
6289 {
6290 require_once './Services/Logging/classes/public/class.ilLoggerFactory.php';
6291 ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
6292 }
6293
6294 return $a_message;
6295 }
6296
6297} // END class.ilObjSurvey
6298
6299?>
sprintf('%.4f', $callTime)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
for($col=0; $col< 50; $col++) $d
$result
$error
Definition: Error.php:17
$size
Definition: RandomTest.php:79
$total
Definition: Utf8Test.php:87
$files
Definition: add-vimline.php:18
$_GET["client_id"]
$_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)
Format a date @access public.
@classDescription Date and time handling
Class for single dates.
Import class.
static _getLanguageOfUser($a_usr_id)
Get language object of user.
static getLogger($a_component_id)
Get component logger.
Class ilMailTemplateDataProvider.
This class handles base functions for mail handling.
static _getUsedHTMLTagsAsString($a_module="")
Returns a string of all allowed HTML tags for text editing.
Class ilObjMediaObject.
static _saveUsage($a_mob_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
Save usage of mob within another container (e.g.
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
static _removeUsage($a_mob_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
Remove usage of mob in another container.
static _saveTempFileAsMediaObject($name, $tmp_name, $upload=TRUE)
Create new media object and update page in db and return new media object.
static _getAvailableQuestionpools($use_object_id=FALSE, $could_be_offline=FALSE, $showPath=FALSE, $permission="read")
Returns the available question pools for the active user.
setShowQuestionTitles($a_show)
Sets the status of the display_question_titles attribute.
isAccessibleWithoutCode()
Checks if the survey is accessable without a survey code.
setAuthor($author="")
Sets the authors name of the ilObjSurvey object.
setActivationVisibility($a_value)
const MODE_PREDEFINED_USERS
getUserAccessCode($user_id)
Returns a survey access code that was saved for a registered user.
getParticipantTextResults($active_id)
deleteConstraints($question_id)
Deletes the constraints for a question.
insertQuestion($question_id)
Inserts a question in the survey and saves the relation to the database.
const EVALUATION_ACCESS_PARTICIPANTS
finishSurvey($finished_id)
Finishes the survey creating an entry in the database.
getActiveID($user_id, $anonymize_id, $appr_id)
Checks if a user already started a survey.
setTutorNotificationStatus($a_value)
deleteAppraisee($a_user_id)
deleteSurveyCode($survey_code)
Deletes a given survey access code.
getExportDirectory()
get export directory of survey
getStatus()
Gets the survey status.
removeConstraintsConcerningQuestion($question_id)
Remove constraints concerning a question with a given question_id.
isOffline()
Gets the survey status.
getInvitation()
Gets the invitation status.
getAnonymize()
get anonymize status
& getAvailableQuestionpools($use_obj_id=false, $could_be_offline=false, $showPath=FALSE, $permission="read")
Returns the available question pools for the active user.
getConstraints($question_id)
Returns the constraints to a given question or questionblock.
addQuestion($question_id)
Adds a question to the survey (used in importer!)
canStartSurvey($anonymous_id=NULL, $a_no_rbac=false)
Checks if the survey can be started.
prepareTextareaOutput($txt_output)
Prepares a string for a text area output in surveys.
getQuestionType($question_id)
Returns the question type of a question with a given id.
setIntroduction($introduction="")
Sets the introduction text.
showQuestionTitles()
Sets the question titles visible during the query.
setMailOwnResults($a_value)
deleteWorkingData($question_id, $active_id)
Deletes the working data of a question in the database.
setActivationLimited($a_value)
createImportDirectory()
creates data directory for import files (data_dir/svy_data/svy_<id>/import, depending on data directo...
setStartDateAndTime($start_date="", $start_time)
Sets the start date of the survey.
setInvitationMode($invitation_mode=0)
Sets the invitation mode.
hasAnonymizedResults()
Checks if the survey results are to be anonymized.
updateConstraint($precondition_id, $if_question_id, $relation, $value, $conjunction)
Updates a precondition.
findCodeForUser($a_user_id)
setTutorNotificationTarget($a_value)
disinviteUser($user_id)
Disinvites a user from a survey.
updateCode($a_id, $a_email, $a_last_name, $a_first_name, $a_sent)
loadQuestionsFromDb()
Loads the survey questions from the database.
static _getConstraints($survey_id)
Returns the constraints to a given question or questionblock.
setMailAddresses($a_addresses)
addQuestionToBlock($question_id, $questionblock_id)
__construct($a_id=0, $a_call_by_reference=true)
Constructor @access public.
processPrintoutput2FO($print_output)
Convert a print output to XSL-FO.
setActivationStartDate($starting_time=NULL)
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)
setActivationEndDate($ending_time=NULL)
getRatersData($a_appraisee_id)
createSurveyCodesForExternalData($data)
& getQuestionpoolTitles($could_be_offline=FALSE, $showPath=FALSE)
Get the titles of all available survey question pools.
getQuestionGUI($questiontype, $question_id)
Returns a question gui object to a given questiontype and question id.
createMetaData()
Create meta data entry.
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.
setObligatoryStates($obligatory_questions)
Sets the obligatory states for questions in a survey from the questions form.
isRater($a_appraisee_id, $a_user_id, $a_anonymous_id=0)
cloneObject($a_target_id, $a_copy_id=0, $a_omit_tree=false)
Clone object.
saveHeading($heading="", $insertbefore)
getFinishedIdForAppraiseeIdAndRaterId($a_appr_id, $a_rat_id)
Get finished id for an appraisee and a rater.
addRater($a_appraisee_id, $a_user_id, $a_anonymous_id=0)
deleteConstraint($constraint_id)
Deletes a constraint of a question.
getUserSurveyExecutionStatus($a_code=null)
const NOTIFICATION_INVITED_USERS
static _instanciateQuestion($question_id)
Creates an instance of a question with a given question id.
getInvitationMode()
Gets the invitation mode.
locateImportFiles($a_dir)
Locates the import directory and the xml file in a directory with an unzipped import file.
sendCodes($not_sent, $subject, $message, $lang)
duplicateQuestionForSurvey($question_id, $a_force=false)
Takes a question and creates a copy of the question for use in the survey.
isHTML($a_text)
Checks if a given string contains HTML or not.
getWorkingtimeForParticipant($finished_id)
checkConstraint($constraint_data, $working_data)
Checks if a constraint is valid.
setSurveyId($survey_id)
Sets the survey id.
disinviteAllUsers()
Disinvite all users.
setReminderStart(ilDate $a_value=null)
deleteAllUserData()
Deletes all user data of a survey.
const NOTIFICATION_PARENT_COURSE
setMailConfirmation($a_value)
const EVALUATION_ACCESS_ALL
closeAppraisee($a_user_id)
setStatus($status=self::STATUS_OFFLINE)
Sets the survey status.
deleteRater($a_appraisee_id, $a_user_id, $a_anonymous_id=0)
setMailNotification($a_notification)
getTextblock($question_id)
setReminderTemplate($a_value)
applySettingsTemplate($template_id)
Apply settings template.
isUnusedCode($a_code, $a_user_id)
setMailParticipantData($a_data)
setInvitation($invitation=0)
Sets the invitation status.
moveQuestions($move_questions, $target_index, $insert_mode)
Move questions and/or questionblocks to another position.
isAnonymizedParticipant($key)
updateConjunctionForQuestions($questions, $conjunction)
set360Results($a_value)
getQuestionblocksTable($arrFilter)
Calculates the data for the output of the questionblock browser.
isAppraisee($a_user_id)
isPoolActive()
Get current pool status.
getUserSettings($usr_id, $key)
getFinishedIdsForAppraiseeId($a_appr_id, $a_exclude_appraisee=false)
const QUESTIONTITLES_VISIBLE
isQuestionInSurvey($a_question_fi)
Check if a question is already in the survey.
& getInvitedUsers()
Returns a list of all invited users in a survey.
getExternalCodeRecipients($a_check_finished=false)
& getSurveyParticipants($finished_ids=null, $force_non_anonymous=false)
toXML()
Returns a QTI xml representation of the survey.
getEvaluationAccess()
Gets the learners evaluation access.
createQuestionblock($title, $show_questiontext, $show_blocktitle, $questions)
Creates a question block for the survey.
static _hasDatasets($survey_id)
getAnonymousIdByCode($a_code)
getLastAccess($finished_id)
getAppraiseesToRate($a_user_id, $a_anonymous_id=null)
& getSurveyPages()
Returns the survey pages in an array (a page contains one or more questions)
saveToDb()
Saves a survey object to a database.
insertQuestionblock($questionblock_id)
Inserts a questionblock in the survey and saves the relation to the database.
hideQuestionTitles()
Sets the question titles hidden during the query.
setAnonymousUserList($a_value)
const ANONYMIZE_FREEACCESS
saveQuestionsToDb()
Saves the survey questions to the database.
modifyQuestionblock($questionblock_id, $title, $show_questiontext, $show_blocktitle)
Modifies a question block.
updateOrder(array $a_order)
createNewAccessCode()
Returns a new, unused survey access code.
read()
read object data from db into object @access public
loadFromDb()
Loads a survey object from a database.
static _getQuestionblock($questionblock_id)
Returns the database row for a given question block.
setStartTime($finished_id, $first_question)
getQuestionsTable($arrFilter)
Calculates the data for the output of the question browser.
sendNotificationMail($user_id, $anonymize_id, $appr_id)
saveUserSettings($usr_id, $key, $title, $value)
unfoldQuestionblocks($questionblocks)
Unfolds question blocks of a question pool.
deliverPDFfromFO($fo)
Delivers a PDF file from a XSL-FO string.
is360SurveyStarted($appr_id, $user_id, $anonymous_code=null)
removeSelectedSurveyResults($finished_ids)
Deletes the user data of a given array of survey participants.
setViewOwnResults($a_value)
& getSurveyQuestions($with_answers=false)
Returns the survey questions and questionblocks in an array.
getSurveyId()
Returns the survey database id.
setStartDate($start_date="")
Sets the start date of the survey.
removeQuestionFromBlock($question_id, $questionblock_id)
getUserSpecificResults($finished_ids)
Calculates the evaluation data for the user specific results.
sentReminderPlaceholders($a_message, $a_user_id, array $a_context_params)
setInvitationAndMode($invitation=0, $invitation_mode=0)
Sets the invitation status and mode (a more performant solution if you change both)
update()
update object data
setEvaluationAccess($evaluation_access=self::EVALUATION_ACCESS_OFF)
Sets the learners evaluation access.
getEndDate()
Gets the end date of the survey.
set360SelfEvaluation($a_value)
setPoolUsage($a_value)
setTutorNotificationRecipients(array $a_value)
isComplete()
Returns 1, if a survey is complete for use.
getSurveyCodesForExport(array $a_codes=null, array $a_ids=null)
Returns a list of survey codes for file export.
getUserDataFromActiveId($active_id, $force_non_anonymous=false)
Returns the user information from an active_id (survey_finished.finished_id)
setReminderTarget($a_value)
set360RaterSent($a_appraisee_id, $a_user_id, $a_anonymous_id, $a_tstamp=null)
saveCompletionStatus()
Saves the completion status of the survey.
static getSurveySkippedValue()
getAllRelations($short_as_key=false)
Returns all available relations.
getNextPage($active_page_question_id, $direction)
Returns the next "page" of a running test.
const EVALUATION_ACCESS_OFF
& getUserData($ids)
Returns a data of all users specified by id list.
createReference()
creates reference for object
static validateExternalRaterCode($a_ref_id, $a_code)
removeQuestion($question_id)
Remove a question from the survey.
set360Mode($a_value)
bindSurveyCodeToUser($user_id, $code)
& getEvaluationByUser($questions, $active_id)
Calculates the evaluation data for a given user or anonymous id.
getStartDate()
Gets the start date of the survey.
static _addQuestionblock($title="", $owner=0, $show_questiontext=true, $show_blocktitle=false)
Adds a questionblock to the database.
& getVariables($question_id)
Returns all variables of a question.
getImportDirectory()
get import directory of survey
deleteSurveyRecord()
Deletes the survey from the database.
getSurveyCodesTableData(array $ids=null, $lang=null)
Fetches the data for the survey codes table.
getNotificationTargetUserIds($a_use_invited)
setReminderStatus($a_value)
startSurvey($user_id, $anonymous_id, $appraisee_id)
Starts the survey creating an entry in the database.
& 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.
removeQuestions($remove_questions, $remove_questionblocks)
Remove questions from the survey.
sentReminder(array $a_recipient_ids)
fixSequenceStructure()
Remove duplicate sequence entries, see #22018.
const ANONYMIZE_CODE_ALL
& getSurveyFinishedIds()
Get the finished id's of all survey participants.
set360SelfAppraisee($a_value)
getLastActivePage($active_id)
Returns the question id of the last active page a user visited in a survey.
getIntroduction()
Gets the introduction text.
setReminderEnd(ilDate $a_value=null)
setEndDateAndTime($end_date="", $end_time)
Sets the end date of the survey.
setEndDate($end_date="")
Sets the end date of the survey.
setTemplate($template_id)
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.
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.
set360SelfRaters($a_value)
getAnonymousId($id)
Checks for an anomyous survey id in the database an returns the id.
setEndTime($finished_id)
loadWorkingData($question_id, $active_id)
Gets the working data of question from the database.
isAppraiseeClosed($a_user_id)
addConstraintToQuestion($to_question_id, $constraint_id)
Adds a constraint to a question.
set360SkillService($a_val)
Set skill service.
createExportDirectory()
creates data directory for export files (data_dir/svy_data/svy_<id>/export, depending on data directo...
isOnline()
Gets the survey status.
setPage($finished_id, $page_id)
Sets the number of the active survey page.
saveAuthorToMetadata($a_author="")
Saves an authors name into the lifecycle metadata if no lifecycle metadata exists This will only be c...
get360SkillService()
Get skill service.
canExportSurveyCode()
Checks if the survey code can be exported with the survey evaluation.
importObject($file_info, $svy_qpl_id)
Imports a survey from XML into the ILIAS database.
isPluginActive($a_pname)
Checks whether or not a question plugin with a given name is active.
inviteUser($user_id)
Invites a user to a survey.
const QUESTIONTITLES_HIDDEN
static _lookupEmail($a_user_id)
Lookup email.
static _getUserData($a_internalids)
return user data for given user ids
static _lookupLogin($a_user_id)
lookup login
static _dropDesktopItem($a_usr_id, $a_item_id, $a_type)
drop an item from user's personal desktop
static _lookupName($a_user_id)
lookup user name
static _lookupFullname($a_user_id)
Lookup Full Name.
static _addDesktopItem($a_usr_id, $a_item_id, $a_type, $a_par="")
add an item to user's personal desktop
Class ilObjectActivation.
setTimingType($a_type)
Set timing type.
static getItem($a_ref_id)
Get item data.
static getInstance($a_obj_id)
Class ilObject Basic functions for all objects.
getType()
get object type @access public
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
deleteMetaData()
delete meta data entry
updateMetaData()
update meta data entry
getRefId()
get reference id @access public
getDescription()
get object description
cloneMetaData($target_obj)
Copy meta data.
getId()
get object id @access public
getTitle()
get object title @access public
countReferences()
count references of object
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
static factory($a_package, $a_timeout=0)
Creates an ilRpcClient instance to our ilServer.
ILIAS Setting Class.
Settings template application class.
Survey exception class.
Skill/Competence handling in surveys.
Wrapper classes for system notifications.
static getNamePresentation($a_user_id, $a_user_image=false, $a_profile_link=false, $a_profile_back_link="", $a_force_first_lastname=false, $a_omit_login=false, $a_sortable=true, $a_return_data_array=false)
Default behaviour is:
static is_email($a_email)
This preg-based function checks whether an e-mail address is formally valid.
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 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 sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
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 ilTempnam($a_temp_path=null)
Create a temporary file in an ILIAS writable directory.
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
static unzip($a_file, $overwrite=false, $a_flat=false)
unzip file
static stripSlashes($a_str, $a_strip_html=true, $a_allow="")
strip slashes if magic qoutes is enabled
static makeDirParents($a_dir)
Create a new directory and all parent directories.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
XML writer class.
xmlHeader()
Writes xml header @access public.
$counter
$y
Definition: example_007.php:83
$h
$text
$params
Definition: example_049.php:96
$code
Definition: example_050.php:99
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
const INVITATION_ON
const INVITATION_OFF
xslt_error(&$proc)
xslt_free(&$proc)
xslt_create()
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang
Definition: langwiz.php:349
$messages
Definition: en-x-test.php:7
$old
$insert
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
$url
Definition: shib_logout.php:72
global $ilDB
global $DIC
$mobs
$ilUser
Definition: imgupload.php:18