MDL-21695 adding help strings
[moodle.git] / mod / feedback / lib.php
CommitLineData
32be99dc 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Library of functions and constants for module feedback
20 * includes the main-part of feedback-functions
21 *
22 * @package mod-feedback
23 * @copyright Andreas Grabs
24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27/** Include eventslib.php */
3b120e46 28require_once($CFG->libdir.'/eventslib.php');
9f42276c
SH
29/** Include calendar/lib.php */
30require_once($CFG->dirroot.'/calendar/lib.php');
3b120e46 31
c70ad9f7 32
c70ad9f7 33define('FEEDBACK_ANONYMOUS_YES', 1);
34define('FEEDBACK_ANONYMOUS_NO', 2);
35define('FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP', 2);
36define('FEEDBACK_DECIMAL', '.');
37define('FEEDBACK_THOUSAND', ',');
38define('FEEDBACK_RESETFORM_RESET', 'feedback_reset_data_');
39define('FEEDBACK_RESETFORM_DROP', 'feedback_drop_feedback_');
40define('FEEDBACK_MAX_PIX_LENGTH', '400'); //max. Breite des grafischen Balkens in der Auswertung
41
29081d02 42/**
32be99dc 43 * @uses FEATURE_GROUPS
44 * @uses FEATURE_GROUPINGS
45 * @uses FEATURE_GROUPMEMBERSONLY
46 * @uses FEATURE_MOD_INTRO
47 * @uses FEATURE_COMPLETION_TRACKS_VIEWS
48 * @uses FEATURE_GRADE_HAS_GRADE
49 * @uses FEATURE_GRADE_OUTCOMES
29081d02 50 * @param string $feature FEATURE_xx constant for requested feature
51 * @return mixed True if module supports feature, null if doesn't know
52 */
53function feedback_supports($feature) {
54 switch($feature) {
42f103be 55 case FEATURE_GROUPS: return true;
56 case FEATURE_GROUPINGS: return true;
57 case FEATURE_GROUPMEMBERSONLY: return true;
dc5c2bd9 58 case FEATURE_MOD_INTRO: return true;
29081d02 59 case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
42f103be 60 case FEATURE_GRADE_HAS_GRADE: return false;
61 case FEATURE_GRADE_OUTCOMES: return false;
62
29081d02 63 default: return null;
64 }
65}
3b120e46 66
c70ad9f7 67/**
32be99dc 68 * this will create a new instance and return the id number
69 * of the new instance.
70 *
71 * @global object
72 * @param object $feedback the object given by mod_feedback_mod_form
73 * @return int
74 */
c70ad9f7 75function feedback_add_instance($feedback) {
c18269c7 76 global $DB;
c70ad9f7 77
78 $feedback->timemodified = time();
79 $feedback->id = '';
80
81 //check if openenable and/or closeenable is set and set correctly to save in db
82 if(empty($feedback->openenable)) {
83 $feedback->timeopen = 0;
84 }
85 if(empty($feedback->closeenable)) {
86 $feedback->timeclose = 0;
87 }
c184660d 88 if(empty($feedback->site_after_submit)) {
89 $feedback->site_after_submit = '';
90 }
c70ad9f7 91
92 //saving the feedback in db
a8f3a651 93 $feedbackid = $DB->insert_record("feedback", $feedback);
37b86a39 94
95 $feedback->id = $feedbackid;
96
c70ad9f7 97 feedback_set_events($feedback);
37b86a39 98
c70ad9f7 99 return $feedbackid;
100}
101
102/**
32be99dc 103 * this will update a given instance
104 *
105 * @global object
106 * @param object $feedback the object given by mod_feedback_mod_form
107 * @return boolean
108 */
c70ad9f7 109function feedback_update_instance($feedback) {
c18269c7 110 global $DB;
c70ad9f7 111
112 $feedback->timemodified = time();
113 $feedback->id = $feedback->instance;
114
115 //check if openenable and/or closeenable is set and set correctly to save in db
116 if(empty($feedback->openenable)) {
117 $feedback->timeopen = 0;
118 }
119 if(empty($feedback->closeenable)) {
120 $feedback->timeclose = 0;
121 }
c184660d 122 if(empty($feedback->site_after_submit)) {
123 $feedback->site_after_submit = '';
124 }
c70ad9f7 125
126 //save the feedback into the db
9d749339 127 $DB->update_record("feedback", $feedback);
c70ad9f7 128
129 //create or update the new events
130 feedback_set_events($feedback);
37b86a39 131
c70ad9f7 132 return true;
133}
134
a59ff6b0
AG
135/**
136 * Serves the files included in feedback items like label. Implements needed access control ;-)
137 *
138 * @param object $course
139 * @param object $cminfo
140 * @param object $context
141 * @param string $filearea
142 * @param array $args
143 * @param bool $forcedownload
144 * @return bool false if file not found, does not return if found - justsend the file
145 */
146function feedback_pluginfile($course, $cminfo, $context, $filearea, $args, $forcedownload) {
147 global $CFG, $DB;
148
149 if (!$cminfo->uservisible) {
150 return false;
151 }
152
153 if ($filearea === 'feedback_item') {
154 $itemid = (int)array_shift($args);
155
156 if (!$cm = get_coursemodule_from_instance('feedback', $cminfo->instance, $course->id)) {
157 return false;
158 }
159
160 require_course_login($course, true, $cm);
161
162 if (!$item = $DB->get_record('feedback_item', array('id'=>$itemid))) {
163 return false;
164 }
165
166 if (!$feedback = $DB->get_record('feedback', array('id'=>$cminfo->instance))) {
167 return false;
168 }
169
170 if (!has_capability('mod/feedback:view', $context)) {
171 return false;
172 }
173
174 if ($item->feedback == $cminfo->instance) {
175 $filecontext = $context;
176 } else {
177 return false;
178 }
179
180 $relativepath = '/'.implode('/', $args);
181 $fullpath = $filecontext->id.$filearea.$itemid.$relativepath;
182
183 $fs = get_file_storage();
184 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
185 return false;
186 }
187
188 // finally send the file
189 send_stored_file($file, 0, 0, true); // download MUST be forced - security!
190 }
191
192 return false;
193}
194
195
c70ad9f7 196/**
32be99dc 197 * this will delete a given instance.
198 * all referenced data also will be deleted
199 *
200 * @global object
201 * @param int $id the instanceid of feedback
202 * @return boolean
203 */
c70ad9f7 204function feedback_delete_instance($id) {
c18269c7 205 global $DB;
206
c70ad9f7 207 //get all referenced items
c18269c7 208 $feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$id));
37b86a39 209
c70ad9f7 210 //deleting all referenced items and values
211 if (is_array($feedbackitems)){
212 foreach($feedbackitems as $feedbackitem){
c18269c7 213 $DB->delete_records("feedback_value", array("item"=>$feedbackitem->id));
214 $DB->delete_records("feedback_valuetmp", array("item"=>$feedbackitem->id));
c70ad9f7 215 }
c18269c7 216 $DB->delete_records("feedback_item", array("feedback"=>$id));
c70ad9f7 217 }
37b86a39 218
c70ad9f7 219 //deleting the referenced tracking data
c18269c7 220 $DB->delete_records('feedback_tracking', array('feedback'=>$id));
37b86a39 221
c70ad9f7 222 //deleting the completeds
c18269c7 223 $DB->delete_records("feedback_completed", array("feedback"=>$id));
37b86a39 224
c70ad9f7 225 //deleting the unfinished completeds
c18269c7 226 $DB->delete_records("feedback_completedtmp", array("feedback"=>$id));
37b86a39 227
c70ad9f7 228 //deleting old events
c18269c7 229 $DB->delete_records('event', array('modulename'=>'feedback', 'instance'=>$id));
230 return $DB->delete_records("feedback", array("id"=>$id));
c70ad9f7 231}
232
233/**
32be99dc 234 * this is called after deleting all instances if the course will be deleted.
235 * only templates have to be deleted
236 *
237 * @global object
238 * @param object $course
239 * @return boolean
240 */
c70ad9f7 241function feedback_delete_course($course) {
0085fff8 242 global $DB;
243
c70ad9f7 244 //delete all templates of given course
0085fff8 245 return $DB->delete_records('feedback_template', array('course'=>$course->id));
c70ad9f7 246}
247
248/**
32be99dc 249 * Return a small object with summary information about what a
250 * user has done with a given particular instance of this module
251 * Used for user activity reports.
252 * $return->time = the time they did it
253 * $return->info = a short text description
254 *
255 * @param object $course
256 * @param object $user
257 * @param object $mod
258 * @param object $feedback
259 * @return object
260 */
c70ad9f7 261function feedback_user_outline($course, $user, $mod, $feedback) {
0085fff8 262 return null;
c70ad9f7 263}
264
6133bd16 265/**
266 * Returns all users who has completed a specified feedback since a given time
267 * many thanks to Manolescu Dorel, who contributed these two functions
32be99dc 268 *
269 * @global object
270 * @global object
271 * @global object
272 * @global object
273 * @uses CONTEXT_MODULE
274 * @param array $activities Passed by reference
275 * @param int $index Passed by reference
276 * @param int $timemodified Timestamp
277 * @param int $courseid
278 * @param int $cmid
279 * @param int $userid
280 * @param int $groupid
281 * @return void
6133bd16 282 */
283function feedback_get_recent_mod_activity(&$activities, &$index, $timemodified, $courseid, $cmid, $userid="", $groupid="") {
284 global $CFG, $COURSE, $USER, $DB;
285
286 if ($COURSE->id == $courseid) {
287 $course = $COURSE;
288 } else {
76b7b592 289 $course = $DB->get_record('course', array('id'=>$courseid));
6133bd16 290 }
291
292 $modinfo =& get_fast_modinfo($course);
293
294 $cm = $modinfo->cms[$cmid];
69f6d0b4
AG
295
296 $sqlargs = array();
6133bd16 297
69f6d0b4
AG
298 $sql = " SELECT fk . * , fc . * , u.firstname, u.lastname, u.email, u.picture
299 FROM {feedback_completed} fc
300 JOIN {feedback} fk ON fk.id = fc.feedback
301 JOIN {user} u ON u.id = fc.userid ";
6133bd16 302
303 if ($groupid) {
69f6d0b4 304 $sql .= " JOIN {groups_members} gm ON gm.userid=u.id ";
6133bd16 305 }
69f6d0b4
AG
306
307 $sql .= " WHERE fc.timemodified > ? AND fk.id = ? ";
308 $sqlargs[] = $timemodified;
309 $sqlargs[] = $cm->instace;
d4b1d58c 310
69f6d0b4
AG
311 if ($userid) {
312 $sql .= " AND u.id = ? ";
313 $sqlargs[] = $userid;
6133bd16 314 }
315
69f6d0b4
AG
316 if ($groupid) {
317 $sql .= " AND gm.groupid = ? ";
318 $sqlargs[] = $groupid;
319 }
320
321 if (!$feedbackitems = $DB->get_records_sql($sql, $sqlargs)) {
322 return;
323 }
6133bd16 324
325 $cm_context = get_context_instance(CONTEXT_MODULE, $cm->id);
326 $accessallgroups = has_capability('moodle/site:accessallgroups', $cm_context);
327 $viewfullnames = has_capability('moodle/site:viewfullnames', $cm_context);
328 $groupmode = groups_get_activity_groupmode($cm, $course);
329
330 if (is_null($modinfo->groups)) {
331 $modinfo->groups = groups_get_user_groups($course->id); // load all my groups and cache it in modinfo
332 }
333
334 $aname = format_string($cm->name,true);
335 foreach ($feedbackitems as $feedbackitem) {
336 if ($feedbackitem->userid != $USER->id) {
d4b1d58c 337
338 if ($groupmode == SEPARATEGROUPS and !$accessallgroups) {
6133bd16 339 $usersgroups = groups_get_all_groups($course->id, $feedbackitem->userid, $cm->groupingid);
340 if (!is_array($usersgroups)) {
341 continue;
342 }
343 $usersgroups = array_keys($usersgroups);
344 $interset = array_intersect($usersgroups, $modinfo->groups[$cm->id]);
345 if (empty($intersect)) {
346 continue;
347 }
348 }
349 }
350
351 $tmpactivity = new object();
352
353 $tmpactivity->type = 'feedback';
354 $tmpactivity->cmid = $cm->id;
355 $tmpactivity->name = $aname;
356 $tmpactivity->sectionnum= $cm->sectionnum;
357 $tmpactivity->timestamp = $feedbackitem->timemodified;
d4b1d58c 358
6133bd16 359 $tmpactivity->content->feedbackid = $feedbackitem->id;
360 $tmpactivity->content->feedbackuserid = $feedbackitem->userid;
d4b1d58c 361
6133bd16 362 $tmpactivity->user->userid = $feedbackitem->userid;
363 $tmpactivity->user->fullname = fullname($feedbackitem, $viewfullnames);
364 $tmpactivity->user->picture = $feedbackitem->picture;
d4b1d58c 365
6133bd16 366 $activities[$index++] = $tmpactivity;
367 }
368
369 return;
370}
371
372/**
373 * Prints all users who has completed a specified feedback since a given time
374 * many thanks to Manolescu Dorel, who contributed these two functions
32be99dc 375 *
376 * @global object
377 * @param object $activity
378 * @param int $courseid
379 * @param string $detail
380 * @param array $modnames
381 * @return void Output is echo'd
6133bd16 382 */
383function feedback_print_recent_mod_activity($activity, $courseid, $detail, $modnames) {
e63f88c9 384 global $CFG, $OUTPUT;
6133bd16 385
386 echo '<table border="0" cellpadding="3" cellspacing="0" class="forum-recent">';
387
388 echo "<tr><td class=\"userpicture\" valign=\"top\">";
812dbaf7 389 echo $OUTPUT->user_picture($activity->user, array('courseid'=>$courseid));
6133bd16 390 echo "</td><td>";
391
392 if ($detail) {
393 $modname = $modnames[$activity->type];
394 echo '<div class="title">';
b5d0cafc 395 echo "<img src=\"" . $OUTPUT->pix_url('icon', $activity->type) . "\" ".
6133bd16 396 "class=\"icon\" alt=\"$modname\" />";
397 echo "<a href=\"$CFG->wwwroot/mod/feedback/view.php?id={$activity->cmid}\">{$activity->name}</a>";
398 echo '</div>';
399 }
d4b1d58c 400
78946b9b 401 echo '<div class="title">';
6133bd16 402 echo '</div>';
d4b1d58c 403
6133bd16 404 echo '<div class="user">';
405 echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->userid}&amp;course=$courseid\">"
406 ."{$activity->user->fullname}</a> - ".userdate($activity->timestamp);
407 echo '</div>';
408
409 echo "</td></tr></table>";
410
411 return;
412}
413
414
c70ad9f7 415/**
32be99dc 416 * Print a detailed representation of what a user has done with
417 * a given particular instance of this module, for user activity reports.
d4b1d58c 418 *
32be99dc 419 * @param object $course
420 * @param object $user
421 * @param object $mod
422 * @param object $feedback
423 * @return bool
424 */
c70ad9f7 425function feedback_user_complete($course, $user, $mod, $feedback) {
c70ad9f7 426 return true;
427}
428
32be99dc 429/**
430 * @return bool true
431 */
c70ad9f7 432function feedback_cron () {
433 return true;
434}
435
32be99dc 436/**
437 * @return bool false
438 */
c70ad9f7 439function feedback_get_participants($feedbackid) {
c70ad9f7 440 return false;
441}
442
32be99dc 443
444/**
445 * @return bool false
446 */
c70ad9f7 447function feedback_scale_used ($feedbackid,$scaleid) {
0085fff8 448 return false;
c70ad9f7 449}
450
1c57ce25 451/**
452 * This function is used by the reset_course_userdata function in moodlelib.
453 * This function will remove all responses from the specified feedback
454 * and clean up any related data.
32be99dc 455 *
456 * @global object
457 * @global object
458 * @uses FEEDBACK_RESETFORM_RESET
459 * @uses FEEDBACK_RESETFORM_DROP
460 * @param object $data the data submitted from the reset course.
1c57ce25 461 * @return array status array
c70ad9f7 462 */
1c57ce25 463function feedback_reset_userdata($data) {
0085fff8 464 global $CFG, $DB;
37b86a39 465
c70ad9f7 466 $resetfeedbacks = array();
467 $dropfeedbacks = array();
1c57ce25 468 $status = array();
469 $componentstr = get_string('modulenameplural', 'feedback');
37b86a39 470
c70ad9f7 471 //get the relevant entries from $data
472 foreach($data as $key => $value) {
473 switch(true) {
474 case substr($key, 0, strlen(FEEDBACK_RESETFORM_RESET)) == FEEDBACK_RESETFORM_RESET:
475 if($value == 1) {
476 $templist = explode('_', $key);
477 if(isset($templist[3]))$resetfeedbacks[] = intval($templist[3]);
478 }
479 break;
480 case substr($key, 0, strlen(FEEDBACK_RESETFORM_DROP)) == FEEDBACK_RESETFORM_DROP:
481 if($value == 1) {
482 $templist = explode('_', $key);
483 if(isset($templist[3]))$dropfeedbacks[] = intval($templist[3]);
484 }
485 break;
486 }
487 }
37b86a39 488
c70ad9f7 489 //reset the selected feedbacks
490 foreach($resetfeedbacks as $id) {
0085fff8 491 $feedback = $DB->get_record('feedback', array('id'=>$id));
c70ad9f7 492 feedback_delete_all_completeds($id);
1c57ce25 493 $status[] = array('component'=>$componentstr.':'.$feedback->name, 'item'=>get_string('resetting_data','feedback'), 'error'=>false);
c70ad9f7 494 }
37b86a39 495
c70ad9f7 496 //drop the selected feedbacks
1c57ce25 497 // foreach($dropfeedbacks as $id) {
498 // $cm = get_coursemodule_from_instance('feedback', $id);
499 // feedback_delete_instance($id);
500 // feedback_delete_course_module($cm->id);
501 // $status[] = array('component'=>$componentstr, 'item'=>get_string('drop_feedback','feedback'), 'error'=>false);
502 // }
503 return $status;
504}
505
506/**
507 * Called by course/reset.php
32be99dc 508 *
509 * @global object
510 * @uses FEEDBACK_RESETFORM_RESET
511 * @param object $mform form passed by reference
1c57ce25 512 */
513function feedback_reset_course_form_definition(&$mform) {
0085fff8 514 global $COURSE, $DB;
515
1c57ce25 516 $mform->addElement('header', 'feedbackheader', get_string('modulenameplural', 'feedback'));
37b86a39 517
0085fff8 518 if(!$feedbacks = $DB->get_records('feedback', array('course'=>$COURSE->id), 'name')){
1c57ce25 519 return;
c70ad9f7 520 }
1c57ce25 521
522 $mform->addElement('static', 'hint', get_string('resetting_data','feedback'));
523 foreach($feedbacks as $feedback) {
524 $mform->addElement('checkbox', FEEDBACK_RESETFORM_RESET.$feedback->id, $feedback->name);
525 // $mform->addElement('checkbox', FEEDBACK_RESETFORM_DROP.$feedback->id, get_string('drop_feedback','feedback'));
526 }
527}
528
529/**
530 * Course reset form defaults.
32be99dc 531 *
532 * @global object
533 * @uses FEEDBACK_RESETFORM_RESET
534 * @param object $course
1c57ce25 535 */
536function feedback_reset_course_form_defaults($course) {
0085fff8 537 global $DB;
538
1c57ce25 539 $return = array();
0085fff8 540 if(!$feedbacks = $DB->get_records('feedback', array('course'=>$course->id), 'name')){
1c57ce25 541 return;
542 }
543 foreach($feedbacks as $feedback) {
544 $return[FEEDBACK_RESETFORM_RESET.$feedback->id] = true;
545 // $return[FEEDBACK_RESETFORM_DROP.$feedback->id] = false;
546 }
547 return $return;
c70ad9f7 548}
549
37b86a39 550/**
c70ad9f7 551 * Called by course/reset.php and shows the formdata by coursereset.
552 * it prints checkboxes for each feedback available at the given course
553 * there are two checkboxes: 1) delete userdata and keep the feedback 2) delete userdata and drop the feedback
32be99dc 554 *
555 * @global object
556 * @uses FEEDBACK_RESETFORM_RESET
557 * @uses FEEDBACK_RESETFORM_DROP
c70ad9f7 558 * @param object $course
559 * @return void
560 */
561function feedback_reset_course_form($course) {
be96a472 562 global $DB, $OUTPUT;
0085fff8 563
c70ad9f7 564 echo get_string('resetting_feedbacks', 'feedback'); echo ':<br />';
0085fff8 565 if (!$feedbacks = $DB->get_records('feedback', array('course'=>$course->id), 'name')) {
566 return;
567 }
37b86a39 568
c70ad9f7 569 foreach($feedbacks as $feedback) {
570 echo '<p>';
571 echo get_string('name','feedback').': '.$feedback->name.'<br />';
2f0e96e4 572 echo html_writer::checkbox(FEEDBACK_RESETFORM_RESET.$feedback->id, 1, true, get_string('resetting_data','feedback'));
be96a472 573 echo '<br />';
2f0e96e4 574 echo html_writer::checkbox(FEEDBACK_RESETFORM_DROP.$feedback->id, 1, false, get_string('drop_feedback','feedback'));
c70ad9f7 575 echo '</p>';
576 }
577}
578
37b86a39 579/**
32be99dc 580 * This creates new events given as timeopen and closeopen by $feedback.
581 *
582 * @global object
583 * @param object $feedback
584 * @return void
c70ad9f7 585 */
586function feedback_set_events($feedback) {
c18269c7 587 global $DB;
588
c70ad9f7 589 // adding the feedback to the eventtable (I have seen this at quiz-module)
c18269c7 590 $DB->delete_records('event', array('modulename'=>'feedback', 'instance'=>$feedback->id));
c70ad9f7 591
50aa3fcc 592 if (!isset($feedback->coursemodule)) {
593 $cm = get_coursemodule_from_id('feedback', $feedback->id);
594 $feedback->coursemodule = $cm->id;
595 }
596
c70ad9f7 597 // the open-event
598 if($feedback->timeopen > 0) {
599 $event = NULL;
50aa3fcc 600 $event->name = get_string('start', 'feedback').' '.$feedback->name;
601 $event->description = format_module_intro('feedback', $feedback, $feedback->coursemodule);
c70ad9f7 602 $event->courseid = $feedback->course;
603 $event->groupid = 0;
50aa3fcc 604 $event->userid = 0;
605 $event->modulename = 'feedback';
c18269c7 606 $event->instance = $feedback->id;
c70ad9f7 607 $event->eventtype = 'open';
608 $event->timestart = $feedback->timeopen;
609 $event->visible = instance_is_visible('feedback', $feedback);
610 if($feedback->timeclose > 0) {
611 $event->timeduration = ($feedback->timeclose - $feedback->timeopen);
612 } else {
613 $event->timeduration = 0;
614 }
37b86a39 615
9f42276c 616 calendar_event::create($event);
c70ad9f7 617 }
618
619 // the close-event
620 if($feedback->timeclose > 0) {
621 $event = NULL;
50aa3fcc 622 $event->name = get_string('stop', 'feedback').' '.$feedback->name;
623 $event->description = format_module_intro('feedback', $feedback, $feedback->coursemodule);
c70ad9f7 624 $event->courseid = $feedback->course;
625 $event->groupid = 0;
50aa3fcc 626 $event->userid = 0;
627 $event->modulename = 'feedback';
c18269c7 628 $event->instance = $feedback->id;
c70ad9f7 629 $event->eventtype = 'close';
630 $event->timestart = $feedback->timeclose;
631 $event->visible = instance_is_visible('feedback', $feedback);
632 $event->timeduration = 0;
633
9f42276c 634 calendar_event::create($event);
c70ad9f7 635 }
636}
637
37b86a39 638/**
c70ad9f7 639 * this function is called by {@link feedback_delete_userdata()}
640 * it drops the feedback-instance from the course_module table
32be99dc 641 *
642 * @global object
c70ad9f7 643 * @param int $id the id from the coursemodule
644 * @return boolean
645 */
646function feedback_delete_course_module($id) {
0085fff8 647 global $DB;
648
649 if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) {
c70ad9f7 650 return true;
651 }
0085fff8 652 return $DB->delete_records('course_modules', array('id'=>$cm->id));
c70ad9f7 653}
654
655
656
657////////////////////////////////////////////////
658//functions to handle capabilities
659////////////////////////////////////////////////
660
37b86a39 661/**
c70ad9f7 662 * returns the context-id related to the given coursemodule-id
32be99dc 663 *
664 * @staticvar object $context
c70ad9f7 665 * @param int $cmid the coursemodule-id
666 * @return object $context
667 */
668function feedback_get_context($cmid) {
669 static $context;
37b86a39 670
c70ad9f7 671 if(isset($context)) return $context;
37b86a39 672
c70ad9f7 673 if (!$context = get_context_instance(CONTEXT_MODULE, $cmid)) {
674 print_error('badcontext');
675 }
676 return $context;
677}
678
37b86a39 679/**
c70ad9f7 680 * returns true if the current role is faked by switching role feature
32be99dc 681 *
682 * @global object
c70ad9f7 683 * @return boolean
684 */
685function feedback_check_is_switchrole(){
686 global $USER;
687 if(isset($USER->switchrole) AND is_array($USER->switchrole) AND count($USER->switchrole) > 0) {
688 return true;
689 }
690 return false;
691}
692
d4b1d58c 693/**
32be99dc 694 * get users which have the complete-capability
695 *
696 * @global object
697 * @uses CONTEXT_MODULE
698 * @param object $cm
699 * @param int $group single groupid
700 * @return object the userrecords
c70ad9f7 701 */
a600ad35 702function feedback_get_complete_users($cm, $group = false) {
703 global $DB;
d4b1d58c 704
a600ad35 705 if (!$context = get_context_instance(CONTEXT_MODULE, $cm->id)) {
c70ad9f7 706 print_error('badcontext');
707 }
37b86a39 708
a600ad35 709 $params = array($cm->instance);
710
711 $fromgroup = '';
712 $wheregroup = '';
713 if($group) {
714 $fromgroup = ', {groups_members} g';
b68bff82 715 $wheregroup = ' AND g.groupid = ? AND g.userid = c.userid';
a600ad35 716 $params[] = $group;
717 }
718 $sql = 'SELECT u.* FROM {user} u, {feedback_completed} c'.$fromgroup.'
719 WHERE u.id = c.userid AND c.feedback = ?
720 '.$wheregroup.'
721 ORDER BY u.lastname';
a600ad35 722 return $DB->get_records_sql($sql, $params);
c70ad9f7 723}
724
37b86a39 725/**
32be99dc 726 * get users which have the viewreports-capability
727 *
728 * @uses CONTEXT_MODULE
729 * @param int $cmid
730 * @param mixed $groups single groupid or array of groupids - group(s) user is in
731 * @return object the userrecords
c70ad9f7 732 */
733function feedback_get_viewreports_users($cmid, $groups = false) {
734
735 if (!$context = get_context_instance(CONTEXT_MODULE, $cmid)) {
736 print_error('badcontext');
737 }
37b86a39 738
c70ad9f7 739 //description of the call below: get_users_by_capability($context, $capability, $fields='', $sort='', $limitfrom='', $limitnum='', $groups='', $exceptions='', $doanything=true)
740 return get_users_by_capability($context, 'mod/feedback:viewreports', '', 'lastname', '', '', $groups, '', false);
741}
742
37b86a39 743/**
32be99dc 744 * get users which have the receivemail-capability
745 *
746 * @uses CONTEXT_MODULE
747 * @param int $cmid
748 * @param mixed $groups single groupid or array of groupids - group(s) user is in
749 * @return object the userrecords
c184660d 750 */
751function feedback_get_receivemail_users($cmid, $groups = false) {
752
753 if (!$context = get_context_instance(CONTEXT_MODULE, $cmid)) {
754 print_error('badcontext');
755 }
37b86a39 756
c184660d 757 //description of the call below: get_users_by_capability($context, $capability, $fields='', $sort='', $limitfrom='', $limitnum='', $groups='', $exceptions='', $doanything=true)
c65e59ba 758 return get_users_by_capability($context, 'mod/feedback:receivemail', '', 'lastname', '', '', $groups, '', false);
c184660d 759}
760
c70ad9f7 761////////////////////////////////////////////////
762//functions to handle the templates
763////////////////////////////////////////////////
764////////////////////////////////////////////////
765
37b86a39 766/**
32be99dc 767 * creates a new template-record.
768 *
769 * @global object
770 * @param int $courseid
771 * @param string $name the name of template shown in the templatelist
772 * @param int $ispublic 0:privat 1:public
773 * @return int the new templateid
c70ad9f7 774 */
775function feedback_create_template($courseid, $name, $ispublic = 0) {
0085fff8 776 global $DB;
777
778 $templ = new object();
779 $templ->course = $courseid;
780 $templ->name = $name;
c70ad9f7 781 $templ->ispublic = $ispublic;
0085fff8 782
783 return $DB->insert_record('feedback_template', $templ);
c70ad9f7 784}
785
37b86a39 786/**
32be99dc 787 * creates new template items.
788 * all items will be copied and the attribute feedback will be set to 0
789 * and the attribute template will be set to the new templateid
790 *
791 * @global object
792 * @param object $feedback
793 * @param string $name the name of template shown in the templatelist
794 * @param int $ispublic 0:privat 1:public
795 * @return boolean
c70ad9f7 796 */
797function feedback_save_as_template($feedback, $name, $ispublic = 0) {
0085fff8 798 global $DB;
799
800 if (!$feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$feedback->id))) {
c70ad9f7 801 return false;
802 }
37b86a39 803
0085fff8 804 if (!$newtempl = feedback_create_template($feedback->course, $name, $ispublic)) {
c70ad9f7 805 return false;
806 }
807 //create items of this new template
808 foreach($feedbackitems as $item) {
0085fff8 809 unset($item->id);
c70ad9f7 810 $item->feedback = 0;
0085fff8 811 $item->template = $newtempl;
a59ff6b0 812 $DB->insert_record('feedback_item', $item);
c70ad9f7 813 }
814 return true;
815}
816
37b86a39 817/**
32be99dc 818 * deletes all feedback_items related to the given template id
819 *
820 * @global object
821 * @param int $id the templateid
822 * @return void
c70ad9f7 823 */
824function feedback_delete_template($id) {
0085fff8 825 global $DB;
826
827 $DB->delete_records("feedback_item", array("template"=>$id));
828 $DB->delete_records("feedback_template", array("id"=>$id));
c70ad9f7 829}
830
37b86a39 831/**
32be99dc 832 * creates new feedback_item-records from template.
833 * if $deleteold is set true so the existing items of the given feedback will be deleted
834 * if $deleteold is set false so the new items will be appanded to the old items
835 *
836 * @global object
837 * @param object $feedback
838 * @param int $templateid
839 * @param boolean $deleteold
c70ad9f7 840 */
841function feedback_items_from_template($feedback, $templateid, $deleteold = false) {
0085fff8 842 global $DB;
843
c70ad9f7 844 //get all templateitems
0085fff8 845 if(!$templitems = $DB->get_records('feedback_item', array('template'=>$templateid))) {
c70ad9f7 846 return false;
847 }
37b86a39 848
c70ad9f7 849 //if deleteold then delete all old items before
850 //get all items
851 if($deleteold) {
0085fff8 852 if($feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$feedback->id))) {
c70ad9f7 853 //delete all items of this feedback
854 foreach($feedbackitems as $item) {
855 feedback_delete_item($item->id, false);
856 }
857 //delete tracking-data
0085fff8 858 $DB->delete_records('feedback_tracking', array('feedback'=>$feedback->id));
859 $DB->delete_records('feedback_completed', array('feedback'=>$feedback->id));
860 $DB->delete_records('feedback_completedtmp', array('feedback'=>$feedback->id));
c70ad9f7 861 $positionoffset = 0;
862 }
0085fff8 863 } else {
c70ad9f7 864 //if the old items are kept the new items will be appended
865 //therefor the new position has an offset
0085fff8 866 $positionoffset = $DB->count_records('feedback_item', array('feedback'=>$feedback->id));
c70ad9f7 867 }
37b86a39 868
c70ad9f7 869 foreach($templitems as $newitem) {
0085fff8 870 unset($newitem->id);
c70ad9f7 871 $newitem->feedback = $feedback->id;
872 $newitem->template = 0;
c70ad9f7 873 $newitem->position = $newitem->position + $positionoffset;
0085fff8 874
875 $DB->insert_record('feedback_item', $newitem);
c70ad9f7 876 }
877}
878
37b86a39 879/**
32be99dc 880 * get the list of available templates.
881 * if the $onlyown param is set true so only templates from own course will be served
882 * this is important for droping templates
883 *
884 * @global object
885 * @param object $course
886 * @param boolean $onlyown
887 * @return array the template recordsets
c70ad9f7 888 */
889function feedback_get_template_list($course, $onlyown = false) {
0085fff8 890 global $DB;
891
892 if ($onlyown) {
893 $templates = $DB->get_records('feedback_template', array('course'=>$course->id));
c70ad9f7 894 } else {
0085fff8 895 $templates = $DB->get_records_select('feedback_template', 'course = ? OR ispublic = 1', array($course->id));
c70ad9f7 896 }
897 return $templates;
898}
899
900////////////////////////////////////////////////
901//Handling der Items
902////////////////////////////////////////////////
903////////////////////////////////////////////////
904
37b86a39 905/**
32be99dc 906 * load the available item plugins from given subdirectory of $CFG->dirroot
907 * the default is "mod/feedback/item"
908 *
909 * @global object
910 * @param string $dir the subdir
911 * @return array pluginnames as string
c70ad9f7 912 */
913function feedback_load_feedback_items($dir = 'mod/feedback/item') {
914 global $CFG;
915 $names =get_list_of_plugins($dir);
916 $ret_names = array();
917
918 foreach($names as $name) {
919 require_once($CFG->dirroot.'/'.$dir.'/'.$name.'/lib.php');
920 if(class_exists('feedback_item_'.$name)) {
921 $ret_names[] = $name;
922 }
923 }
924 return $ret_names;
925}
926
37b86a39 927/**
32be99dc 928 * load the available item plugins to use as dropdown-options
929 *
930 * @global object
931 * @return array pluginnames as string
c70ad9f7 932 */
933function feedback_load_feedback_items_options() {
934 global $CFG;
37b86a39 935
c70ad9f7 936 $feedback_options = array("pagebreak" => get_string('add_pagebreak', 'feedback'));
37b86a39 937
c70ad9f7 938 if (!$feedback_names = feedback_load_feedback_items('mod/feedback/item')) {
939 return array();
940 }
37b86a39 941
c70ad9f7 942 foreach($feedback_names as $fn) {
943 $feedback_options[$fn] = get_string($fn,'feedback');
944 }
945 asort($feedback_options);
37b86a39 946 $feedback_options = array_merge( array(' ' => get_string('select')), $feedback_options );
c70ad9f7 947 return $feedback_options;
948}
949
37b86a39 950/**
32be99dc 951 * creates a new item-record
952 *
953 * @global object
954 * @param object $data the data from edit_item_form
955 * @return int the new itemid
c70ad9f7 956 */
957function feedback_create_item($data) {
0085fff8 958 global $DB;
959
c70ad9f7 960 $item = new object;
0085fff8 961 $item->feedback = $data->feedbackid;
c70ad9f7 962
963 $item->template=0;
964 if (isset($data->templateid)) {
78946b9b 965 $item->template = intval($data->templateid);
37b86a39 966 }
c70ad9f7 967
968 $itemname = trim($data->itemname);
0085fff8 969 $item->name = ($itemname ? $data->itemname : get_string('no_itemname', 'feedback'));
37b86a39 970
d185ff44
SH
971 if (!empty($data->itemlabel)) {
972 $item->label = trim($data->itemlabel);
973 } else {
974 $item->label = get_string('no_itemlabel', 'feedback');
975 }
b7a47958 976
c70ad9f7 977 //get the used class from item-typ
978 $itemclass = 'feedback_item_'.$data->typ;
979 //get the instance of the item class
980 $itemobj = new $itemclass();
a59ff6b0
AG
981 // $item->presentation = $itemobj->get_presentation($data);
982 $item->presentation = ''; //the date comes from postupdate() of the itemobj
37b86a39 983
c70ad9f7 984 $item->hasvalue = $itemobj->get_hasvalue();
37b86a39 985
c70ad9f7 986 $item->typ = $data->typ;
987 $item->position = $data->position;
988
989 $item->required=0;
ab5bd34d 990 if (!empty($data->required)) {
991 $item->required = $data->required;
37b86a39 992 }
c70ad9f7 993
a59ff6b0
AG
994 $item->id = $DB->insert_record('feedback_item', $item);
995
996 //move all itemdata to the data
997 $data->id = $item->id;
998 $data->feedback = $item->feedback;
999 $data->name = $item->name;
1000 $data->label = $item->label;
1001 $data->required = $item->required;
1002 return $itemobj->postupdate($data);
c70ad9f7 1003}
1004
37b86a39 1005/**
32be99dc 1006 * save the changes of a given item.
1007 *
1008 * @global object
1009 * @param object $item
1010 * @param object $data the data from edit_item_form
1011 * @return boolean
c70ad9f7 1012 */
a59ff6b0 1013function feedback_update_item($item){
0085fff8 1014 global $DB;
0085fff8 1015 return $DB->update_record("feedback_item", $item);
c70ad9f7 1016}
1017
37b86a39 1018/**
32be99dc 1019 * deletes a item and also deletes all related values
1020 *
1021 * @global object
1022 * @param int $itemid
1023 * @param boolean $renumber should the kept items renumbered Yes/No
1024 * @return void
c70ad9f7 1025 */
1026function feedback_delete_item($itemid, $renumber = true){
0085fff8 1027 global $DB;
1028
1029 $item = $DB->get_record('feedback_item', array('id'=>$itemid));
1030 $DB->delete_records("feedback_value", array("item"=>$itemid));
1031 $DB->delete_records("feedback_valuetmp", array("item"=>$itemid));
1032 $DB->delete_records("feedback_item", array("id"=>$itemid));
c70ad9f7 1033 if($renumber) {
1034 feedback_renumber_items($item->feedback);
1035 }
1036}
1037
37b86a39 1038/**
32be99dc 1039 * deletes all items of the given feedbackid
1040 *
1041 * @global object
1042 * @param int $feedbackid
1043 * @return void
c70ad9f7 1044 */
1045function feedback_delete_all_items($feedbackid){
0085fff8 1046 global $DB;
1047
1048 if(!$items = $DB->get_records('feedback_item', array('feedback'=>$feedbackid))) {
c70ad9f7 1049 return;
1050 }
1051 foreach($items as $item) {
1052 feedback_delete_item($item->id, false);
1053 }
0085fff8 1054 $DB->delete_records('feedback_completedtmp', array('feedback'=>$feedbackid));
1055 $DB->delete_records('feedback_completed', array('feedback'=>$feedbackid));
c70ad9f7 1056}
1057
37b86a39 1058/**
32be99dc 1059 * this function toggled the item-attribute required (yes/no)
1060 *
1061 * @global object
1062 * @param object $item
1063 * @return boolean
c70ad9f7 1064 */
1065function feedback_switch_item_required($item) {
0085fff8 1066 global $DB;
1067
c70ad9f7 1068 if($item->required == 1) {
1069 $item->required = 0;
1070 } else {
1071 $item->required = 1;
1072 }
0085fff8 1073 $item->name = $item->name;
1074 $item->presentation = $item->presentation;
1075 return $DB->update_record('feedback_item', $item);
c70ad9f7 1076}
1077
37b86a39 1078/**
32be99dc 1079 * renumbers all items of the given feedbackid
1080 *
1081 * @global object
1082 * @param int $feedbackid
1083 * @return void
c70ad9f7 1084 */
1085function feedback_renumber_items($feedbackid){
0085fff8 1086 global $DB;
1087
1088 $items = $DB->get_records('feedback_item', array('feedback'=>$feedbackid), 'position');
c70ad9f7 1089 $pos = 1;
1090 if($items) {
1091 foreach($items as $item){
1092 $item->position = $pos;
1093 $pos++;
1094 feedback_update_item($item);
1095 }
1096 }
1097}
1098
37b86a39 1099/**
32be99dc 1100 * this decreases the position of the given item
1101 *
1102 * @global object
1103 * @param object $item
1104 * @return void
c70ad9f7 1105 */
1106function feedback_moveup_item($item){
0085fff8 1107 global $DB;
1108
a59ff6b0
AG
1109 if($item->position == 1) {
1110 return true;
1111 }
1112
1113 if(!$items = $DB->get_records('feedback_item', array('feedback'=>$item->feedback), 'position')) {
1114 return false;
1115 }
1116
1117 $itembefore = null;
1118 foreach($items as $i) {
1119 if($i->id == $item->id) {
1120 if(is_null($itembefore)) {
1121 return true;
1122 }
1123 $itembefore->position = $item->position;
1124 $item->position--;
1125 feedback_update_item($itembefore);
1126 feedback_update_item($item);
1127 feedback_renumber_items($item->feedback);
1128 return true;
1129 }
1130 $itembefore = $i;
1131 }
1132 return false;
c70ad9f7 1133}
1134
37b86a39 1135/**
32be99dc 1136 * this increased the position of the given item
1137 *
1138 * @global object
1139 * @param object $item
1140 * @return void
c70ad9f7 1141 */
1142function feedback_movedown_item($item){
0085fff8 1143 global $DB;
1144
a59ff6b0
AG
1145 if(!$items = $DB->get_records('feedback_item', array('feedback'=>$item->feedback), 'position')) {
1146 return false;
c70ad9f7 1147 }
a59ff6b0
AG
1148
1149 $movedownitem = null;
1150 foreach($items as $i) {
1151 if(!is_null($movedownitem) AND $movedownitem->id == $item->id) {
1152 $movedownitem->position = $i->position;
1153 $i->position--;
1154 feedback_update_item($movedownitem);
1155 feedback_update_item($i);
1156 feedback_renumber_items($item->feedback);
1157 return true;
1158 }
1159 $movedownitem = $i;
1160 }
1161 return false;
c70ad9f7 1162}
1163
37b86a39 1164/**
32be99dc 1165 * here the position of the given item will be set to the value in $pos
1166 *
1167 * @global object
1168 * @param object $moveitem
1169 * @param int $pos
1170 * @return boolean
c70ad9f7 1171 */
1172function feedback_move_item($moveitem, $pos){
0085fff8 1173 global $DB;
1174
0085fff8 1175 if (!$allitems = $DB->get_records('feedback_item', array('feedback'=>$moveitem->feedback), 'position')) {
c70ad9f7 1176 return false;
1177 }
0085fff8 1178 if (is_array($allitems)) {
c70ad9f7 1179 $index = 1;
1180 foreach($allitems as $item) {
c70ad9f7 1181 if($index == $pos) {
c70ad9f7 1182 $index++;
1183 }
a59ff6b0
AG
1184 if($item->id == $moveitem->id) {
1185 $moveitem->position = $pos;
1186 feedback_update_item($moveitem);
1187 continue;
1188 }
c70ad9f7 1189 $item->position = $index;
1190 feedback_update_item($item);
1191 $index++;
1192 }
c70ad9f7 1193 return true;
1194 }
1195 return false;
1196}
1197
9d5fbd65
AG
1198/**
1199 * prints the given item.
1200 * if $readonly is set true so the ouput only is for showing responses and not for editing or completing.
1201 * each item-class has an own print_item function implemented.
1202 *
1203 * @param object $item the item what we want to print out
1204 * @return void
1205 */
1206function feedback_print_item_preview($item){
1207 global $CFG;
1208 if($item->typ == 'pagebreak') {
1209 return;
1210 }
1211 //get the class of the given item-typ
1212 $itemclass = 'feedback_item_'.$item->typ;
1213 if (!class_exists($itemclass)) {
1214 require_once($CFG->dirroot.'/mod/feedback/item/'.$item->typ.'/lib.php');
1215 }
1216 //get the instance of the item-class
1217 $itemobj = new $itemclass();
1218 $itemobj->print_item_preview($item);
1219}
1220
37b86a39 1221/**
32be99dc 1222 * prints the given item.
1223 * if $readonly is set true so the ouput only is for showing responses and not for editing or completing.
1224 * each item-class has an own print_item function implemented.
1225 *
1226 * @param object $item the item what we want to print out
1227 * @param mixed $value the value if $readonly is set true and we showing responses
32be99dc 1228 * @param boolean $highlightrequire if this set true and the value are false on completing so the item will be highlighted
1229 * @return void
c70ad9f7 1230 */
9d5fbd65 1231function feedback_print_item_complete($item, $value = false, $highlightrequire = false){
ab5bd34d 1232 global $CFG;
9d5fbd65
AG
1233 if($item->typ == 'pagebreak') {
1234 return;
1235 }
37b86a39 1236
c70ad9f7 1237 //get the class of the given item-typ
1238 $itemclass = 'feedback_item_'.$item->typ;
ab5bd34d 1239 if (!class_exists($itemclass)) {
1240 require_once($CFG->dirroot.'/mod/feedback/item/'.$item->typ.'/lib.php');
1241 }
c70ad9f7 1242 //get the instance of the item-class
1243 $itemobj = new $itemclass();
9d5fbd65
AG
1244 $itemobj->print_item_complete($item, $value, $highlightrequire);
1245}
1246
1247/**
1248 * prints the given item.
1249 * if $readonly is set true so the ouput only is for showing responses and not for editing or completing.
1250 * each item-class has an own print_item function implemented.
1251 *
1252 * @param object $item the item what we want to print out
1253 * @param mixed $value the value if $readonly is set true and we showing responses
1254 * @return void
1255 */
1256function feedback_print_item_show_value($item, $value = false){
1257 global $CFG;
1258 if($item->typ == 'pagebreak') {
1259 return;
1260 }
1261
1262 //get the class of the given item-typ
1263 $itemclass = 'feedback_item_'.$item->typ;
1264 if (!class_exists($itemclass)) {
1265 require_once($CFG->dirroot.'/mod/feedback/item/'.$item->typ.'/lib.php');
1266 }
1267 //get the instance of the item-class
1268 $itemobj = new $itemclass();
1269 $itemobj->print_item_show_value($item, $value);
c70ad9f7 1270}
1271
37b86a39 1272/**
32be99dc 1273 * if the user completes a feedback and there is a pagebreak so the values are saved temporary.
1274 * the values are saved permanently not until the user click on save button
1275 *
1276 * @global object
1277 * @param object $feedbackcompleted
1278 * @return object temporary saved completed-record
c70ad9f7 1279 */
0085fff8 1280function feedback_set_tmp_values($feedbackcompleted) {
1281 global $DB;
1282
c70ad9f7 1283 //first we create a completedtmp
1284 $tmpcpl = new object();
1285 foreach($feedbackcompleted as $key => $value) {
1286 $tmpcpl->{$key} = $value;
1287 }
1288 // $tmpcpl = $feedbackcompleted;
0085fff8 1289 unset($tmpcpl->id);
c70ad9f7 1290 $tmpcpl->timemodified = time();
7826abc7 1291 $tmpcpl->id = $DB->insert_record('feedback_completedtmp', $tmpcpl);
c70ad9f7 1292 //get all values of original-completed
0085fff8 1293 if(!$values = $DB->get_records('feedback_value', array('completed'=>$feedbackcompleted->id))) {
c70ad9f7 1294 return;
1295 }
1296 foreach($values as $value) {
0085fff8 1297 unset($value->id);
c70ad9f7 1298 $value->completed = $tmpcpl->id;
0085fff8 1299 $DB->insert_record('feedback_valuetmp', $value);
c70ad9f7 1300 }
1301 return $tmpcpl;
1302}
1303
37b86a39 1304/**
32be99dc 1305 * this saves the temporary saved values permanently
1306 *
1307 * @global object
1308 * @param object $feedbackcompletedtmp the temporary completed
1309 * @param object $feedbackcompleted the target completed
1310 * @param int $userid
1311 * @return int the id of the completed
c70ad9f7 1312 */
1313function feedback_save_tmp_values($feedbackcompletedtmp, $feedbackcompleted, $userid) {
0085fff8 1314 global $DB;
1315
c70ad9f7 1316 $tmpcplid = $feedbackcompletedtmp->id;
1317 if(!$feedbackcompleted) {
1318
1319 //first we create a completedtmp
1320 $newcpl = new object();
1321 foreach($feedbackcompletedtmp as $key => $value) {
1322 $newcpl->{$key} = $value;
1323 }
1324
0085fff8 1325 unset($newcpl->id);
c70ad9f7 1326 $newcpl->userid = $userid;
1327 $newcpl->timemodified = time();
7826abc7 1328 $newcpl->id = $DB->insert_record('feedback_completed', $newcpl);
c70ad9f7 1329 //get all values of tmp-completed
0085fff8 1330 if(!$values = $DB->get_records('feedback_valuetmp', array('completed'=>$feedbackcompletedtmp->id))) {
c70ad9f7 1331 return false;
1332 }
1333
1334 foreach($values as $value) {
0085fff8 1335 unset($value->id);
c70ad9f7 1336 $value->completed = $newcpl->id;
0085fff8 1337 $DB->insert_record('feedback_value', $value);
c70ad9f7 1338 }
1339 //drop all the tmpvalues
0085fff8 1340 $DB->delete_records('feedback_valuetmp', array('completed'=>$tmpcplid));
1341 $DB->delete_records('feedback_completedtmp', array('id'=>$tmpcplid));
c70ad9f7 1342 return $newcpl->id;
0085fff8 1343
1344 } else {
c70ad9f7 1345 //first drop all existing values
0085fff8 1346 $DB->delete_records('feedback_value', array('completed'=>$feedbackcompleted->id));
c70ad9f7 1347 //update the current completed
1348 $feedbackcompleted->timemodified = time();
0085fff8 1349 $DB->update_record('feedback_completed', $feedbackcompleted);
c70ad9f7 1350 //save all the new values from feedback_valuetmp
1351 //get all values of tmp-completed
0085fff8 1352 if(!$values = $DB->get_records('feedback_valuetmp', array('completed'=>$feedbackcompletedtmp->id))) {
c70ad9f7 1353 return false;
1354 }
1355 foreach($values as $value) {
0085fff8 1356 unset($value->id);
c70ad9f7 1357 $value->completed = $feedbackcompleted->id;
0085fff8 1358 $DB->insert_record('feedback_value', $value);
c70ad9f7 1359 }
1360 //drop all the tmpvalues
0085fff8 1361 $DB->delete_records('feedback_valuetmp', array('completed'=>$tmpcplid));
1362 $DB->delete_records('feedback_completedtmp', array('id'=>$tmpcplid));
c70ad9f7 1363 return $feedbackcompleted->id;
1364 }
1365}
1366
37b86a39 1367/**
32be99dc 1368 * deletes the given temporary completed and all related temporary values
1369 *
1370 * @global object
1371 * @param int $tmpcplid
1372 * @return void
c70ad9f7 1373 */
1374function feedback_delete_completedtmp($tmpcplid) {
0085fff8 1375 global $DB;
1376
1377 $DB->delete_records('feedback_valuetmp', array('completed'=>$tmpcplid));
1378 $DB->delete_records('feedback_completedtmp', array('id'=>$tmpcplid));
c70ad9f7 1379}
1380
1381////////////////////////////////////////////////
1382////////////////////////////////////////////////
1383////////////////////////////////////////////////
1384//functions to handle the pagebreaks
1385////////////////////////////////////////////////
1386
37b86a39 1387/**
32be99dc 1388 * this creates a pagebreak.
1389 * a pagebreak is a special kind of item
1390 *
1391 * @global object
1392 * @param int $feedbackid
1393 * @return mixed false if there already is a pagebreak on last position or the id of the pagebreak-item
c70ad9f7 1394 */
1395function feedback_create_pagebreak($feedbackid) {
0085fff8 1396 global $DB;
1397
c70ad9f7 1398 //check if there already is a pagebreak on the last position
0085fff8 1399 $lastposition = $DB->count_records('feedback_item', array('feedback'=>$feedbackid));
c70ad9f7 1400 if($lastposition == feedback_get_last_break_position($feedbackid)) {
1401 return false;
1402 }
37b86a39 1403
c70ad9f7 1404 $item = new object();
c70ad9f7 1405 $item->feedback = $feedbackid;
1406
1407 $item->template=0;
1408
1409 $item->name = '';
37b86a39 1410
c70ad9f7 1411 $item->presentation = '';
1412 $item->hasvalue = 0;
37b86a39 1413
c70ad9f7 1414 $item->typ = 'pagebreak';
1415 $item->position = $lastposition + 1;
1416
1417 $item->required=0;
1418
0085fff8 1419 return $DB->insert_record('feedback_item', $item);
c70ad9f7 1420}
1421
37b86a39 1422/**
32be99dc 1423 * get all positions of pagebreaks in the given feedback
1424 *
1425 * @global object
1426 * @param int $feedbackid
1427 * @return array all ordered pagebreak positions
c70ad9f7 1428 */
1429function feedback_get_all_break_positions($feedbackid) {
534792cd 1430 global $DB;
1431
1432 if(!$allbreaks = $DB->get_records_menu('feedback_item', array('typ'=>'pagebreak', 'feedback'=>$feedbackid), 'position', 'id, position')) return false;
c70ad9f7 1433 return array_values($allbreaks);
1434}
1435
37b86a39 1436/**
32be99dc 1437 * get the position of the last pagebreak
d4b1d58c 1438 *
32be99dc 1439 * @param int $feedbackid
1440 * @return int the position of the last pagebreak
c70ad9f7 1441 */
1442function feedback_get_last_break_position($feedbackid) {
1443 if(!$allbreaks = feedback_get_all_break_positions($feedbackid)) return false;
1444 return $allbreaks[count($allbreaks) - 1];
1445}
1446
37b86a39 1447/**
32be99dc 1448 * this returns the position where the user can continue the completing.
1449 *
1450 * @global object
1451 * @global object
1452 * @global object
1453 * @param int $feedbackid
1454 * @param int $courseid
1455 * @param string $guestid this id will be saved temporary and is unique
1456 * @return int the position to continue
c70ad9f7 1457 */
1458function feedback_get_page_to_continue($feedbackid, $courseid = false, $guestid) {
0085fff8 1459 global $CFG, $USER, $DB;
37b86a39 1460
c70ad9f7 1461 //is there any break?
37b86a39 1462
c70ad9f7 1463 if(!$allbreaks = feedback_get_all_break_positions($feedbackid)) return false;
0085fff8 1464
1465 $params = array();
c70ad9f7 1466 if($courseid) {
0085fff8 1467 $courseselect = "fv.course_id = :courseid";
1468 $params['courseid'] = $courseid;
c70ad9f7 1469 }else {
1470 $courseselect = "1";
1471 }
37b86a39 1472
c70ad9f7 1473 if($guestid) {
0085fff8 1474 $userselect = "AND fc.guestid = :guestid";
c70ad9f7 1475 $usergroup = "GROUP BY fc.guestid";
0085fff8 1476 $params['guestid'] = $guestid;
c70ad9f7 1477 }else {
0085fff8 1478 $userselect = "AND fc.userid = :userid";
c70ad9f7 1479 $usergroup = "GROUP BY fc.userid";
0085fff8 1480 $params['userid'] = $USER->id;
c70ad9f7 1481 }
0085fff8 1482
c70ad9f7 1483 $sql = "SELECT MAX(fi.position)
abf1c50f 1484 FROM {feedback_completedtmp} fc, {feedback_valuetmp} fv, {feedback_item} fi
0085fff8 1485 WHERE fc.id = fv.completed
1486 $userselect
1487 AND fc.feedback = :feedbackid
1488 AND $courseselect
c70ad9f7 1489 AND fi.id = fv.item
0085fff8 1490 $usergroup";
1491 $params['feedbackid'] = $feedbackid;
1492
1493 $lastpos = $DB->get_field_sql($sql, $params);
c70ad9f7 1494
1495 //the index of found pagebreak is the searched pagenumber
1496 foreach($allbreaks as $pagenr => $br) {
1497 if($lastpos < $br) return $pagenr;
1498 }
1499 return count($allbreaks);
1500}
1501
1502////////////////////////////////////////////////
1503////////////////////////////////////////////////
1504////////////////////////////////////////////////
1505//functions to handle the values
1506////////////////////////////////////////////////
1507
37b86a39 1508/**
32be99dc 1509 * this saves the values of an completed.
1510 * if the param $tmp is set true so the values are saved temporary in table feedback_valuetmp
1511 * if there is already a completed and the userid is set so the values are updated
1512 * on all other things new value records will be created
d4b1d58c 1513 *
32be99dc 1514 * @global object
1515 * @param object $data the data from complete form
1516 * @param int $userid
1517 * @param boolean $tmp
1518 * @return mixed false on error or the completeid
c70ad9f7 1519 */
1520function feedback_save_values($data, $usrid, $tmp = false) {
0085fff8 1521 global $DB;
1522
c70ad9f7 1523 $tmpstr = $tmp ? 'tmp' : '';
1524 $time = time(); //arb
1525 $timemodified = mktime(0, 0, 0, date('m', $time),date('d', $time),date('Y', $time)); //arb
37b86a39 1526// $timemodified = time();
c70ad9f7 1527 if($usrid == 0) {
1528 return feedback_create_values($data, $usrid, $timemodified, $tmp);
1529 }
0085fff8 1530 if(!$data['completedid'] or !$completed = $DB->get_record('feedback_completed'.$tmpstr, array('id'=>$data['completedid']))) {
c70ad9f7 1531 return feedback_create_values($data, $usrid, $timemodified, $tmp);
1532 }else{
1533 $completed->timemodified = $timemodified;
1534 return feedback_update_values($data, $completed, $tmp);
1535 }
1536}
1537
37b86a39 1538/**
32be99dc 1539 * this saves the values from anonymous user such as guest on the main-site
1540 *
1541 * @global object
1542 * @param object $data the data form complete_guest form
1543 * @param string $guestid the unique guestidentifier
1544 * @return mixed false on error or the completeid
c70ad9f7 1545 */
1546function feedback_save_guest_values($data, $guestid) {
0085fff8 1547 global $DB;
1548
c70ad9f7 1549 $timemodified = time();
0085fff8 1550 if(!$completed = $DB->get_record('feedback_completedtmp', array('id'=>$data['completedid']))) {
c70ad9f7 1551 return feedback_create_values($data, 0, $timemodified, true, $guestid);
1552 }else {
1553 $completed->timemodified = $timemodified;
1554 return feedback_update_values($data, $completed, true);
1555 }
1556}
1557
37b86a39 1558/**
32be99dc 1559 * get the value from the given item related to the given completed.
1560 * the value can come as temporary or as permanently value. the deciding is done by $tmp
1561 *
1562 * @global object
1563 * @param int $completeid
1564 * @param int $itemid
1565 * @param boolean $tmp
1566 * @return mixed the value, the type depends on plugin-definition
c70ad9f7 1567 */
1568function feedback_get_item_value($completedid, $itemid, $tmp = false) {
0085fff8 1569 global $DB;
1570
c70ad9f7 1571 $tmpstr = $tmp ? 'tmp' : '';
0085fff8 1572 return $DB->get_field('feedback_value'.$tmpstr, 'value', array('completed'=>$completedid, 'item'=>$itemid));
c70ad9f7 1573}
1574
37b86a39 1575/**
32be99dc 1576 * this function checks the correctness of values.
1577 * the rules for this are implemented in the class of each item.
1578 * it can be the required attribute or the value self e.g. numeric.
1579 * the params first/lastitem are given to determine the visible range between pagebreaks.
1580 *
1581 * @global object
1582 * @param object $data the data of complete form
1583 * @param int $firstitem the position of firstitem for checking
1584 * @param int $lastitem the position of lastitem for checking
1585 * @return boolean
c70ad9f7 1586 */
1587function feedback_check_values($data, $firstitem, $lastitem) {
ab5bd34d 1588 global $DB, $CFG;
0085fff8 1589
c70ad9f7 1590 //get all items between the first- and lastitem
0085fff8 1591 $select = "feedback = ?
1592 AND position >= ?
1593 AND position <= ?
c70ad9f7 1594 AND hasvalue = 1";
0085fff8 1595 $params = array(intval($data['feedbackid']), $firstitem, $lastitem);
1596 if(!$feedbackitems = $DB->get_records_select('feedback_item', $select, $params)) {
c70ad9f7 1597 //if no values are given so no values can be wrong ;-)
1598 return true;
1599 }
1600
1601 foreach($feedbackitems as $item) {
1602 //the name of the input field of the completeform is given in a special form:
1603 //<item-typ>_<item-id> eg. numeric_234
1604 //this is the key to get the value for the correct item
1605 $formvalname = $item->typ . '_' . $item->id;
37b86a39 1606
c70ad9f7 1607 //check if the value is set
1608 if((!isset($data[$formvalname])) AND ($item->required == 1)) {
1609 return false;
1610 }
37b86a39 1611
c70ad9f7 1612 //if there is a value so save it temporary
1613 $value = isset($data[$formvalname]) ? $data[$formvalname] : '';
1614
1615 //get the class of the item-typ
1616 $itemclass = 'feedback_item_'.$item->typ;
ab5bd34d 1617
1618 if (!class_exists($itemclass)) {
1619 require_once($CFG->dirroot.'/mod/feedback/item/'.$item->typ.'/lib.php');
1620 }
1621
c70ad9f7 1622 //get the instance of the item-class
1623 $itemobj = new $itemclass();
37b86a39 1624
c70ad9f7 1625 //now we let check the value by the item-class
1626 if(!$itemobj->check_value($value, $item)) {
1627 return false;
1628 }
1629 }
1630 //if no wrong values so we can return true
1631 return true;
1632}
1633
37b86a39 1634/**
32be99dc 1635 * this function create a complete-record and the related value-records.
1636 * depending on the $tmp (true/false) the values are saved temporary or permanently
1637 *
1638 * @global object
1639 * @param object $data the data of the complete form
1640 * @param int $userid
1641 * @param int $timemodified
1642 * @param boolean $tmp
1643 * @param string $guestid a unique identifier to save temporary data
1644 * @return mixed false on error or the completedid
c70ad9f7 1645 */
1646function feedback_create_values($data, $usrid, $timemodified, $tmp = false, $guestid = false){
0085fff8 1647 global $DB;
1648
c70ad9f7 1649 $tmpstr = $tmp ? 'tmp' : '';
1650 //first we create a new completed record
0085fff8 1651 $completed = new object();
1652 $completed->feedback = $data['feedbackid'];
1653 $completed->userid = $usrid;
1654 $completed->guestid = $guestid;
1655 $completed->timemodified = $timemodified;
c70ad9f7 1656 $completed->anonymous_response = $data['anonymous_response'];
37b86a39 1657
a8f3a651 1658 $completedid = $DB->insert_record('feedback_completed'.$tmpstr, $completed);
37b86a39 1659
0085fff8 1660 $completed = $DB->get_record('feedback_completed'.$tmpstr, array('id'=>$completedid));
c70ad9f7 1661
1662 //$data includes an associative array. the keys are in the form like abc_xxx
1663 //with explode we make an array with(abc, xxx) and (abc=typ und xxx=itemnr)
1664 $keys = array_keys($data);
1665 $errcount = 0;
1666 foreach($keys as $key){
1667 //ensure the keys are what we want
6dbcacee 1668 if(preg_match('/([a-z0-9]{1,})_([0-9]{1,})/i',$key)){
0085fff8 1669 $value = new object();
c70ad9f7 1670 $itemnr = explode('_', $key);
c70ad9f7 1671 $value->item = intval($itemnr[1]);
1672 $value->completed = $completed->id;
1673 $value->course_id = intval($data['courseid']);
37b86a39 1674
c70ad9f7 1675 //get the class of item-typ
1676 $itemclass = 'feedback_item_'.$itemnr[0];
1677 //get the instance of item-class
ab5bd34d 1678 if (!class_exists($itemclass)) {
1679 require_once($CFG->dirroot.'/mod/feedback/item/'.$itemnr[0].'/lib.php');
1680 }
c70ad9f7 1681 $itemobj = new $itemclass();
1682 //the kind of values can be absolutely different so we run create_value directly by the item-class
1683 $value->value = $itemobj->create_value($data[$key]);
1684
a8f3a651 1685 $DB->insert_record('feedback_value'.$tmpstr, $value);
c70ad9f7 1686 }
1687 }
37b86a39 1688
c70ad9f7 1689 //if nothing is wrong so we can return the completedid otherwise false
1690 return $errcount == 0 ? $completed->id : false;
1691}
1692
37b86a39 1693/**
32be99dc 1694 * this function updates a complete-record and the related value-records.
1695 * depending on the $tmp (true/false) the values are saved temporary or permanently
1696 *
1697 * @global object
1698 * @param object $data the data of the complete form
1699 * @param object $completed
1700 * @param boolean $tmp
1701 * @return int the completedid
c70ad9f7 1702 */
0085fff8 1703function feedback_update_values($data, $completed, $tmp = false) {
1704 global $DB;
1705
c70ad9f7 1706 $tmpstr = $tmp ? 'tmp' : '';
37b86a39 1707
0085fff8 1708 $DB->update_record('feedback_completed'.$tmpstr, $completed);
c70ad9f7 1709 //get the values of this completed
0085fff8 1710 $values = $DB->get_records('feedback_value'.$tmpstr, array('completed'=>$completed->id));
37b86a39 1711
c70ad9f7 1712 //$data includes an associative array. the keys are in the form like abc_xxx
1713 //with explode we make an array with(abc, xxx) and (abc=typ und xxx=itemnr)
1714 $keys = array_keys($data);
1715 foreach($keys as $key){
1716 //ensure the keys are what we want
6dbcacee 1717 if(preg_match('/([a-z0-9]{1,})_([0-9]{1,})/i',$key)){
c70ad9f7 1718 //build the new value to update([id], item, completed, value)
1719 $itemnr = explode('_', $key);
0085fff8 1720 $newvalue = new object();
1721 $newvalue->item = $itemnr[1];
c70ad9f7 1722 $newvalue->completed = $completed->id;
0085fff8 1723 $newvalue->course_id = $data['courseid'];
37b86a39 1724
c70ad9f7 1725 //get the class of item-typ
1726 $itemclass = 'feedback_item_'.$itemnr[0];
1727 //get the instace of the item-class
ab5bd34d 1728 if (!class_exists($itemclass)) {
1729 require_once($CFG->dirroot.'/mod/feedback/item/'.$itemnr[0].'/lib.php');
1730 }
c70ad9f7 1731 $itemobj = new $itemclass();
1732 //the kind of values can be absolutely different so we run create_value directly by the item-class
1733 $newvalue->value = $itemobj->create_value($data[$key]);
37b86a39 1734
c70ad9f7 1735 //check, if we have to create or update the value
1736 $exist = false;
1737 foreach($values as $value){
1738 if($value->item == $newvalue->item){
1739 $newvalue->id = $value->id;
1740 $exist = true;
1741 break;
1742 }
1743 }
1744 if($exist){
0085fff8 1745 $DB->update_record('feedback_value'.$tmpstr, $newvalue);
c70ad9f7 1746 }else {
0085fff8 1747 $DB->insert_record('feedback_value'.$tmpstr, $newvalue);
c70ad9f7 1748 }
37b86a39 1749
c70ad9f7 1750 }
1751 }
1752
1753 return $completed->id;
1754}
1755
37b86a39 1756/**
32be99dc 1757 * get the values of an item depending on the given groupid.
1758 * if the feedback is anonymous so the values are shuffled
1759 *
1760 * @global object
1761 * @global object
1762 * @param object $item
1763 * @param int $groupid
1764 * @param int $courseid
1765 * @return array the value-records
c70ad9f7 1766 */
1767function feedback_get_group_values($item, $groupid = false, $courseid = false){
0085fff8 1768 global $CFG, $DB;
c70ad9f7 1769
1770 //if the groupid is given?
0085fff8 1771 if (intval($groupid) > 0) {
c70ad9f7 1772 $query = 'SELECT fbv . *
abf1c50f 1773 FROM {feedback_value} fbv, {feedback_completed} fbc, {groups_members} gm
0085fff8 1774 WHERE fbv.item = ?
37b86a39 1775 AND fbv.completed = fbc.id
1776 AND fbc.userid = gm.userid
0085fff8 1777 AND gm.groupid = ?
1778 ORDER BY fbc.timemodified';
1779 $values = $DB->get_records_sql($query, array($item->id, $groupid));
1780
1781 } else {
c70ad9f7 1782 if ($courseid) {
0085fff8 1783 $values = $DB->get_records('feedback_value', array('item'=>$item->id, 'course_id'=>$courseid));
c70ad9f7 1784 } else {
0085fff8 1785 $values = $DB->get_records('feedback_value', array('item'=>$item->id));
c70ad9f7 1786 }
37b86a39 1787 }
0085fff8 1788 if ($DB->get_field('feedback', 'anonymous', array('id'=>$item->feedback)) == FEEDBACK_ANONYMOUS_YES) {
c70ad9f7 1789 if(is_array($values))
1790 shuffle($values);
1791 }
1792 return $values;
1793}
1794
37b86a39 1795/**
32be99dc 1796 * check for multiple_submit = false.
1797 * if the feedback is global so the courseid must be given
1798 *
1799 * @global object
1800 * @global object
1801 * @param int $feedbackid
1802 * @param int $courseid
1803 * @return boolean true if the feedback already is submitted otherwise false
c70ad9f7 1804 */
1805function feedback_is_already_submitted($feedbackid, $courseid = false) {
534792cd 1806 global $USER, $DB;
37b86a39 1807
534792cd 1808 if (!$trackings = $DB->get_records_menu('feedback_tracking', array('userid'=>$USER->id, 'feedback'=>$feedbackid), '', 'id, completed')) {
c70ad9f7 1809 return false;
1810 }
1811
1812 if($courseid) {
534792cd 1813 $select = 'completed IN ('.implode(',',$trackings).') AND course_id = ?';
1814 if(!$values = $DB->get_records_select('feedback_value', $select, array($courseid))) {
c70ad9f7 1815 return false;
1816 }
1817 }
1818
1819 return true;
1820}
1821
37b86a39 1822/**
32be99dc 1823 * if the completion of a feedback will be continued eg. by pagebreak or by multiple submit so the complete must be found.
1824 * if the param $tmp is set true so all things are related to temporary completeds
1825 *
1826 * @global object
1827 * @global object
1828 * @global object
1829 * @param int $feedbackid
1830 * @param boolean $tmp
1831 * @param int $courseid
1832 * @param string $guestid
1833 * @return int the id of the found completed
c70ad9f7 1834 */
1835function feedback_get_current_completed($feedbackid, $tmp = false, $courseid = false, $guestid = false) {
0085fff8 1836 global $USER, $CFG, $DB;
37b86a39 1837
c70ad9f7 1838 $tmpstr = $tmp ? 'tmp' : '';
37b86a39 1839
c70ad9f7 1840 if(!$courseid) {
1841 if($guestid) {
0085fff8 1842 return $DB->get_record('feedback_completed'.$tmpstr, array('feedback'=>$feedbackid, 'guestid'=>$guestid));
c70ad9f7 1843 }else {
0085fff8 1844 return $DB->get_record('feedback_completed'.$tmpstr, array('feedback'=>$feedbackid, 'userid'=>$USER->id));
c70ad9f7 1845 }
1846 }
37b86a39 1847
0085fff8 1848 $params = array();
37b86a39 1849
0085fff8 1850 if ($guestid) {
1851 $userselect = "AND fc.guestid = :guestid";
1852 $params['guestid'] = $guestid;
c70ad9f7 1853 }else {
0085fff8 1854 $userselect = "AND fc.userid = :userid";
1855 $params['userid'] = $USER->id;
c70ad9f7 1856 }
1857 //if courseid is set the feedback is global. there can be more than one completed on one feedback
0085fff8 1858 $sql = "SELECT fc.*
abf1c50f 1859 FROM {feedback_value{$tmpstr}} fv, {feedback_completed{$tmpstr}} fc
0085fff8 1860 WHERE fv.course_id = :courseid
c70ad9f7 1861 AND fv.completed = fc.id
0085fff8 1862 $userselect
1863 AND fc.feedback = :feedbackid";
1864 $params['courseid'] = intval($courseid);
1865 $params['feedbackid'] = $feedbackid;
c70ad9f7 1866
d90e0ef3 1867 if (!$sqlresult = $DB->get_records_sql($sql, $params)) {
0085fff8 1868 return false;
1869 }
c70ad9f7 1870 foreach($sqlresult as $r) {
0085fff8 1871 return $DB->get_record('feedback_completed'.$tmpstr, array('id'=>$r->id));
c70ad9f7 1872 }
1873}
1874
37b86a39 1875/**
32be99dc 1876 * get the completeds depending on the given groupid.
1877 *
1878 * @global object
1879 * @global object
1880 * @param object $feedback
1881 * @param int $groupid
1882 * @return mixed array of found completeds otherwise false
c70ad9f7 1883 */
59f89d80 1884function feedback_get_completeds_group($feedback, $groupid = false, $courseid = false) {
0085fff8 1885 global $CFG, $DB;
1886
1887 if (intval($groupid) > 0){
1888 $query = "SELECT fbc.*
abf1c50f 1889 FROM {feedback_completed} fbc, {groups_members} gm
0085fff8 1890 WHERE fbc.feedback = ?
1891 AND gm.groupid = ?
1892 AND fbc.userid = gm.userid";
1893 if ($values = $DB->get_records_sql($query, array($feedback->id, $groupid))) {
c70ad9f7 1894 return $values;
0085fff8 1895 } else {
1896 return false;
1897 }
1898 } else {
59f89d80 1899 if($courseid) {
1900 $query = "SELECT DISTINCT fbc.*
abf1c50f 1901 FROM {feedback_completed} fbc, {feedback_value} fbv
59f89d80 1902 WHERE fbc.id = fbv.completed
1903 AND fbc.feedback = ?
1904 AND fbv.course_id = ?
1905 ORDER BY random_response";
1906 if ($values = $DB->get_records_sql($query, array($feedback->id, $courseid))) {
1907 return $values;
1908 } else {
1909 return false;
1910 }
1911 }else {
1912 if ($values = $DB->get_records('feedback_completed', array('feedback'=>$feedback->id))) {
1913 return $values;
1914 } else {
1915 return false;
1916 }
0085fff8 1917 }
c70ad9f7 1918 }
1919}
1920
37b86a39 1921/**
32be99dc 1922 * get the count of completeds depending on the given groupid.
1923 *
1924 * @global object
1925 * @global object
1926 * @param object $feedback
1927 * @param int $groupid
1928 * @param int $courseid
1929 * @return mixed count of completeds or false
c70ad9f7 1930 */
1931function feedback_get_completeds_group_count($feedback, $groupid = false, $courseid = false) {
0085fff8 1932 global $CFG, $DB;
1933
1934 if ($courseid > 0 AND !$groupid <= 0) {
1935 $sql = "SELECT id, COUNT(item) AS ci
37b86a39 1936 FROM {feedback_value}
0085fff8 1937 WHERE course_id = ?
1938 GROUP BY item ORDER BY ci DESC";
1939 if ($foundrecs = $DB->get_records_sql($sql, array($courseid))) {
c70ad9f7 1940 $foundrecs = array_values($foundrecs);
1941 return $foundrecs[0]->ci;
1942 }
1943 return false;
1944 }
1945 if($values = feedback_get_completeds_group($feedback, $groupid)) {
1946 return sizeof($values);
1947 }else {
1948 return false;
1949 }
1950}
1951
1952/* get the own groupid.
1953@param object $course
1954@param object $cm
1955function feedback_get_groupid($course, $cm) {
1956 $groupmode = groupmode($course, $cm);
37b86a39 1957
c70ad9f7 1958 //get groupid
e3c7f155 1959 if($groupmode > 0 && !has_capability('moodle/site:doanything', get_context_instance(CONTEXT_SYSTEM))) {
c70ad9f7 1960 if($mygroupid = mygroupid($course->id)) {
1961 return $mygroupid[0]; //get the first groupid
1962 }
1963 }else {
1964 return false;
1965 }
1966}
1967 */
1968
37b86a39 1969/**
32be99dc 1970 * deletes all completed-recordsets from a feedback.
1971 * all related data such as values also will be deleted
1972 *
1973 * @global object
1974 * @param int $feedbackid
1975 * @return void
c70ad9f7 1976 */
1977function feedback_delete_all_completeds($feedbackid) {
0085fff8 1978 global $DB;
1979
1980 if (!$completeds = $DB->get_records('feedback_completed', array('feedback'=>$feedbackid))) {
1981 return;
1982 }
c70ad9f7 1983 foreach($completeds as $completed) {
1984 feedback_delete_completed($completed->id);
1985 }
1986}
1987
37b86a39 1988/**
32be99dc 1989 * deletes a completed given by completedid.
1990 * all related data such values or tracking data also will be deleted
d4b1d58c 1991 *
32be99dc 1992 * @global object
1993 * @param int $completedid
1994 * @return boolean
c70ad9f7 1995 */
1996function feedback_delete_completed($completedid) {
0085fff8 1997 global $DB;
1998
1999 if (!$completed = $DB->get_record('feedback_completed', array('id'=>$completedid))) {
c70ad9f7 2000 return false;
2001 }
2002 //first we delete all related values
0085fff8 2003 $DB->delete_records('feedback_value', array('completed'=>$completed->id));
37b86a39 2004
c70ad9f7 2005 //now we delete all tracking data
0085fff8 2006 if($tracking = $DB->get_record('feedback_tracking', array('completed'=>$completed->id, 'feedback'=>$completed->feedback))) {
2007 $DB->delete_records('feedback_tracking', array('completed'=>$completed->id));
c70ad9f7 2008 }
37b86a39 2009
c70ad9f7 2010 //last we delete the completed-record
0085fff8 2011 return $DB->delete_records('feedback_completed', array('id'=>$completed->id));
c70ad9f7 2012}
2013
2014////////////////////////////////////////////////
2015////////////////////////////////////////////////
2016////////////////////////////////////////////////
2017//functions to handle sitecourse mapping
2018////////////////////////////////////////////////
2019
37b86a39 2020/**
32be99dc 2021 * checks if the course and the feedback is in the table feedback_sitecourse_map.
2022 *
2023 * @global object
2024 * @param int $feedbackid
2025 * @param int $courseid
2026 * @return int the count of records
c70ad9f7 2027 */
2028function feedback_is_course_in_sitecourse_map($feedbackid, $courseid) {
0085fff8 2029 global $DB;
2030 return $DB->count_records('feedback_sitecourse_map', array('feedbackid'=>$feedbackid, 'courseid'=>$courseid));
c70ad9f7 2031}
2032
37b86a39 2033/**
32be99dc 2034 * checks if the feedback is in the table feedback_sitecourse_map.
2035 *
2036 * @global object
2037 * @param int $feedbackid
2038 * @return boolean
c70ad9f7 2039 */
2040function feedback_is_feedback_in_sitecourse_map($feedbackid) {
0085fff8 2041 global $Db;
2042 return $DB->record_exists('feedback_sitecourse_map', array('feedbackid'=>$feedbackid));
c70ad9f7 2043}
2044
37b86a39 2045/**
32be99dc 2046 * gets the feedbacks from table feedback_sitecourse_map.
2047 * this is used to show the global feedbacks on the feedback block
2048 * all feedbacks with the following criteria will be selected:<br />
2049 *
2050 * 1) all feedbacks which id are listed together with the courseid in sitecoursemap and<br />
2051 * 2) all feedbacks which not are listed in sitecoursemap
2052 *
2053 * @global object
2054 * @param int $courseid
2055 * @return array the feedback-records
c70ad9f7 2056 */
2057function feedback_get_feedbacks_from_sitecourse_map($courseid) {
0085fff8 2058 global $DB;
37b86a39 2059
c70ad9f7 2060 //first get all feedbacks listed in sitecourse_map with named courseid
0085fff8 2061 $sql = "SELECT f.id AS id, cm.id AS cmid, f.name AS name, f.timeopen AS timeopen, f.timeclose AS timeclose
2062 FROM {feedback} f, {course_modules} cm, {feedback_sitecourse_map} sm, {modules} m
2063 WHERE f.id = cm.instance
2064 AND f.course = '".SITEID."'
37b86a39 2065 AND m.id = cm.module
0085fff8 2066 AND m.name = 'feedback'
37b86a39 2067 AND sm.courseid = ?
0085fff8 2068 AND sm.feedbackid = f.id";
37b86a39 2069
0085fff8 2070 if (!$feedbacks1 = $DB->get_records_sql($sql, array($courseid))) {
c70ad9f7 2071 $feedbacks1 = array();
2072 }
37b86a39 2073
c70ad9f7 2074 //second get all feedbacks not listed in sitecourse_map
2075 $feedbacks2 = array();
0085fff8 2076 $sql = "SELECT f.id AS id, cm.id AS cmid, f.name AS name, f.timeopen AS timeopen, f.timeclose AS timeclose
2077 FROM {feedback} f, {course_modules} cm, {modules} m
2078 WHERE f.id = cm.instance
2079 AND f.course = '".SITEID."'
2080 AND m.id = cm.module
2081 AND m.name = 'feedback'";
2082 if (!$allfeedbacks = $DB->get_records_sql($sql)) {
c70ad9f7 2083 $allfeedbacks = array();
2084 }
2085 foreach($allfeedbacks as $a) {
0085fff8 2086 if(!$DB->record_exists('feedback_sitecourse_map', array('feedbackid'=>$a->id))) {
c70ad9f7 2087 $feedbacks2[] = $a;
2088 }
2089 }
37b86a39 2090
c70ad9f7 2091 return array_merge($feedbacks1, $feedbacks2);
37b86a39 2092
c70ad9f7 2093}
2094
37b86a39 2095/**
32be99dc 2096 * gets the courses from table feedback_sitecourse_map.
2097 *
2098 * @global object
2099 * @param int $feedbackid
2100 * @return array the course-records
c70ad9f7 2101 */
2102function feedback_get_courses_from_sitecourse_map($feedbackid) {
0085fff8 2103 global $DB;
37b86a39 2104
0085fff8 2105 $sql = "SELECT f.id, f.courseid, c.fullname, c.shortname
2106 FROM {feedback_sitecourse_map} f, {course} c
2107 WHERE c.id = f.courseid
2108 AND f.feedbackid = ?
2109 ORDER BY c.fullname";
37b86a39 2110
0085fff8 2111 return $DB->get_records_sql($sql, array($feedbackid));
37b86a39 2112
c70ad9f7 2113}
2114
37b86a39 2115/**
32be99dc 2116 * removes non existing courses or feedbacks from sitecourse_map.
2117 * it shouldn't be called all too often
2118 * a good place for it could be the mapcourse.php or unmapcourse.php
d4b1d58c 2119 *
32be99dc 2120 * @global object
2121 * @return void
c70ad9f7 2122 */
2123function feedback_clean_up_sitecourse_map() {
0085fff8 2124 global $DB;
2125
2126 $maps = $DB->get_records('feedback_sitecourse_map');
c70ad9f7 2127 foreach($maps as $map) {
0085fff8 2128 if (!$DB->get_record('course', array('id'=>$map->courseid))) {
2129 $DB->delete_records('feedback_sitecourse_map', array('courseid'=>$map->courseid, 'feedbackid'=>$map->feedbackid));
c70ad9f7 2130 continue;
2131 }
0085fff8 2132 if (!$DB->get_record('feedback', array('id'=>$map->feedbackid))) {
2133 $DB->delete_records('feedback_sitecourse_map', array('courseid'=>$map->courseid, 'feedbackid'=>$map->feedbackid));
c70ad9f7 2134 continue;
2135 }
37b86a39 2136
c70ad9f7 2137 }
2138}
2139
2140////////////////////////////////////////////////
2141////////////////////////////////////////////////
2142////////////////////////////////////////////////
2143//not relatable functions
2144////////////////////////////////////////////////
2145
37b86a39 2146/**
32be99dc 2147 * prints the option items of a selection-input item (dropdownlist).
2148 * @param int $startval the first value of the list
2149 * @param int $endval the last value of the list
2150 * @param int $selectval which item should be selected
2151 * @param int $interval the stepsize from the first to the last value
2152 * @return void
c70ad9f7 2153 */
2154function feedback_print_numeric_option_list($startval, $endval, $selectval = '', $interval = 1){
2155 for($i = $startval; $i <= $endval; $i += $interval){
2156 if($selectval == ($i)){
2157 $selected = 'selected="selected"';
2158 }else{
2159 $selected = '';
2160 }
2161 echo '<option '.$selected.'>'.$i.'</option>';
2162 }
2163}
2164
37b86a39 2165/**
32be99dc 2166 * sends an email to the teachers of the course where the given feedback is placed.
2167 *
2168 * @global object
2169 * @global object
2170 * @uses FEEDBACK_ANONYMOUS_NO
2171 * @uses FORMAT_PLAIN
2172 * @param object $cm the coursemodule-record
2173 * @param object $feedback
2174 * @param object $course
2175 * @param int $userid
2176 * @return void
c70ad9f7 2177 */
c184660d 2178function feedback_send_email($cm, $feedback, $course, $userid) {
c6307ef2 2179 global $CFG, $DB;
37b86a39 2180
c70ad9f7 2181 if ($feedback->email_notification == 0) { // No need to do anything
2182 return;
2183 }
37b86a39 2184
0085fff8 2185 $user = $DB->get_record('user', array('id'=>$userid));
37b86a39 2186
84973212 2187 if (isset($cm->groupmode) && empty($course->groupmodeforce)) {
2188 $groupmode = $cm->groupmode;
2189 } else {
2190 $groupmode = $course->groupmode;
2191 }
2192
2193 if ($groupmode == SEPARATEGROUPS) {
c6307ef2 2194 $groups = $DB->get_records_sql_menu("SELECT g.name, g.id
2195 FROM {groups} g, {groups_members} m
2196 WHERE g.courseid = ?
2197 AND g.id = m.groupid
2198 AND m.userid = ?
2199 ORDER BY name ASC", array($course->id, $userid));
c70ad9f7 2200 $groups = array_values($groups);
37b86a39 2201
c184660d 2202 $teachers = feedback_get_receivemail_users($cm->id, $groups);
c70ad9f7 2203 } else {
c184660d 2204 $teachers = feedback_get_receivemail_users($cm->id);
c70ad9f7 2205 }
37b86a39 2206
c70ad9f7 2207 if ($teachers) {
2208
2209 $strfeedbacks = get_string('modulenameplural', 'feedback');
2210 $strfeedback = get_string('modulename', 'feedback');
2211 $strcompleted = get_string('completed', 'feedback');
2212 $printusername = $feedback->anonymous == FEEDBACK_ANONYMOUS_NO ? fullname($user) : get_string('anonymous_user', 'feedback');
37b86a39 2213
c70ad9f7 2214 foreach ($teachers as $teacher) {
0085fff8 2215 $info = new object();
c70ad9f7 2216 $info->username = $printusername;
2217 $info->feedback = format_string($feedback->name,true);
2218 $info->url = $CFG->wwwroot.'/mod/feedback/show_entries.php?id='.$cm->id.'&userid='.$userid.'&do_show=showentries';
2219
2220 $postsubject = $strcompleted.': '.$info->username.' -> '.$feedback->name;
c184660d 2221 $posttext = feedback_send_email_text($info, $course);
2222 $posthtml = ($teacher->mailformat == 1) ? feedback_send_email_html($info, $course, $cm) : '';
37b86a39 2223
c70ad9f7 2224 if($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) {
3b120e46 2225 $eventdata = new object();
2226 $eventdata->modulename = 'feedback';
2227 $eventdata->userfrom = $user;
2228 $eventdata->userto = $teacher;
2229 $eventdata->subject = $postsubject;
2230 $eventdata->fullmessage = $posttext;
2231 $eventdata->fullmessageformat = FORMAT_PLAIN;
2232 $eventdata->fullmessagehtml = $posthtml;
2233 $eventdata->smallmessage = '';
7c7d3afa 2234 message_send($eventdata);
c70ad9f7 2235 }else {
3b120e46 2236 $eventdata = new object();
2237 $eventdata->modulename = 'feedback';
2238 $eventdata->userfrom = $teacher;
2239 $eventdata->userto = $teacher;
2240 $eventdata->subject = $postsubject;
2241 $eventdata->fullmessage = $posttext;
2242 $eventdata->fullmessageformat = FORMAT_PLAIN;
2243 $eventdata->fullmessagehtml = $posthtml;
2244 $eventdata->smallmessage = '';
7c7d3afa 2245 message_send($eventdata);
c70ad9f7 2246 }
2247 }
2248 }
2249}
2250
37b86a39 2251/**
32be99dc 2252 * sends an email to the teachers of the course where the given feedback is placed.
2253 *
2254 * @global object
2255 * @uses FORMAT_PLAIN
2256 * @param object $cm the coursemodule-record
2257 * @param object $feedback
2258 * @param object $course
2259 * @return void
c70ad9f7 2260 */
c184660d 2261function feedback_send_email_anonym($cm, $feedback, $course) {
c70ad9f7 2262 global $CFG;
37b86a39 2263
c70ad9f7 2264 if ($feedback->email_notification == 0) { // No need to do anything
2265 return;
2266 }
37b86a39 2267
c184660d 2268 $teachers = feedback_get_receivemail_users($cm->id);
c70ad9f7 2269
2270 if ($teachers) {
2271
2272 $strfeedbacks = get_string('modulenameplural', 'feedback');
2273 $strfeedback = get_string('modulename', 'feedback');
2274 $strcompleted = get_string('completed', 'feedback');
2275 $printusername = get_string('anonymous_user', 'feedback');
37b86a39 2276
c70ad9f7 2277 foreach ($teachers as $teacher) {
0085fff8 2278 $info = new object();
c70ad9f7 2279 $info->username = $printusername;
2280 $info->feedback = format_string($feedback->name,true);
2281 $info->url = $CFG->wwwroot.'/mod/feedback/show_entries_anonym.php?id='.$cm->id;
2282
2283 $postsubject = $strcompleted.': '.$info->username.' -> '.$feedback->name;
c184660d 2284 $posttext = feedback_send_email_text($info, $course);
2285 $posthtml = ($teacher->mailformat == 1) ? feedback_send_email_html($info, $course, $cm) : '';
37b86a39 2286
3b120e46 2287 $eventdata = new object();
2288 $eventdata->modulename = 'feedback';
2289 $eventdata->userfrom = $teacher;
2290 $eventdata->userto = $teacher;
2291 $eventdata->subject = $postsubject;
2292 $eventdata->fullmessage = $posttext;
2293 $eventdata->fullmessageformat = FORMAT_PLAIN;
2294 $eventdata->fullmessagehtml = $posthtml;
2295 $eventdata->smallmessage = '';
7c7d3afa 2296 message_send($eventdata);
c70ad9f7 2297 }
2298 }
2299}
2300
37b86a39 2301/**
32be99dc 2302 * send the text-part of the email
2303 *
2304 * @param object $info includes some infos about the feedback you want to send
2305 * @param object $course
2306 * @return string the text you want to post
c70ad9f7 2307 */
c184660d 2308function feedback_send_email_text($info, $course) {
c70ad9f7 2309 $posttext = $course->shortname.' -> '.get_string('modulenameplural', 'feedback').' -> '.
2310 $info->feedback."\n";
2311 $posttext .= '---------------------------------------------------------------------'."\n";
2312 $posttext .= get_string("emailteachermail", "feedback", $info)."\n";
2313 $posttext .= '---------------------------------------------------------------------'."\n";
2314 return $posttext;
2315}
2316
2317
37b86a39 2318/**
32be99dc 2319 * send the html-part of the email
2320 *
2321 * @global object
2322 * @param object $info includes some infos about the feedback you want to send
2323 * @param object $course
2324 * @return string the text you want to post
c70ad9f7 2325 */
c184660d 2326function feedback_send_email_html($info, $course, $cm) {
c70ad9f7 2327 global $CFG;
2328 $posthtml = '<p><font face="sans-serif">'.
5dee2210
AG
2329 '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'.$course->shortname.'</a> ->'.
2330 '<a href="'.$CFG->wwwroot.'/mod/feedback/index.php?id='.$course->id.'">'.get_string('modulenameplural', 'feedback').'</a> ->'.
2331 '<a href="'.$CFG->wwwroot.'/mod/feedback/view.php?id='.$cm->id.'">'.$info->feedback.'</a></font></p>';
c70ad9f7 2332 $posthtml .= '<hr /><font face="sans-serif">';
2333 $posthtml .= '<p>'.get_string('emailteachermailhtml', 'feedback', $info).'</p>';
2334 $posthtml .= '</font><hr />';
2335 return $posthtml;
2336}
2337
37b86a39 2338/**
32be99dc 2339 * print some errors to inform users about this.
2340 *
2341 * @global object
2342 * @return void
c70ad9f7 2343 */
2344function feedback_print_errors() {
37b86a39 2345
53b1f5da 2346 global $SESSION, $OUTPUT;
37b86a39 2347
f1b9e2df 2348 feedback_init_feedback_session();
2349
c70ad9f7 2350 if(empty($SESSION->feedback->errors)) {
78946b9b 2351 return;
c70ad9f7 2352 }
2353
d4b1d58c 2354 echo $OUTPUT->box_start('generalbox errorboxcontent boxaligncenter boxwidthnormal');
53b1f5da 2355 echo $OUTPUT->heading(get_string('handling_error', 'feedback'));
c70ad9f7 2356
2357 echo '<p align="center"><b><font color="black"><pre>';
2358 print_r($SESSION->feedback->errors) . "\n";
2359 echo '</pre></font></b></p>';
37b86a39 2360
d4b1d58c 2361 echo $OUTPUT->box_end();
c70ad9f7 2362 echo '<br /><br />';
2363 $SESSION->feedback->errors = array(); //remove errors
37b86a39 2364}
c70ad9f7 2365
32be99dc 2366/**
2367 * @param string $url
2368 * @return string
2369 */
c184660d 2370function feedback_encode_target_url($url) {
2371 if (strpos($url, '?')) {
2372 list($part1, $part2) = explode('?', $url, 2); //maximal 2 parts
2373 return $part1 . '?' . htmlentities($part2);
2374 } else {
2375 return $url;
2376 }
2377}
ab5bd34d 2378
0b29477b
SH
2379/**
2380 * Adds module specific settings to the settings block
2381 *
2382 * @param settings_navigation $settings The settings navigation object
2383 * @param navigation_node $feedbacknode The node to add module settings to
2384 */
2385function feedback_extend_settings_navigation(settings_navigation $settings, navigation_node $feedbacknode) {
2386 global $PAGE, $DB;
ab5bd34d 2387
c987dbad 2388 if (!$context = get_context_instance(CONTEXT_MODULE, $PAGE->cm->id)) {
3406acde 2389 print_error('badcontext');
c987dbad
AG
2390 }
2391
3406acde
SH
2392 if (has_capability('mod/feedback:edititems', $context)) {
2393 $questionnode = $feedbacknode->add(get_string('questions', 'feedback'));
2394 $questionnode->add(get_string('edit_items', 'feedback'), new moodle_url('/mod/feedback/edit.php', array('id'=>$PAGE->cm->id, 'do_show'=>'edit')));
2395 $questionnode->add(get_string('export_questions', 'feedback'), new moodle_url('/mod/feedback/export.php', array('id'=>$PAGE->cm->id, 'action'=>'exportfile')));
2396 $questionnode->add(get_string('import_questions', 'feedback'), new moodle_url('/mod/feedback/import.php', array('id'=>$PAGE->cm->id)));
2397 $questionnode->add(get_string('templates', 'feedback'), new moodle_url('/mod/feedback/edit.php', array('id'=>$PAGE->cm->id, 'do_show'=>'templates')));
ab5bd34d 2398 }
2399
3406acde 2400 if (has_capability('mod/feedback:viewreports', $context)) {
0b29477b 2401 $feedback = $DB->get_record('feedback', array('id'=>$PAGE->cm->instance));
ab5bd34d 2402 if($feedback->course == SITEID){
0b29477b 2403 $feedbacknode->add(get_string('analysis', 'feedback'), new moodle_url('/mod/feedback/analysis_course.php', array('id'=>$PAGE->cm->id, 'course'=>$PAGE->course->id,'do_show'=>'analysis')));
ab5bd34d 2404 }else {
0b29477b 2405 $feedbacknode->add(get_string('analysis', 'feedback'), new moodle_url('/mod/feedback/analysis.php', array('id'=>$PAGE->cm->id, 'course'=>$PAGE->course->id,'do_show'=>'analysis')));
ab5bd34d 2406 }
ab5bd34d 2407
0b29477b 2408 $feedbacknode->add(get_string('show_entries', 'feedback'), new moodle_url('/mod/feedback/show_entries.php', array('id'=>$PAGE->cm->id, 'do_show'=>'showentries')));
ab5bd34d 2409 }
c987dbad 2410}
f1b9e2df 2411
2412function feedback_init_feedback_session() {
2413 //initialize the feedback-Session - not nice at all!!
2414 global $SESSION;
2415 if (!empty($SESSION)) {
2416 if (!isset($SESSION->feedback) OR !is_object($SESSION->feedback)) {
2417 $SESSION->feedback = new object();
2418 }
2419 }
ab5bd34d 2420}