aboutsummaryrefslogtreecommitdiff
path: root/app/controllers/questionnaire.php
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:07:19 +0200
committerJan-Hendrik Willms <tleilax+github@gmail.com>2021-07-22 16:19:12 +0200
commita3da1483a9e689846179159355badfec8073dbec (patch)
tree770dcca6bdf5f6f2a11b0e7fcbbeda6919a3fc52 /app/controllers/questionnaire.php
current code from svn, revision 62608
Diffstat (limited to 'app/controllers/questionnaire.php')
-rw-r--r--app/controllers/questionnaire.php960
1 files changed, 960 insertions, 0 deletions
diff --git a/app/controllers/questionnaire.php b/app/controllers/questionnaire.php
new file mode 100644
index 0000000..f407c07
--- /dev/null
+++ b/app/controllers/questionnaire.php
@@ -0,0 +1,960 @@
+<?php
+
+require_once 'lib/classes/QuestionType.interface.php';
+
+class QuestionnaireController extends AuthenticatedController
+{
+ protected $allow_nobody = true; //nobody is allowed
+
+ public function before_filter(&$action, &$args)
+ {
+ parent::before_filter($action, $args);
+ if ($action !== 'courseoverview' && Navigation::hasItem('/contents/questionnaire')) {
+ Navigation::activateItem('/contents/questionnaire');
+ }
+ PageLayout::setTitle(_('Fragebögen'));
+
+ //trigger autoloading:
+ class_exists('Vote');
+ class_exists('Test');
+ class_exists('Freetext');
+ }
+
+ public function overview_action()
+ {
+ if (Navigation::hasItem('/contents/questionnaire/overview')) {
+ Navigation::activateItem('/contents/questionnaire/overview');
+ }
+
+ if (!$GLOBALS['perm']->have_perm('autor')) {
+ throw new AccessDeniedException('Only for logged in users.');
+ }
+ $this->questionnaires = Questionnaire::findBySQL("user_id = ? ORDER BY mkdate DESC", [$GLOBALS['user']->id]);
+ foreach ($this->questionnaires as $questionnaire) {
+ if (!$questionnaire['visible'] && $questionnaire->isRunning()) {
+ $questionnaire->start();
+ }
+ if ($questionnaire['visible'] && $questionnaire->isStopped()) {
+ $questionnaire->stop();
+ }
+ }
+ }
+
+ public function courseoverview_action()
+ {
+ $this->range_type = Course::findCurrent() ? 'course' : 'institute';
+ if (($this->range_type === "institute") && $GLOBALS['perm']->have_perm('admin')) {
+ if (!Context::get()->id) {
+ Navigation::activateItem('/admin/institute/questionnaires');
+ }
+ require_once 'lib/admin_search.inc.php';
+ }
+ if (!$GLOBALS['perm']->have_studip_perm("tutor", Context::get()->id)) {
+ throw new AccessDeniedException("Only for logged in users.");
+ }
+ Navigation::activateItem("/course/admin/questionnaires");
+ $this->statusgruppen = Statusgruppen::findByRange_id(Context::get()->id);
+ $this->questionnaires = Questionnaire::findBySQL(
+ "INNER JOIN questionnaire_assignments USING (questionnaire_id) WHERE (questionnaire_assignments.range_id = ? AND questionnaire_assignments.range_type = ?) OR (questionnaire_assignments.range_id IN (?) AND questionnaire_assignments.range_type = 'statusgruppe') ORDER BY questionnaires.mkdate DESC",
+ [Context::get()->id, $this->range_type, array_map(function ($g) { return $g->getId(); }, $this->statusgruppen)]
+ );
+ foreach ($this->questionnaires as $questionnaire) {
+ if (!$questionnaire['visible'] && $questionnaire->isRunning()) {
+ $questionnaire->start();
+ }
+ if ($questionnaire['visible'] && $questionnaire->isStopped()) {
+ $questionnaire->stop();
+ }
+ }
+ $this->render_action("overview");
+ }
+
+ public function thank_you_action()
+ {
+
+ }
+
+ public function add_to_context_action()
+ {
+ $this->statusgruppen = Statusgruppen::findByRange_id(Context::get()->id);
+ if (!count($this->statusgruppen)) {
+ $this->redirect(
+ $this->url_for("questionnaire/edit", [
+ 'range_type' => Context::getType(),
+ 'range_id' => Context::get()->id
+ ]));
+ return;
+ }
+ PageLayout::setTitle(_("Kontext auswählen"));
+ }
+
+ public function edit_action($questionnaire_id = null)
+ {
+ if (!$GLOBALS['perm']->have_perm("autor")) {
+ throw new AccessDeniedException("Only for authors.");
+ }
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if ($this->questionnaire->isNew()) {
+ PageLayout::setTitle(_("Neuer Fragebogen"));
+ } else {
+ PageLayout::setTitle(_("Fragebogen bearbeiten: ").$this->questionnaire['title']);
+ }
+ if (!$this->questionnaire->isEditable()) {
+ throw new AccessDeniedException(_('Fragebogen ist nicht bearbeitbar.'));
+ }
+ if ($this->questionnaire->isRunning() && $this->questionnaire->countAnswers() > 0) {
+ $this->render_text(
+ MessageBox::error(_("Fragebogen ist gestartet worden und kann jetzt nicht mehr bearbeitet werden. Stoppen oder löschen Sie den Fragebogen stattdessen."))
+ );
+ return;
+ }
+ if (Request::isPost()) {
+ $neworder = array_flip(Request::getArray("neworder"));
+ $order = array_flip(json_decode(Request::get("order"), true));
+ $questionnaire_data = Request::getArray("questionnaire");
+ $questionnaire_data['startdate'] = $questionnaire_data['startdate']
+ ? (strtotime($questionnaire_data['startdate']) ?: time())
+ : null;
+ $questionnaire_data['stopdate'] = strtotime($questionnaire_data['stopdate']) ?: null;
+ $questionnaire_data['copyable'] = (int) $questionnaire_data['copyable'];
+ $questionnaire_data['anonymous'] = (int) $questionnaire_data['anonymous'];
+ $questionnaire_data['editanswers'] = $questionnaire_data['anonymous'] ? 0 : (int) $questionnaire_data['editanswers'];
+ if ($this->questionnaire->isNew()) {
+ $questionnaire_data['visible'] = ($questionnaire_data['startdate'] <= time() && (!$questionnaire_data['stopdate'] || $questionnaire_data['stopdate'] >= time())) ? 1 : 0;
+ }
+ $this->questionnaire->setData($questionnaire_data);
+ $question_types_data = Request::getArray("question_types");
+ foreach ($question_types_data as $question_id => $question_type) {
+ $question = null;
+ foreach ($this->questionnaire->questions as $index => $q) {
+ if ($q->getId() === $question_id) {
+ $question = $q;
+ break;
+ }
+ }
+ if (!$question) {
+ $question = new $question_type($question_id);
+ $this->questionnaire->questions[] = $question;
+ }
+ $question['position'] = $neworder[$question_id] + 1;
+ $question->createDataFromRequest();
+ }
+ foreach ($this->questionnaire->questions as $q) {
+ if (!in_array($q->getId(), array_keys($question_types_data))) {
+ $q->delete();
+ }
+ }
+ if (Request::submitted("questionnaire_store")) {
+ //save everything
+ $is_new = $this->questionnaire->isNew();
+ if ($is_new) {
+ $this->questionnaire['user_id'] = $GLOBALS['user']->id;
+ }
+ $this->questionnaire->store();
+
+ if ($is_new && Request::get("range_id") && Request::get("range_type")) {
+ if (Request::get("range_id") === "start" && !$GLOBALS['perm']->have_perm("root")) {
+ throw new Exception(_("Der Fragebogen darf nicht von Ihnen auf die Startseite eingehängt werden, sondern nur von einem Admin."));
+ }
+ if (Request::get("range_type") === "course" && !$GLOBALS['perm']->have_studip_perm("tutor", Request::get("range_id"))) {
+ throw new Exception(_("Der Fragebogen darf nicht in die ausgewählte Veranstaltung eingebunden werden."));
+ }
+ if (Request::get("range_type") === "user" && Request::get("range_id") !== $GLOBALS['user']->id) {
+ throw new Exception(_("Der Fragebogen darf nicht in diesen Bereich eingebunden werden."));
+ }
+ $assignment = new QuestionnaireAssignment();
+ $assignment['questionnaire_id'] = $this->questionnaire->getId();
+ $assignment['range_id'] = Request::option("range_id");
+ $assignment['range_type'] = Request::get("range_type");
+ $assignment['user_id'] = $GLOBALS['user']->id;
+ $assignment->store();
+ }
+ if ($is_new) {
+ $message = MessageBox::success(_("Der Fragebogen wurde erfolgreich erstellt."));
+ } else {
+ $message = MessageBox::success(_("Der Fragebogen wurde gespeichert."));
+ }
+ if (Request::isAjax()) {
+ $this->questionnaire->restore();
+ $this->questionnaire->resetRelation("assignments");
+ $output = [
+ 'questionnaire_id' => $this->questionnaire->getId(),
+ 'overview_html' => $this->render_template_as_string("questionnaire/_overview_questionnaire.php"),
+ 'widget_html' => $this->questionnaire->isStarted()
+ ? $this->render_template_as_string("questionnaire/_widget_questionnaire.php")
+ : "",
+ 'message' => $message->__toString()
+ ];
+ $this->response->add_header("X-Dialog-Close", 1);
+ $this->response->add_header("X-Dialog-Execute", "STUDIP.Questionnaire.updateOverviewQuestionnaire");
+ $this->render_json($output);
+ } else {
+ PageLayout::postMessage($message);
+ if (Request::get("range_type") === "user") {
+ $this->redirect("profile");
+ } elseif (Request::get("range_type") === "course") {
+ $this->redirect("course/overview");
+ } elseif (Request::get("range_id") === "start") {
+ $this->redirect("start");
+ } else {
+ $this->redirect("questionnaire/overview");
+ }
+ }
+ }
+ return;
+ }
+
+ $statement = DBManager::get()->prepare("
+ SELECT question_id
+ FROM questionnaire_questions
+ WHERE questionnaire_questions.questionnaire_id = ?
+ ORDER BY position ASC
+ ");
+ $statement->execute(array($this->questionnaire->getId()));
+ $this->order = $statement->fetchAll(PDO::FETCH_COLUMN, 0);
+ }
+
+ public function copy_action($from)
+ {
+ $this->old_questionnaire = Questionnaire::find($from);
+ if (!$this->old_questionnaire->isCopyable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht kopierbar.'));
+ }
+ $this->questionnaire = new Questionnaire();
+ $this->questionnaire->setData($this->old_questionnaire->toArray());
+ $this->questionnaire->setId($this->questionnaire->getNewId());
+ $this->questionnaire['user_id'] = $GLOBALS['user']->id;
+ $this->questionnaire['startdate'] = null;
+ $this->questionnaire['stopdate'] = null;
+ $this->questionnaire['mkdate'] = time();
+ $this->questionnaire['chdate'] = time();
+ $this->questionnaire->store();
+ foreach ($this->old_questionnaire->questions as $question) {
+ $new_question = QuestionnaireQuestion::build($question->toArray());
+ $new_question->setId($new_question->getNewId());
+ $new_question['questionnaire_id'] = $this->questionnaire->getid();
+ $new_question['mkdate'] = time();
+
+ $etask = new \eTask\Task();
+ $etask->setData($question->etask->toRawArray());
+ $etask->setId(null); //to get a new integer id
+ $etask->store();
+ $new_question['etask_task_id'] = $etask->getId();
+
+ $new_question->store();
+ }
+ PageLayout::postSuccess(_('Der Fragebogen wurde kopiert. Wo soll er angezeigt werden?'));
+ $this->redirect("questionnaire/context/".$this->questionnaire->getId());
+ }
+
+ public function delete_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isEditable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht bearbeitbar.'));
+ }
+ $this->questionnaire->delete();
+ PageLayout::postSuccess(_('Der Fragebogen wurde gelöscht.'));
+ if (Request::get("redirect")) {
+ $this->redirect(Request::get("redirect"));
+ } else {
+ $this->redirect("questionnaire/overview");
+ }
+ }
+
+ public function bulkdelete_action()
+ {
+ if (!Request::isPost()) {
+ throw new MethodNotAllowedException();
+ }
+ foreach (Request::getArray("q") as $questionnaire_id) {
+ $questionnaire = new Questionnaire($questionnaire_id);
+ if ($questionnaire->isEditable()) {
+ $questionnaire->delete();
+ }
+ }
+ PageLayout::postSuccess(_('Fragebögen wurden gelöscht.'));
+ if (Request::get("range_type") === "user") {
+ $this->redirect("questionnaire/overview");
+ } elseif (Request::get("range_type") === "course") {
+ $this->redirect("questionnaire/courseoverview");
+ } elseif (Request::get("range_id") === "start") {
+ $this->redirect("start");
+ } else {
+ $this->redirect("questionnaire/overview");
+ }
+ }
+
+ public function add_question_action()
+ {
+ if (!$GLOBALS['perm']->have_perm("autor")) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht einsehbar.'));
+ }
+ $class = Request::get("questiontype");
+ $this->question = new $class();
+ $this->question->setId($this->question->getNewId());
+
+ $template = $this->get_template_factory()->open("questionnaire/_question.php");
+ $template->set_attribute("question", $this->question);
+
+ $output = [
+ 'html' => $template->render(),
+ 'question_id' => $this->question->getId()
+ ];
+ $this->render_json($output);
+ }
+
+ public function answer_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isViewable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht einsehbar.'));
+ }
+ object_set_visit($questionnaire_id, 'vote');
+ $this->range_type = Request::get("range_type");
+ $this->range_id = Request::get("range_id");
+ PageLayout::setTitle(sprintf(_("Fragebogen beantworten: %s"), $this->questionnaire->title));
+ }
+
+ public function evaluate_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isViewable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht einsehbar.'));
+ }
+ object_set_visit($questionnaire_id, 'vote');
+ PageLayout::setTitle(sprintf(_("Fragebogen: %s"), $this->questionnaire->title));
+
+ if (Request::isAjax() && !$_SERVER['HTTP_X_DIALOG']) {
+ PageLayout::clearMessages();
+ }
+ }
+
+ public function stop_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isEditable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht bearbeitbar.'));
+ }
+ $this->questionnaire->stop();
+
+ PageLayout::postSuccess(_('Die Befragung wurde beendet.'));
+ if (Request::get("redirect")) {
+ $this->redirect(Request::get("redirect"));
+ } else {
+ $this->redirect("questionnaire/overview");
+ }
+ }
+
+ public function start_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isEditable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht bearbeitbar.'));
+ }
+ $this->questionnaire->start();
+
+ PageLayout::postSuccess(_("Die Befragung wurde gestartet."));
+ if (Request::get("redirect")) {
+ $this->redirect(Request::get("redirect"));
+ } else {
+ $this->redirect("questionnaire/overview");
+ }
+ }
+
+ public function export_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isEditable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht exportierbar.'));
+ }
+ $csv = [[_("Nummer"), _("Benutzername"), _("Nachname"), _("Vorname"), _("E-Mail")]];
+
+ $results = [];
+ $user_ids = [];
+
+ foreach ($this->questionnaire->questions as $question) {
+ $result = (array) $question->getResultArray();
+ foreach ($result as $frage => $r) {
+ $csv[0][] = $frage;
+ $user_ids = array_merge($user_ids, array_keys($r));
+ $user_ids = array_unique($user_ids);
+ }
+ $results[] = $result;
+ }
+
+ foreach ($user_ids as $key => $user_id) {
+ $user = User::find($user_id);
+ if ($user) {
+ $csv_line = [$key + 1, $user['username'], $user['Nachname'], $user['Vorname'], $user['Email']];
+ } else {
+ $csv_line = [$key + 1, $user_id, '', '', ''];
+ }
+
+ foreach ($results as $result) {
+ foreach ($result as $frage => $value) {
+ $csv_line[] = $value[$user_id];
+ }
+ }
+ $csv[] = $csv_line;
+ }
+ $this->response->add_header('Content-Type', "text/csv");
+ $this->response->add_header('Content-Disposition', "attachment; " . encode_header_parameter('filename', $this->questionnaire['title'].'.csv'));
+ $this->render_text(array_to_csv($csv));
+ }
+
+ public function context_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isEditable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht bearbeitbar.'));
+ }
+ foreach ($this->questionnaire->assignments as $relation) {
+ if ($relation['range_type'] === "user") {
+ $this->profile = $relation;
+ }
+ if ($relation['range_id'] === "public") {
+ $this->public = $relation;
+ }
+ if ($relation['range_id'] === "start") {
+ $this->start = $relation;
+ }
+ }
+ if (Request::isPost()) {
+ if (Request::get("user")) {
+ if (!$this->profile) {
+ $this->profile = new QuestionnaireAssignment();
+ $this->profile['questionnaire_id'] = $this->questionnaire->getId();
+ $this->profile['range_id'] = $GLOBALS['user']->id;
+ $this->profile['range_type'] = "user";
+ $this->profile['user_id'] = $GLOBALS['user']->id;
+ $this->profile->store();
+ }
+ } else {
+ if ($this->profile) {
+ $this->profile->delete();
+ }
+ }
+ if (Request::get("public")) {
+ if (!$this->public) {
+ $this->public = new QuestionnaireAssignment();
+ $this->public['questionnaire_id'] = $this->questionnaire->getId();
+ $this->public['range_id'] = "public";
+ $this->public['range_type'] = "static";
+ $this->public['user_id'] = $GLOBALS['user']->id;
+ $this->public->store();
+ }
+ } else {
+ if ($this->public) {
+ $this->public->delete();
+ }
+ }
+ if ($GLOBALS['perm']->have_perm("root")) {
+ if (Request::get("start")) {
+ if (!$this->start) {
+ $this->start = new QuestionnaireAssignment();
+ $this->start['questionnaire_id'] = $this->questionnaire->getId();
+ $this->start['range_id'] = "start";
+ $this->start['range_type'] = "static";
+ $this->start['user_id'] = $GLOBALS['user']->id;
+ $this->start->store();
+ }
+ } else {
+ if ($this->start) {
+ $this->start->delete();
+ }
+ }
+ }
+ if (Request::option("add_seminar_id") && $GLOBALS['perm']->have_studip_perm("tutor", Request::option("add_seminar_id"))) {
+ $course_assignment = new QuestionnaireAssignment();
+ $course_assignment['questionnaire_id'] = $this->questionnaire->getId();
+ $course_assignment['range_id'] = Request::option("add_seminar_id");
+ $course_assignment['range_type'] = "course";
+ $course_assignment['user_id'] = $GLOBALS['user']->id;
+ $course_assignment->store();
+ }
+ if (Request::option("add_institut_id") && $GLOBALS['perm']->have_studip_perm("admin", Request::option("add_institut_id"))) {
+ $course_assignment = new QuestionnaireAssignment();
+ $course_assignment['questionnaire_id'] = $this->questionnaire->getId();
+ $course_assignment['range_id'] = Request::option("add_institut_id");
+ $course_assignment['range_type'] = "institute";
+ $course_assignment['user_id'] = $GLOBALS['user']->id;
+ $course_assignment->store();
+ }
+ if (Request::option("add_statusgruppe_id") && $GLOBALS['perm']->have_studip_perm("tutor", Statusgruppen::find(Request::option("add_statusgruppe_id"))->range_id)) {
+ $course_assignment = new QuestionnaireAssignment();
+ $course_assignment['questionnaire_id'] = $this->questionnaire->getId();
+ $course_assignment['range_id'] = Request::option("add_statusgruppe_id");
+ $course_assignment['range_type'] = "statusgruppe";
+ $course_assignment['user_id'] = $GLOBALS['user']->id;
+ $course_assignment->store();
+ }
+ foreach (PluginManager::getInstance()->getPlugins("QuestionnaireAssignmentPlugin") as $plugin) {
+ $plugin->storeQuestionnaireAssignments($this->questionnaire);
+ }
+
+ foreach (Request::getArray('remove_sem') as $seminar_id) {
+ if ($GLOBALS['perm']->have_studip_perm('tutor', $seminar_id)) {
+ $course_assignment = QuestionnaireAssignment::findBySeminarAndQuestionnaire($seminar_id, $this->questionnaire->getId());
+ if ($course_assignment) {
+ $course_assignment->delete();
+ }
+ }
+ }
+
+ foreach (Request::optionArray('remove_inst') as $institute_id) {
+ if ($GLOBALS['perm']->have_studip_perm('admin', $institute_id)) {
+ $inst_assignment = QuestionnaireAssignment::findByInstituteAndQuestionnaire($institute_id, $this->questionnaire->id);
+ if ($inst_assignment) {
+ $inst_assignment->delete();
+ }
+ }
+ }
+
+ foreach (Request::optionArray('remove_statusgruppe') as $statusgruppe_id) {
+ if ($GLOBALS['perm']->have_studip_perm("tutor", Statusgruppen::find($statusgruppe_id)->range_id)) {
+ $inst_assignment = QuestionnaireAssignment::findByStatusgruppeAndQuestionnaire($statusgruppe_id, $this->questionnaire->id);
+ if ($inst_assignment) {
+ $inst_assignment->delete();
+ }
+ }
+ }
+
+ PageLayout::postSuccess(_('Die Bereichszuweisungen wurden gespeichert.'));
+ $this->questionnaire->restore();
+ $this->questionnaire->resetRelation("assignments");
+ $output = [
+ 'func' => "STUDIP.Questionnaire.updateOverviewQuestionnaire",
+ 'payload' => [
+ 'questionnaire_id' => $this->questionnaire->getId(),
+ 'overview_html' => $this->render_template_as_string("questionnaire/_overview_questionnaire.php")
+ ]
+ ];
+ $this->response->add_header("X-Dialog-Execute", json_encode($output));
+ }
+ PageLayout::setTitle(sprintf(_("Bereiche für Fragebogen: %s"), $this->questionnaire->title));
+ if ($GLOBALS['perm']->have_perm("root")) {
+ $this->statusgruppesearch = new SQLSearch(
+ "SELECT statusgruppen.statusgruppe_id, CONCAT(seminare.name, ': ', statusgruppen.name) AS search_name
+ FROM statusgruppen
+ INNER JOIN seminare ON (seminare.Seminar_id = statusgruppen.range_id)
+ WHERE CONCAT(seminare.name, ': ', statusgruppen.name) LIKE :input
+ ORDER BY statusgruppen.name ASC ",
+ _("Teilnehmergruppe suchen")
+ );
+ } elseif ($GLOBALS['perm']->have_perm("admin")) {
+ $this->statusgruppesearch = new SQLSearch(
+ "SELECT statusgruppen.statusgruppe_id, CONCAT(seminare.name, ': ', statusgruppen.name) AS search_name
+ FROM statusgruppen
+ INNER JOIN seminare ON (seminare.Seminar_id = statusgruppen.range_id)
+ INNER JOIN seminar_inst ON (seminar_inst.seminar_id = seminare.Seminar_id)
+ INNER JOIN user_inst ON (seminar_inst.institut_id = user_inst.Institut_id AND inst_perms = 'admin')
+ WHERE CONCAT(seminare.name, ': ', statusgruppen.name) LIKE :input
+ AND user_inst.user_id = " . DBManager::get()->quote($GLOBALS['user']->id) . "
+ ORDER BY statusgruppen.name ASC ",
+ _("Teilnehmergruppe suchen")
+ );
+ } else {
+ $this->statusgruppesearch = new SQLSearch(
+ "SELECT statusgruppen.statusgruppe_id, CONCAT(seminare.name, ': ', statusgruppen.name) AS search_name
+ FROM statusgruppen
+ LEFT JOIN seminar_user ON (statusgruppen.range_id = seminar_user.Seminar_id AND seminar_user.status IN ('tutor', 'dozent'))
+ LEFT JOIN seminare ON (seminare.Seminar_id = statusgruppen.range_id)
+ WHERE seminar_user.user_id = " . DBManager::get()->quote($GLOBALS['user']->id) . "
+ AND CONCAT(seminare.name, ': ', statusgruppen.name) LIKE :input
+ ORDER BY statusgruppen.name ASC ",
+ _("Teilnehmergruppe suchen")
+ );
+ }
+ }
+
+ public function widget_action($range_id, $range_type = "course")
+ {
+ if (get_class($this->parent_controller) === __CLASS__) {
+ throw new RuntimeException('widget_action must be relayed');
+ }
+ $this->range_id = $range_id;
+ $this->range_type = $range_type;
+ if (in_array($this->range_id, ["public", "start"])) {
+ $this->range_type = "static";
+ }
+ $statusgruppen_ids = [];
+ if (in_array($this->range_type, ["course", "institute"])) {
+ if ($GLOBALS['perm']->have_studip_perm("tutor", $this->range_id)) {
+ $statusgruppen = Statusgruppen::findByRange_id(Context::get()->id);
+ } else {
+ $statusgruppen = Statusgruppen::findBySQL("INNER JOIN statusgruppe_user USING (statusgruppe_id) WHERE statusgruppen.range_id = ? AND statusgruppe_user.user_id = ? ", [
+ Context::get()->id,
+ $GLOBALS['user']->id
+ ]);
+ }
+ $statusgruppen_ids = array_map(function ($g) { return $g->getId(); }, $statusgruppen);
+ }
+ $statement = DBManager::get()->prepare("
+ SELECT questionnaires.*
+ FROM questionnaires
+ INNER JOIN questionnaire_assignments ON (questionnaires.questionnaire_id = questionnaire_assignments.questionnaire_id)
+ WHERE (
+ questionnaire_assignments.range_id = :range_id
+ AND questionnaire_assignments.range_type = :range_type
+ ) OR (
+ questionnaire_assignments.range_id IN (:statusgruppe_id)
+ AND questionnaire_assignments.range_type = 'statusgruppe'
+ )
+ AND startdate <= UNIX_TIMESTAMP()
+ ORDER BY questionnaires.mkdate DESC
+ ");
+ $statement->execute([
+ 'range_id' => $this->range_id,
+ 'range_type' => $this->range_type,
+ 'statusgruppe_id' => $statusgruppen_ids
+ ]);
+ $this->questionnaire_data = $statement->fetchAll(PDO::FETCH_ASSOC);
+ $stopped_visible = 0;
+ foreach ($this->questionnaire_data as $i => $questionnaire) {
+ $one = Questionnaire::buildExisting($questionnaire);
+ if (!$questionnaire['visible'] && $one->isRunning()) {
+ $one->start();
+ }
+ if ($questionnaire['visible'] && $one->isStopped()) {
+ $one->stop();
+ }
+ if ($one->isStopped() && $one->resultsVisible()) {
+ $stopped_visible++;
+ }
+ if ($one->isStopped() && (!$one->resultsVisible() || !Request::get("questionnaire_showall"))) {
+ unset($this->questionnaire_data[$i]);
+ continue;
+ }
+
+ object_set_visit($questionnaire['questionnaire_id'], 'vote');
+ }
+ if (in_array($this->range_type, ["course", "institute"])
+ && !$GLOBALS['perm']->have_studip_perm("tutor", $this->range_id)
+ && !($stopped_visible || count($this->questionnaire_data))) {
+ $this->render_nothing();
+ }
+ }
+
+
+ /**
+ * The assign action allows assigning multiple questionnaires
+ * to multiple courses.
+ */
+ public function assign_action()
+ {
+ PageLayout::setTitle(_('Fragebögen zuordnen'));
+
+ if (Navigation::hasItem('/contents/questionnaire/assign')) {
+ Navigation::activateItem('/contents/questionnaire/assign');
+ }
+
+ if (!$GLOBALS['perm']->have_perm('admin')) {
+ throw new AccessDeniedException();
+ }
+
+ $user = User::findCurrent();
+
+ $this->available_semesters = Semester::findBySql(
+ 'TRUE ORDER BY beginn DESC'
+ );
+ $this->available_institutes = Institute::getMyInstitutes($user->id);
+ $this->available_course_types = SemType::getTypes();
+ $this->selected_questionnaires = [];
+
+ $this->step = 0;
+
+ //We accept only forms which have been sent via POST!
+ if (Request::isPost()) {
+ CSRFProtection::verifyUnsafeRequest();
+
+ if (Request::submitted('search_courses')) {
+ $this->step = 1;
+ } elseif (Request::submitted('select_courses')) {
+ $this->step = 2;
+ } elseif (Request::submitted('copy') || Request::submitted('assign')) {
+ $this->step = 3;
+ }
+
+ if ($this->step >= 1) {
+ //Step 1: Search for courses.
+ $this->semester_id = Request::get('semester_id');
+ $this->institute_id = Request::get('institute_id');
+ $this->course_type_id = Request::get('course_type_id');
+
+ if ($this->institute_id) {
+ //Check if the user has at least admin permissions on the selected
+ //institute. If not, then don't process the submitted data
+ //any further:
+ if (!$GLOBALS['perm']->have_studip_perm('admin', $this->institute_id, $user->id)) {
+ PageLayout::postError(
+ _('Sie haben unzureichende Berechtigungen an der gewählten Einrichtung! Bitte wählen Sie eine andere Einrichtung!')
+ );
+ $this->step = 0;
+ return;
+ }
+ }
+
+ $this->semester = Semester::find($this->semester_id);
+ if ($this->institute_id) {
+ $this->institute = Institute::find($this->institute_id);
+ }
+
+ $this->error_message = '';
+
+ if (!$this->semester) {
+ PageLayout::postError(_('Es wurde kein gültiges Semester ausgewählt!'));
+ $this->step = 0;
+ return;
+ }
+
+ //Search courses matching the search criteria:
+
+ $sql = 'start_time = :semester_begin ';
+ $sql_array = [
+ 'semester_begin' => $this->semester->beginn
+ ];
+
+ if ($this->institute) {
+ $sql .= 'AND institut_id = :institute_id ';
+ $sql_array['institute_id'] = $this->institute->id;
+ }
+ if ($this->course_type_id) {
+ $sql .= 'AND status = :course_type_id ';
+ $sql_array['course_type_id'] = $this->course_type_id;
+ }
+
+ $sql .= 'ORDER BY name ASC';
+
+ $courses = Course::findBySql($sql, $sql_array);
+
+ $this->found_courses = [];
+
+ //We can only add those courses where the current user
+ //has at least admin permissions:
+ foreach ($courses as $course) {
+ if ($GLOBALS['perm']->have_studip_perm('admin', $course->id, $user_id)) {
+ $this->found_courses[] = $course;
+ }
+ }
+ }
+
+ if ($this->step >= 2) {
+ //Step 2: Courses have been selected. Search for questionnaires.
+ $this->course_id_list = Request::getArray('course_id_list');
+ $this->selected_courses = Course::findMany($this->course_id_list);
+ if (!$this->selected_courses) {
+ PageLayout::postError(
+ _('Es wurde keine Veranstaltung ausgewählt! Bitte mindestens eine Veranstaltung auswählen!')
+ );
+ $this->step = 1;
+ return;
+ }
+ $courses_without_perms = [];
+ foreach ($this->selected_courses as $course) {
+ if (!$GLOBALS['perm']->have_studip_perm('admin', $course->id, $user_id)) {
+ $courses_without_perms[] = $course->getFullName();
+ }
+ }
+
+ if ($courses_without_perms) {
+ PageLayout::postError(
+ ngettext(
+ 'Ihre Berechtigungen reichen nicht, um Fragebögen zu der folgenden Veranstaltung zuweisen zu können:',
+ 'Ihre Berechtigungen reichen nicht, um Fragebögen zu den folgenden Veranstaltungen zuweisen zu können:',
+ count($courses_without_perms)
+ ),
+ $courses_without_perms
+ );
+ $this->step = 1;
+ return;
+ }
+
+ //Get only the questionnaires of the current user:
+ $this->questionnaires = Questionnaire::findBySql(
+ 'user_id = :user_id ORDER BY mkdate DESC',
+ [
+ 'user_id' => $user->id
+ ]
+ );
+ }
+
+ if ($this->step >= 3) {
+ //Step 3: Questionnaires have been selected. Assign them
+ //to the found courses.
+ $this->selected_questionnaire_ids = Request::getArray('selected_questionnaire_ids');
+ $this->delete_dates = Request::get('delete_dates');
+ $this->copy_questionnaires = Request::submitted('copy');
+
+ //Get only the questionnaires of the current user:
+ $this->selected_questionnaires = Questionnaire::findBySql(
+ 'user_id = :user_id AND questionnaire_id IN ( :questionnaire_ids )',
+ [
+ 'user_id' => $user->id,
+ 'questionnaire_ids' => $this->selected_questionnaire_ids
+ ]
+ );
+ if (!$this->selected_questionnaires) {
+ PageLayout::postError(
+ _('Es wurde kein Fragebogen ausgewählt! Bitte mindestens einen Fragebogen auswählen!')
+ );
+ $this->step = 2;
+ return;
+ }
+
+ $errors = [];
+ foreach ($this->selected_courses as $course) {
+ foreach ($this->selected_questionnaires as $questionnaire) {
+ if ($this->copy_questionnaires) {
+ //The questionnaire shall be copied and only the copy
+ //shall be placed inside the course.
+
+ //The following code to copy a questionnaire was copied
+ //from the questionnaire controller's copy_action method.
+ //If that method changes please keep this code "in sync"
+ //with the code from the questionnaire controller to avoid
+ //misbehavior of this plugin.
+ $new_questionnaire = new Questionnaire();
+ $new_questionnaire->setData($questionnaire->toArray());
+ $new_questionnaire->setId($new_questionnaire->getNewId());
+ $new_questionnaire->user_id = $user->id;
+ //Contrary to the original code, copied questionnaires
+ //may still contain the start date and end date of the
+ //original questionnaire.
+ if ($this->delete_dates) {
+ $new_questionnaire->startdate = null;
+ $new_questionnaire->stopdate = null;
+ }
+
+ $new_questionnaire->mkdate = time();
+ $new_questionnaire->chdate = time();
+ $new_questionnaire->store();
+ foreach ($questionnaire->questions as $question) {
+ $new_question = QuestionnaireQuestion::build($question->toArray());
+ $new_question->setId($new_question->getNewId());
+ $new_question->questionnaire_id = $new_questionnaire->id;
+ $new_question->mkdate = time();
+ $new_question->store();
+ }
+
+ $assignment = new QuestionnaireAssignment();
+ $assignment->questionnaire_id = $new_questionnaire->id;
+ $assignment->range_id = $course->id;
+ $assignment->range_type = 'course';
+ $assignment->user_id = $user->id;
+ if (!$assignment->store()) {
+ $errors[] = sprintf(
+ _('Fragebogen "%1$s" konnte nicht in Veranstaltung "%2$s" kopiert werden!'),
+ $new_questionnaire->title,
+ $course->name
+ );
+ }
+ } else {
+ //The questionnaire shall be assigned to the course.
+ //We must check if the association already exists.
+ $assignment = QuestionnaireAssignment::findBySeminarAndQuestionnaire(
+ $course->id,
+ $questionnaire->id
+ );
+
+ if (!$assignment) {
+ //The assignment doesn't exist: create it:
+ $assignment = new QuestionnaireAssignment();
+ $assignment->questionnaire_id = $questionnaire->id;
+ $assignment->range_id = $course->id;
+ $assignment->range_type = 'course';
+ $assignment->user_id = $user->id;
+ if (!$assignment->store()) {
+ $errors[] = sprintf(
+ _('Fragebogen "%1$s" konnte nicht zu Veranstaltung "%2$s" zugeordnet werden!'),
+ htmlReady($questionnaire->title),
+ htmlReady($course->name)
+ );
+ }
+ }
+ }
+ }
+ }
+
+ if ($errors) {
+ PageLayout::postError(
+ _('Beim Zuordnen traten Fehler auf:'),
+ $errors
+ );
+ } else {
+ PageLayout::postSuccess(
+ _('Alle gewählten Fragebögen wurden den gewählten Veranstaltungen zugeordnet!')
+ );
+ }
+ }
+ }
+ }
+
+ public function submit_action($questionnaire_id)
+ {
+ $this->questionnaire = new Questionnaire($questionnaire_id);
+ if (!$this->questionnaire->isViewable()) {
+ throw new AccessDeniedException(_('Der Fragebogen ist nicht einsehbar.'));
+ }
+ $answered_before = $this->questionnaire->isAnswered();
+ if ($this->questionnaire->isAnswerable()) {
+ foreach ($this->questionnaire->questions as $question) {
+ $answer = $question->createAnswer();
+ if (!$answer['question_id']) {
+ $answer['question_id'] = $question->getId();
+ }
+ $answer['user_id'] = $GLOBALS['user']->id;
+ if (!$answer['answerdata']) {
+ $answer['answerdata'] = [];
+ }
+ if ($this->questionnaire['anonymous']) {
+ $answer['user_id'] = 'anonymous';
+ $answer['chdate'] = 1;
+ $answer['mkdate'] = 1;
+ $this->anonAnswers[] = $answer->toArray();
+ $answer['user_id'] = null;
+ }
+ $answer->store();
+ }
+ if ($this->questionnaire['anonymous'] && ($GLOBALS['user']->id !== "nobody")) {
+ $anonymous_answer = new QuestionnaireAnonymousAnswer();
+ $anonymous_answer['questionnaire_id'] = $this->questionnaire->getId();
+ $anonymous_answer['user_id'] = $GLOBALS['user']->id;
+ $anonymous_answer->store();
+ }
+ if (!$answered_before && !$this->questionnaire['anonymous'] && ($this->questionnaire['user_id'] !== $GLOBALS['user']->id)) {
+ $url = URLHelper::getURL("dispatch.php/questionnaire/evaluate/" . $this->questionnaire->getId(), [], true);
+ PersonalNotifications::add(
+ $this->questionnaire['user_id'],
+ $url,
+ sprintf(_("%s hat an der Befragung '%s' teilgenommen."), $GLOBALS['user']->getFullName(), $this->questionnaire['title']),
+ "questionnaire_" . $this->questionnaire->getId(),
+ Icon::create('vote'),
+ true
+ );
+ }
+ }
+
+ if (Request::isAjax()) {
+ $this->response->add_header("X-Dialog-Close", "1");
+ $this->response->add_header("X-Dialog-Execute", "STUDIP.Questionnaire.updateWidgetQuestionnaire");
+ $this->render_template("questionnaire/evaluate");
+ } elseif (Request::get("range_type") === "user") {
+ PageLayout::postMessage(MessageBox::success(_("Danke für die Teilnahme!")));
+ $this->redirect("profile?username=".get_username(Request::option("range_id")));
+ } elseif (Request::get("range_type") === "course") {
+ PageLayout::postMessage(MessageBox::success(_("Danke für die Teilnahme!")));
+ $this->redirect("course/overview?cid=".Request::option("range_id"));
+ } elseif (Request::get("range_id") === "start") {
+ PageLayout::postMessage(MessageBox::success(_("Danke für die Teilnahme!")));
+ $this->redirect("start");
+ } else {
+ PageLayout::postMessage(MessageBox::success(_("Danke für die Teilnahme!")));
+ if ($GLOBALS['perm']->have_perm("autor")) {
+ $this->redirect("questionnaire/overview");
+ } else {
+ $this->redirect("questionnaire/thank_you");
+ }
+ }
+ }
+}