[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Library of functions and constants for module feedback 19 * includes the main-part of feedback-functions 20 * 21 * @package mod_feedback 22 * @copyright Andreas Grabs 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 /** Include eventslib.php */ 27 require_once($CFG->libdir.'/eventslib.php'); 28 // Include forms lib. 29 require_once($CFG->libdir.'/formslib.php'); 30 31 define('FEEDBACK_ANONYMOUS_YES', 1); 32 define('FEEDBACK_ANONYMOUS_NO', 2); 33 define('FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP', 2); 34 define('FEEDBACK_DECIMAL', '.'); 35 define('FEEDBACK_THOUSAND', ','); 36 define('FEEDBACK_RESETFORM_RESET', 'feedback_reset_data_'); 37 define('FEEDBACK_RESETFORM_DROP', 'feedback_drop_feedback_'); 38 define('FEEDBACK_MAX_PIX_LENGTH', '400'); //max. Breite des grafischen Balkens in der Auswertung 39 define('FEEDBACK_DEFAULT_PAGE_COUNT', 20); 40 41 /** 42 * Returns all other caps used in module. 43 * 44 * @return array 45 */ 46 function feedback_get_extra_capabilities() { 47 return array('moodle/site:accessallgroups'); 48 } 49 50 /** 51 * @uses FEATURE_GROUPS 52 * @uses FEATURE_GROUPINGS 53 * @uses FEATURE_MOD_INTRO 54 * @uses FEATURE_COMPLETION_TRACKS_VIEWS 55 * @uses FEATURE_GRADE_HAS_GRADE 56 * @uses FEATURE_GRADE_OUTCOMES 57 * @param string $feature FEATURE_xx constant for requested feature 58 * @return mixed True if module supports feature, null if doesn't know 59 */ 60 function feedback_supports($feature) { 61 switch($feature) { 62 case FEATURE_GROUPS: return true; 63 case FEATURE_GROUPINGS: return true; 64 case FEATURE_MOD_INTRO: return true; 65 case FEATURE_COMPLETION_TRACKS_VIEWS: return true; 66 case FEATURE_COMPLETION_HAS_RULES: return true; 67 case FEATURE_GRADE_HAS_GRADE: return false; 68 case FEATURE_GRADE_OUTCOMES: return false; 69 case FEATURE_BACKUP_MOODLE2: return true; 70 case FEATURE_SHOW_DESCRIPTION: return true; 71 72 default: return null; 73 } 74 } 75 76 /** 77 * this will create a new instance and return the id number 78 * of the new instance. 79 * 80 * @global object 81 * @param object $feedback the object given by mod_feedback_mod_form 82 * @return int 83 */ 84 function feedback_add_instance($feedback) { 85 global $DB; 86 87 $feedback->timemodified = time(); 88 $feedback->id = ''; 89 90 if (empty($feedback->site_after_submit)) { 91 $feedback->site_after_submit = ''; 92 } 93 94 //saving the feedback in db 95 $feedbackid = $DB->insert_record("feedback", $feedback); 96 97 $feedback->id = $feedbackid; 98 99 feedback_set_events($feedback); 100 101 if (!isset($feedback->coursemodule)) { 102 $cm = get_coursemodule_from_id('feedback', $feedback->id); 103 $feedback->coursemodule = $cm->id; 104 } 105 $context = context_module::instance($feedback->coursemodule); 106 107 $editoroptions = feedback_get_editor_options(); 108 109 // process the custom wysiwyg editor in page_after_submit 110 if ($draftitemid = $feedback->page_after_submit_editor['itemid']) { 111 $feedback->page_after_submit = file_save_draft_area_files($draftitemid, $context->id, 112 'mod_feedback', 'page_after_submit', 113 0, $editoroptions, 114 $feedback->page_after_submit_editor['text']); 115 116 $feedback->page_after_submitformat = $feedback->page_after_submit_editor['format']; 117 } 118 $DB->update_record('feedback', $feedback); 119 120 return $feedbackid; 121 } 122 123 /** 124 * this will update a given instance 125 * 126 * @global object 127 * @param object $feedback the object given by mod_feedback_mod_form 128 * @return boolean 129 */ 130 function feedback_update_instance($feedback) { 131 global $DB; 132 133 $feedback->timemodified = time(); 134 $feedback->id = $feedback->instance; 135 136 if (empty($feedback->site_after_submit)) { 137 $feedback->site_after_submit = ''; 138 } 139 140 //save the feedback into the db 141 $DB->update_record("feedback", $feedback); 142 143 //create or update the new events 144 feedback_set_events($feedback); 145 146 $context = context_module::instance($feedback->coursemodule); 147 148 $editoroptions = feedback_get_editor_options(); 149 150 // process the custom wysiwyg editor in page_after_submit 151 if ($draftitemid = $feedback->page_after_submit_editor['itemid']) { 152 $feedback->page_after_submit = file_save_draft_area_files($draftitemid, $context->id, 153 'mod_feedback', 'page_after_submit', 154 0, $editoroptions, 155 $feedback->page_after_submit_editor['text']); 156 157 $feedback->page_after_submitformat = $feedback->page_after_submit_editor['format']; 158 } 159 $DB->update_record('feedback', $feedback); 160 161 return true; 162 } 163 164 /** 165 * Serves the files included in feedback items like label. Implements needed access control ;-) 166 * 167 * There are two situations in general where the files will be sent. 168 * 1) filearea = item, 2) filearea = template 169 * 170 * @package mod_feedback 171 * @category files 172 * @param stdClass $course course object 173 * @param stdClass $cm course module object 174 * @param stdClass $context context object 175 * @param string $filearea file area 176 * @param array $args extra arguments 177 * @param bool $forcedownload whether or not force download 178 * @param array $options additional options affecting the file serving 179 * @return bool false if file not found, does not return if found - justsend the file 180 */ 181 function feedback_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) { 182 global $CFG, $DB; 183 184 if ($filearea === 'item' or $filearea === 'template') { 185 $itemid = (int)array_shift($args); 186 //get the item what includes the file 187 if (!$item = $DB->get_record('feedback_item', array('id'=>$itemid))) { 188 return false; 189 } 190 $feedbackid = $item->feedback; 191 $templateid = $item->template; 192 } 193 194 if ($filearea === 'page_after_submit' or $filearea === 'item') { 195 if (! $feedback = $DB->get_record("feedback", array("id"=>$cm->instance))) { 196 return false; 197 } 198 199 $feedbackid = $feedback->id; 200 201 //if the filearea is "item" so we check the permissions like view/complete the feedback 202 $canload = false; 203 //first check whether the user has the complete capability 204 if (has_capability('mod/feedback:complete', $context)) { 205 $canload = true; 206 } 207 208 //now we check whether the user has the view capability 209 if (has_capability('mod/feedback:view', $context)) { 210 $canload = true; 211 } 212 213 //if the feedback is on frontpage and anonymous and the fullanonymous is allowed 214 //so the file can be loaded too. 215 if (isset($CFG->feedback_allowfullanonymous) 216 AND $CFG->feedback_allowfullanonymous 217 AND $course->id == SITEID 218 AND $feedback->anonymous == FEEDBACK_ANONYMOUS_YES ) { 219 $canload = true; 220 } 221 222 if (!$canload) { 223 return false; 224 } 225 } else if ($filearea === 'template') { //now we check files in templates 226 if (!$template = $DB->get_record('feedback_template', array('id'=>$templateid))) { 227 return false; 228 } 229 230 //if the file is not public so the capability edititems has to be there 231 if (!$template->ispublic) { 232 if (!has_capability('mod/feedback:edititems', $context)) { 233 return false; 234 } 235 } else { //on public templates, at least the user has to be logged in 236 if (!isloggedin()) { 237 return false; 238 } 239 } 240 } else { 241 return false; 242 } 243 244 if ($context->contextlevel == CONTEXT_MODULE) { 245 if ($filearea !== 'item' and $filearea !== 'page_after_submit') { 246 return false; 247 } 248 } 249 250 if ($context->contextlevel == CONTEXT_COURSE || $context->contextlevel == CONTEXT_SYSTEM) { 251 if ($filearea !== 'template') { 252 return false; 253 } 254 } 255 256 $relativepath = implode('/', $args); 257 if ($filearea === 'page_after_submit') { 258 $fullpath = "/{$context->id}/mod_feedback/$filearea/$relativepath"; 259 } else { 260 $fullpath = "/{$context->id}/mod_feedback/$filearea/{$item->id}/$relativepath"; 261 } 262 263 $fs = get_file_storage(); 264 265 if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) { 266 return false; 267 } 268 269 // finally send the file 270 send_stored_file($file, 0, 0, true, $options); // download MUST be forced - security! 271 272 return false; 273 } 274 275 /** 276 * this will delete a given instance. 277 * all referenced data also will be deleted 278 * 279 * @global object 280 * @param int $id the instanceid of feedback 281 * @return boolean 282 */ 283 function feedback_delete_instance($id) { 284 global $DB; 285 286 //get all referenced items 287 $feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$id)); 288 289 //deleting all referenced items and values 290 if (is_array($feedbackitems)) { 291 foreach ($feedbackitems as $feedbackitem) { 292 $DB->delete_records("feedback_value", array("item"=>$feedbackitem->id)); 293 $DB->delete_records("feedback_valuetmp", array("item"=>$feedbackitem->id)); 294 } 295 if ($delitems = $DB->get_records("feedback_item", array("feedback"=>$id))) { 296 foreach ($delitems as $delitem) { 297 feedback_delete_item($delitem->id, false); 298 } 299 } 300 } 301 302 //deleting the completeds 303 $DB->delete_records("feedback_completed", array("feedback"=>$id)); 304 305 //deleting the unfinished completeds 306 $DB->delete_records("feedback_completedtmp", array("feedback"=>$id)); 307 308 //deleting old events 309 $DB->delete_records('event', array('modulename'=>'feedback', 'instance'=>$id)); 310 return $DB->delete_records("feedback", array("id"=>$id)); 311 } 312 313 /** 314 * Return a small object with summary information about what a 315 * user has done with a given particular instance of this module 316 * Used for user activity reports. 317 * $return->time = the time they did it 318 * $return->info = a short text description 319 * 320 * @param object $course 321 * @param object $user 322 * @param object $mod 323 * @param object $feedback 324 * @return object 325 */ 326 function feedback_user_outline($course, $user, $mod, $feedback) { 327 return null; 328 } 329 330 /** 331 * Returns all users who has completed a specified feedback since a given time 332 * many thanks to Manolescu Dorel, who contributed these two functions 333 * 334 * @global object 335 * @global object 336 * @global object 337 * @global object 338 * @uses CONTEXT_MODULE 339 * @param array $activities Passed by reference 340 * @param int $index Passed by reference 341 * @param int $timemodified Timestamp 342 * @param int $courseid 343 * @param int $cmid 344 * @param int $userid 345 * @param int $groupid 346 * @return void 347 */ 348 function feedback_get_recent_mod_activity(&$activities, &$index, 349 $timemodified, $courseid, 350 $cmid, $userid="", $groupid="") { 351 352 global $CFG, $COURSE, $USER, $DB; 353 354 if ($COURSE->id == $courseid) { 355 $course = $COURSE; 356 } else { 357 $course = $DB->get_record('course', array('id'=>$courseid)); 358 } 359 360 $modinfo = get_fast_modinfo($course); 361 362 $cm = $modinfo->cms[$cmid]; 363 364 $sqlargs = array(); 365 366 $userfields = user_picture::fields('u', null, 'useridagain'); 367 $sql = " SELECT fk . * , fc . * , $userfields 368 FROM {feedback_completed} fc 369 JOIN {feedback} fk ON fk.id = fc.feedback 370 JOIN {user} u ON u.id = fc.userid "; 371 372 if ($groupid) { 373 $sql .= " JOIN {groups_members} gm ON gm.userid=u.id "; 374 } 375 376 $sql .= " WHERE fc.timemodified > ? 377 AND fk.id = ? 378 AND fc.anonymous_response = ?"; 379 $sqlargs[] = $timemodified; 380 $sqlargs[] = $cm->instance; 381 $sqlargs[] = FEEDBACK_ANONYMOUS_NO; 382 383 if ($userid) { 384 $sql .= " AND u.id = ? "; 385 $sqlargs[] = $userid; 386 } 387 388 if ($groupid) { 389 $sql .= " AND gm.groupid = ? "; 390 $sqlargs[] = $groupid; 391 } 392 393 if (!$feedbackitems = $DB->get_records_sql($sql, $sqlargs)) { 394 return; 395 } 396 397 $cm_context = context_module::instance($cm->id); 398 399 if (!has_capability('mod/feedback:view', $cm_context)) { 400 return; 401 } 402 403 $accessallgroups = has_capability('moodle/site:accessallgroups', $cm_context); 404 $viewfullnames = has_capability('moodle/site:viewfullnames', $cm_context); 405 $groupmode = groups_get_activity_groupmode($cm, $course); 406 407 $aname = format_string($cm->name, true); 408 foreach ($feedbackitems as $feedbackitem) { 409 if ($feedbackitem->userid != $USER->id) { 410 411 if ($groupmode == SEPARATEGROUPS and !$accessallgroups) { 412 $usersgroups = groups_get_all_groups($course->id, 413 $feedbackitem->userid, 414 $cm->groupingid); 415 if (!is_array($usersgroups)) { 416 continue; 417 } 418 $usersgroups = array_keys($usersgroups); 419 $intersect = array_intersect($usersgroups, $modinfo->get_groups($cm->groupingid)); 420 if (empty($intersect)) { 421 continue; 422 } 423 } 424 } 425 426 $tmpactivity = new stdClass(); 427 428 $tmpactivity->type = 'feedback'; 429 $tmpactivity->cmid = $cm->id; 430 $tmpactivity->name = $aname; 431 $tmpactivity->sectionnum= $cm->sectionnum; 432 $tmpactivity->timestamp = $feedbackitem->timemodified; 433 434 $tmpactivity->content = new stdClass(); 435 $tmpactivity->content->feedbackid = $feedbackitem->id; 436 $tmpactivity->content->feedbackuserid = $feedbackitem->userid; 437 438 $tmpactivity->user = user_picture::unalias($feedbackitem, null, 'useridagain'); 439 $tmpactivity->user->fullname = fullname($feedbackitem, $viewfullnames); 440 441 $activities[$index++] = $tmpactivity; 442 } 443 444 return; 445 } 446 447 /** 448 * Prints all users who has completed a specified feedback since a given time 449 * many thanks to Manolescu Dorel, who contributed these two functions 450 * 451 * @global object 452 * @param object $activity 453 * @param int $courseid 454 * @param string $detail 455 * @param array $modnames 456 * @return void Output is echo'd 457 */ 458 function feedback_print_recent_mod_activity($activity, $courseid, $detail, $modnames) { 459 global $CFG, $OUTPUT; 460 461 echo '<table border="0" cellpadding="3" cellspacing="0" class="forum-recent">'; 462 463 echo "<tr><td class=\"userpicture\" valign=\"top\">"; 464 echo $OUTPUT->user_picture($activity->user, array('courseid'=>$courseid)); 465 echo "</td><td>"; 466 467 if ($detail) { 468 $modname = $modnames[$activity->type]; 469 echo '<div class="title">'; 470 echo "<img src=\"" . $OUTPUT->pix_url('icon', $activity->type) . "\" ". 471 "class=\"icon\" alt=\"$modname\" />"; 472 echo "<a href=\"$CFG->wwwroot/mod/feedback/view.php?id={$activity->cmid}\">{$activity->name}</a>"; 473 echo '</div>'; 474 } 475 476 echo '<div class="title">'; 477 echo '</div>'; 478 479 echo '<div class="user">'; 480 echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->id}&course=$courseid\">" 481 ."{$activity->user->fullname}</a> - ".userdate($activity->timestamp); 482 echo '</div>'; 483 484 echo "</td></tr></table>"; 485 486 return; 487 } 488 489 /** 490 * Obtains the automatic completion state for this feedback based on the condition 491 * in feedback settings. 492 * 493 * @param object $course Course 494 * @param object $cm Course-module 495 * @param int $userid User ID 496 * @param bool $type Type of comparison (or/and; can be used as return value if no conditions) 497 * @return bool True if completed, false if not, $type if conditions not set. 498 */ 499 function feedback_get_completion_state($course, $cm, $userid, $type) { 500 global $CFG, $DB; 501 502 // Get feedback details 503 $feedback = $DB->get_record('feedback', array('id'=>$cm->instance), '*', MUST_EXIST); 504 505 // If completion option is enabled, evaluate it and return true/false 506 if ($feedback->completionsubmit) { 507 $params = array('userid'=>$userid, 'feedback'=>$feedback->id); 508 return $DB->record_exists('feedback_completed', $params); 509 } else { 510 // Completion option is not enabled so just return $type 511 return $type; 512 } 513 } 514 515 516 /** 517 * Print a detailed representation of what a user has done with 518 * a given particular instance of this module, for user activity reports. 519 * 520 * @param object $course 521 * @param object $user 522 * @param object $mod 523 * @param object $feedback 524 * @return bool 525 */ 526 function feedback_user_complete($course, $user, $mod, $feedback) { 527 return true; 528 } 529 530 /** 531 * @return bool true 532 */ 533 function feedback_cron () { 534 return true; 535 } 536 537 /** 538 * @return bool false 539 */ 540 function feedback_scale_used ($feedbackid, $scaleid) { 541 return false; 542 } 543 544 /** 545 * Checks if scale is being used by any instance of feedback 546 * 547 * This is used to find out if scale used anywhere 548 * @param $scaleid int 549 * @return boolean True if the scale is used by any assignment 550 */ 551 function feedback_scale_used_anywhere($scaleid) { 552 return false; 553 } 554 555 /** 556 * List the actions that correspond to a view of this module. 557 * This is used by the participation report. 558 * 559 * Note: This is not used by new logging system. Event with 560 * crud = 'r' and edulevel = LEVEL_PARTICIPATING will 561 * be considered as view action. 562 * 563 * @return array 564 */ 565 function feedback_get_view_actions() { 566 return array('view', 'view all'); 567 } 568 569 /** 570 * List the actions that correspond to a post of this module. 571 * This is used by the participation report. 572 * 573 * Note: This is not used by new logging system. Event with 574 * crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING 575 * will be considered as post action. 576 * 577 * @return array 578 */ 579 function feedback_get_post_actions() { 580 return array('submit'); 581 } 582 583 /** 584 * This function is used by the reset_course_userdata function in moodlelib. 585 * This function will remove all responses from the specified feedback 586 * and clean up any related data. 587 * 588 * @global object 589 * @global object 590 * @uses FEEDBACK_RESETFORM_RESET 591 * @uses FEEDBACK_RESETFORM_DROP 592 * @param object $data the data submitted from the reset course. 593 * @return array status array 594 */ 595 function feedback_reset_userdata($data) { 596 global $CFG, $DB; 597 598 $resetfeedbacks = array(); 599 $dropfeedbacks = array(); 600 $status = array(); 601 $componentstr = get_string('modulenameplural', 'feedback'); 602 603 //get the relevant entries from $data 604 foreach ($data as $key => $value) { 605 switch(true) { 606 case substr($key, 0, strlen(FEEDBACK_RESETFORM_RESET)) == FEEDBACK_RESETFORM_RESET: 607 if ($value == 1) { 608 $templist = explode('_', $key); 609 if (isset($templist[3])) { 610 $resetfeedbacks[] = intval($templist[3]); 611 } 612 } 613 break; 614 case substr($key, 0, strlen(FEEDBACK_RESETFORM_DROP)) == FEEDBACK_RESETFORM_DROP: 615 if ($value == 1) { 616 $templist = explode('_', $key); 617 if (isset($templist[3])) { 618 $dropfeedbacks[] = intval($templist[3]); 619 } 620 } 621 break; 622 } 623 } 624 625 //reset the selected feedbacks 626 foreach ($resetfeedbacks as $id) { 627 $feedback = $DB->get_record('feedback', array('id'=>$id)); 628 feedback_delete_all_completeds($feedback); 629 $status[] = array('component'=>$componentstr.':'.$feedback->name, 630 'item'=>get_string('resetting_data', 'feedback'), 631 'error'=>false); 632 } 633 634 // Updating dates - shift may be negative too. 635 if ($data->timeshift) { 636 $shifterror = !shift_course_mod_dates('feedback', array('timeopen', 'timeclose'), $data->timeshift, $data->courseid); 637 $status[] = array('component' => $componentstr, 'item' => get_string('datechanged'), 'error' => $shifterror); 638 } 639 640 return $status; 641 } 642 643 /** 644 * Called by course/reset.php 645 * 646 * @global object 647 * @uses FEEDBACK_RESETFORM_RESET 648 * @param object $mform form passed by reference 649 */ 650 function feedback_reset_course_form_definition(&$mform) { 651 global $COURSE, $DB; 652 653 $mform->addElement('header', 'feedbackheader', get_string('modulenameplural', 'feedback')); 654 655 if (!$feedbacks = $DB->get_records('feedback', array('course'=>$COURSE->id), 'name')) { 656 return; 657 } 658 659 $mform->addElement('static', 'hint', get_string('resetting_data', 'feedback')); 660 foreach ($feedbacks as $feedback) { 661 $mform->addElement('checkbox', FEEDBACK_RESETFORM_RESET.$feedback->id, $feedback->name); 662 } 663 } 664 665 /** 666 * Course reset form defaults. 667 * 668 * @global object 669 * @uses FEEDBACK_RESETFORM_RESET 670 * @param object $course 671 */ 672 function feedback_reset_course_form_defaults($course) { 673 global $DB; 674 675 $return = array(); 676 if (!$feedbacks = $DB->get_records('feedback', array('course'=>$course->id), 'name')) { 677 return; 678 } 679 foreach ($feedbacks as $feedback) { 680 $return[FEEDBACK_RESETFORM_RESET.$feedback->id] = true; 681 } 682 return $return; 683 } 684 685 /** 686 * Called by course/reset.php and shows the formdata by coursereset. 687 * it prints checkboxes for each feedback available at the given course 688 * there are two checkboxes: 689 * 1) delete userdata and keep the feedback 690 * 2) delete userdata and drop the feedback 691 * 692 * @global object 693 * @uses FEEDBACK_RESETFORM_RESET 694 * @uses FEEDBACK_RESETFORM_DROP 695 * @param object $course 696 * @return void 697 */ 698 function feedback_reset_course_form($course) { 699 global $DB, $OUTPUT; 700 701 echo get_string('resetting_feedbacks', 'feedback'); echo ':<br />'; 702 if (!$feedbacks = $DB->get_records('feedback', array('course'=>$course->id), 'name')) { 703 return; 704 } 705 706 foreach ($feedbacks as $feedback) { 707 echo '<p>'; 708 echo get_string('name', 'feedback').': '.$feedback->name.'<br />'; 709 echo html_writer::checkbox(FEEDBACK_RESETFORM_RESET.$feedback->id, 710 1, true, 711 get_string('resetting_data', 'feedback')); 712 echo '<br />'; 713 echo html_writer::checkbox(FEEDBACK_RESETFORM_DROP.$feedback->id, 714 1, false, 715 get_string('drop_feedback', 'feedback')); 716 echo '</p>'; 717 } 718 } 719 720 /** 721 * This gets an array with default options for the editor 722 * 723 * @return array the options 724 */ 725 function feedback_get_editor_options() { 726 return array('maxfiles' => EDITOR_UNLIMITED_FILES, 727 'trusttext'=>true); 728 } 729 730 /** 731 * This creates new events given as timeopen and closeopen by $feedback. 732 * 733 * @global object 734 * @param object $feedback 735 * @return void 736 */ 737 function feedback_set_events($feedback) { 738 global $DB, $CFG; 739 740 // Include calendar/lib.php. 741 require_once($CFG->dirroot.'/calendar/lib.php'); 742 743 // Get CMID if not sent as part of $feedback. 744 if (!isset($feedback->coursemodule)) { 745 $cm = get_coursemodule_from_instance('feedback', $feedback->id, $feedback->course); 746 $feedback->coursemodule = $cm->id; 747 } 748 749 // Feedback start calendar events. 750 $eventid = $DB->get_field('event', 'id', 751 array('modulename' => 'feedback', 'instance' => $feedback->id, 'eventtype' => 'open')); 752 753 if (isset($feedback->timeopen) && $feedback->timeopen > 0) { 754 $event = new stdClass(); 755 $event->name = get_string('calendarstart', 'feedback', $feedback->name); 756 $event->description = format_module_intro('feedback', $feedback, $feedback->coursemodule); 757 $event->timestart = $feedback->timeopen; 758 $event->visible = instance_is_visible('feedback', $feedback); 759 $event->timeduration = 0; 760 if ($eventid) { 761 // Calendar event exists so update it. 762 $event->id = $eventid; 763 $calendarevent = calendar_event::load($event->id); 764 $calendarevent->update($event); 765 } else { 766 // Event doesn't exist so create one. 767 $event->courseid = $feedback->course; 768 $event->groupid = 0; 769 $event->userid = 0; 770 $event->modulename = 'feedback'; 771 $event->instance = $feedback->id; 772 $event->eventtype = 'open'; 773 calendar_event::create($event); 774 } 775 } else if ($eventid) { 776 // Calendar event is on longer needed. 777 $calendarevent = calendar_event::load($eventid); 778 $calendarevent->delete(); 779 } 780 781 // Feedback close calendar events. 782 $eventid = $DB->get_field('event', 'id', 783 array('modulename' => 'feedback', 'instance' => $feedback->id, 'eventtype' => 'close')); 784 785 if (isset($feedback->timeclose) && $feedback->timeclose > 0) { 786 $event = new stdClass(); 787 $event->name = get_string('calendarend', 'feedback', $feedback->name); 788 $event->description = format_module_intro('feedback', $feedback, $feedback->coursemodule); 789 $event->timestart = $feedback->timeclose; 790 $event->visible = instance_is_visible('feedback', $feedback); 791 $event->timeduration = 0; 792 if ($eventid) { 793 // Calendar event exists so update it. 794 $event->id = $eventid; 795 $calendarevent = calendar_event::load($event->id); 796 $calendarevent->update($event); 797 } else { 798 // Event doesn't exist so create one. 799 $event->courseid = $feedback->course; 800 $event->groupid = 0; 801 $event->userid = 0; 802 $event->modulename = 'feedback'; 803 $event->instance = $feedback->id; 804 $event->eventtype = 'close'; 805 calendar_event::create($event); 806 } 807 } else if ($eventid) { 808 // Calendar event is on longer needed. 809 $calendarevent = calendar_event::load($eventid); 810 $calendarevent->delete(); 811 } 812 } 813 814 /** 815 * This standard function will check all instances of this module 816 * and make sure there are up-to-date events created for each of them. 817 * If courseid = 0, then every feedback event in the site is checked, else 818 * only feedback events belonging to the course specified are checked. 819 * This function is used, in its new format, by restore_refresh_events() 820 * 821 * @param int $courseid 822 * @return bool 823 */ 824 function feedback_refresh_events($courseid = 0) { 825 global $DB; 826 827 if ($courseid) { 828 if (! $feedbacks = $DB->get_records("feedback", array("course" => $courseid))) { 829 return true; 830 } 831 } else { 832 if (! $feedbacks = $DB->get_records("feedback")) { 833 return true; 834 } 835 } 836 837 foreach ($feedbacks as $feedback) { 838 feedback_set_events($feedback); 839 } 840 return true; 841 } 842 843 /** 844 * this function is called by {@link feedback_delete_userdata()} 845 * it drops the feedback-instance from the course_module table 846 * 847 * @global object 848 * @param int $id the id from the coursemodule 849 * @return boolean 850 */ 851 function feedback_delete_course_module($id) { 852 global $DB; 853 854 if (!$cm = $DB->get_record('course_modules', array('id'=>$id))) { 855 return true; 856 } 857 return $DB->delete_records('course_modules', array('id'=>$cm->id)); 858 } 859 860 861 862 //////////////////////////////////////////////// 863 //functions to handle capabilities 864 //////////////////////////////////////////////// 865 866 /** 867 * returns the context-id related to the given coursemodule-id 868 * 869 * @deprecated since 3.1 870 * @staticvar object $context 871 * @param int $cmid the coursemodule-id 872 * @return object $context 873 */ 874 function feedback_get_context($cmid) { 875 debugging('Function feedback_get_context() is deprecated because it was not used.', 876 DEBUG_DEVELOPER); 877 static $context; 878 879 if (isset($context)) { 880 return $context; 881 } 882 883 $context = context_module::instance($cmid); 884 return $context; 885 } 886 887 /** 888 * returns true if the current role is faked by switching role feature 889 * 890 * @global object 891 * @return boolean 892 */ 893 function feedback_check_is_switchrole() { 894 global $USER; 895 if (isset($USER->switchrole) AND 896 is_array($USER->switchrole) AND 897 count($USER->switchrole) > 0) { 898 899 return true; 900 } 901 return false; 902 } 903 904 /** 905 * count users which have not completed the feedback 906 * 907 * @global object 908 * @uses CONTEXT_MODULE 909 * @param cm_info $cm Course-module object 910 * @param int $group single groupid 911 * @param string $sort 912 * @param int $startpage 913 * @param int $pagecount 914 * @return object the userrecords 915 */ 916 function feedback_get_incomplete_users(cm_info $cm, 917 $group = false, 918 $sort = '', 919 $startpage = false, 920 $pagecount = false) { 921 922 global $DB; 923 924 $context = context_module::instance($cm->id); 925 926 //first get all user who can complete this feedback 927 $cap = 'mod/feedback:complete'; 928 $fields = 'u.id, u.username'; 929 if (!$allusers = get_users_by_capability($context, 930 $cap, 931 $fields, 932 $sort, 933 '', 934 '', 935 $group, 936 '', 937 true)) { 938 return false; 939 } 940 // Filter users that are not in the correct group/grouping. 941 $info = new \core_availability\info_module($cm); 942 $allusers = $info->filter_user_list($allusers); 943 944 $allusers = array_keys($allusers); 945 946 //now get all completeds 947 $params = array('feedback'=>$cm->instance); 948 if (!$completedusers = $DB->get_records_menu('feedback_completed', $params, '', 'userid,id')) { 949 return $allusers; 950 } 951 $completedusers = array_keys($completedusers); 952 953 //now strike all completedusers from allusers 954 $allusers = array_diff($allusers, $completedusers); 955 956 //for paging I use array_slice() 957 if ($startpage !== false AND $pagecount !== false) { 958 $allusers = array_slice($allusers, $startpage, $pagecount); 959 } 960 961 return $allusers; 962 } 963 964 /** 965 * count users which have not completed the feedback 966 * 967 * @global object 968 * @param object $cm 969 * @param int $group single groupid 970 * @return int count of userrecords 971 */ 972 function feedback_count_incomplete_users($cm, $group = false) { 973 if ($allusers = feedback_get_incomplete_users($cm, $group)) { 974 return count($allusers); 975 } 976 return 0; 977 } 978 979 /** 980 * count users which have completed a feedback 981 * 982 * @global object 983 * @uses FEEDBACK_ANONYMOUS_NO 984 * @param object $cm 985 * @param int $group single groupid 986 * @return int count of userrecords 987 */ 988 function feedback_count_complete_users($cm, $group = false) { 989 global $DB; 990 991 $params = array(FEEDBACK_ANONYMOUS_NO, $cm->instance); 992 993 $fromgroup = ''; 994 $wheregroup = ''; 995 if ($group) { 996 $fromgroup = ', {groups_members} g'; 997 $wheregroup = ' AND g.groupid = ? AND g.userid = c.userid'; 998 $params[] = $group; 999 } 1000 1001 $sql = 'SELECT COUNT(u.id) FROM {user} u, {feedback_completed} c'.$fromgroup.' 1002 WHERE anonymous_response = ? AND u.id = c.userid AND c.feedback = ? 1003 '.$wheregroup; 1004 1005 return $DB->count_records_sql($sql, $params); 1006 1007 } 1008 1009 /** 1010 * get users which have completed a feedback 1011 * 1012 * @global object 1013 * @uses CONTEXT_MODULE 1014 * @uses FEEDBACK_ANONYMOUS_NO 1015 * @param object $cm 1016 * @param int $group single groupid 1017 * @param string $where a sql where condition (must end with " AND ") 1018 * @param array parameters used in $where 1019 * @param string $sort a table field 1020 * @param int $startpage 1021 * @param int $pagecount 1022 * @return object the userrecords 1023 */ 1024 function feedback_get_complete_users($cm, 1025 $group = false, 1026 $where = '', 1027 array $params = null, 1028 $sort = '', 1029 $startpage = false, 1030 $pagecount = false) { 1031 1032 global $DB; 1033 1034 $context = context_module::instance($cm->id); 1035 1036 $params = (array)$params; 1037 1038 $params['anon'] = FEEDBACK_ANONYMOUS_NO; 1039 $params['instance'] = $cm->instance; 1040 1041 $fromgroup = ''; 1042 $wheregroup = ''; 1043 if ($group) { 1044 $fromgroup = ', {groups_members} g'; 1045 $wheregroup = ' AND g.groupid = :group AND g.userid = c.userid'; 1046 $params['group'] = $group; 1047 } 1048 1049 if ($sort) { 1050 $sortsql = ' ORDER BY '.$sort; 1051 } else { 1052 $sortsql = ''; 1053 } 1054 1055 $ufields = user_picture::fields('u'); 1056 $sql = 'SELECT DISTINCT '.$ufields.', c.timemodified as completed_timemodified 1057 FROM {user} u, {feedback_completed} c '.$fromgroup.' 1058 WHERE '.$where.' anonymous_response = :anon 1059 AND u.id = c.userid 1060 AND c.feedback = :instance 1061 '.$wheregroup.$sortsql; 1062 1063 if ($startpage === false OR $pagecount === false) { 1064 $startpage = false; 1065 $pagecount = false; 1066 } 1067 return $DB->get_records_sql($sql, $params, $startpage, $pagecount); 1068 } 1069 1070 /** 1071 * get users which have the viewreports-capability 1072 * 1073 * @uses CONTEXT_MODULE 1074 * @param int $cmid 1075 * @param mixed $groups single groupid or array of groupids - group(s) user is in 1076 * @return object the userrecords 1077 */ 1078 function feedback_get_viewreports_users($cmid, $groups = false) { 1079 1080 $context = context_module::instance($cmid); 1081 1082 //description of the call below: 1083 //get_users_by_capability($context, $capability, $fields='', $sort='', $limitfrom='', 1084 // $limitnum='', $groups='', $exceptions='', $doanything=true) 1085 return get_users_by_capability($context, 1086 'mod/feedback:viewreports', 1087 '', 1088 'lastname', 1089 '', 1090 '', 1091 $groups, 1092 '', 1093 false); 1094 } 1095 1096 /** 1097 * get users which have the receivemail-capability 1098 * 1099 * @uses CONTEXT_MODULE 1100 * @param int $cmid 1101 * @param mixed $groups single groupid or array of groupids - group(s) user is in 1102 * @return object the userrecords 1103 */ 1104 function feedback_get_receivemail_users($cmid, $groups = false) { 1105 1106 $context = context_module::instance($cmid); 1107 1108 //description of the call below: 1109 //get_users_by_capability($context, $capability, $fields='', $sort='', $limitfrom='', 1110 // $limitnum='', $groups='', $exceptions='', $doanything=true) 1111 return get_users_by_capability($context, 1112 'mod/feedback:receivemail', 1113 '', 1114 'lastname', 1115 '', 1116 '', 1117 $groups, 1118 '', 1119 false); 1120 } 1121 1122 //////////////////////////////////////////////// 1123 //functions to handle the templates 1124 //////////////////////////////////////////////// 1125 //////////////////////////////////////////////// 1126 1127 /** 1128 * creates a new template-record. 1129 * 1130 * @global object 1131 * @param int $courseid 1132 * @param string $name the name of template shown in the templatelist 1133 * @param int $ispublic 0:privat 1:public 1134 * @return int the new templateid 1135 */ 1136 function feedback_create_template($courseid, $name, $ispublic = 0) { 1137 global $DB; 1138 1139 $templ = new stdClass(); 1140 $templ->course = ($ispublic ? 0 : $courseid); 1141 $templ->name = $name; 1142 $templ->ispublic = $ispublic; 1143 1144 $templid = $DB->insert_record('feedback_template', $templ); 1145 return $DB->get_record('feedback_template', array('id'=>$templid)); 1146 } 1147 1148 /** 1149 * creates new template items. 1150 * all items will be copied and the attribute feedback will be set to 0 1151 * and the attribute template will be set to the new templateid 1152 * 1153 * @global object 1154 * @uses CONTEXT_MODULE 1155 * @uses CONTEXT_COURSE 1156 * @param object $feedback 1157 * @param string $name the name of template shown in the templatelist 1158 * @param int $ispublic 0:privat 1:public 1159 * @return boolean 1160 */ 1161 function feedback_save_as_template($feedback, $name, $ispublic = 0) { 1162 global $DB; 1163 $fs = get_file_storage(); 1164 1165 if (!$feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$feedback->id))) { 1166 return false; 1167 } 1168 1169 if (!$newtempl = feedback_create_template($feedback->course, $name, $ispublic)) { 1170 return false; 1171 } 1172 1173 //files in the template_item are in the context of the current course or 1174 //if the template is public the files are in the system context 1175 //files in the feedback_item are in the feedback_context of the feedback 1176 if ($ispublic) { 1177 $s_context = context_system::instance(); 1178 } else { 1179 $s_context = context_course::instance($newtempl->course); 1180 } 1181 $cm = get_coursemodule_from_instance('feedback', $feedback->id); 1182 $f_context = context_module::instance($cm->id); 1183 1184 //create items of this new template 1185 //depend items we are storing temporary in an mapping list array(new id => dependitem) 1186 //we also store a mapping of all items array(oldid => newid) 1187 $dependitemsmap = array(); 1188 $itembackup = array(); 1189 foreach ($feedbackitems as $item) { 1190 1191 $t_item = clone($item); 1192 1193 unset($t_item->id); 1194 $t_item->feedback = 0; 1195 $t_item->template = $newtempl->id; 1196 $t_item->id = $DB->insert_record('feedback_item', $t_item); 1197 //copy all included files to the feedback_template filearea 1198 $itemfiles = $fs->get_area_files($f_context->id, 1199 'mod_feedback', 1200 'item', 1201 $item->id, 1202 "id", 1203 false); 1204 if ($itemfiles) { 1205 foreach ($itemfiles as $ifile) { 1206 $file_record = new stdClass(); 1207 $file_record->contextid = $s_context->id; 1208 $file_record->component = 'mod_feedback'; 1209 $file_record->filearea = 'template'; 1210 $file_record->itemid = $t_item->id; 1211 $fs->create_file_from_storedfile($file_record, $ifile); 1212 } 1213 } 1214 1215 $itembackup[$item->id] = $t_item->id; 1216 if ($t_item->dependitem) { 1217 $dependitemsmap[$t_item->id] = $t_item->dependitem; 1218 } 1219 1220 } 1221 1222 //remapping the dependency 1223 foreach ($dependitemsmap as $key => $dependitem) { 1224 $newitem = $DB->get_record('feedback_item', array('id'=>$key)); 1225 $newitem->dependitem = $itembackup[$newitem->dependitem]; 1226 $DB->update_record('feedback_item', $newitem); 1227 } 1228 1229 return true; 1230 } 1231 1232 /** 1233 * deletes all feedback_items related to the given template id 1234 * 1235 * @global object 1236 * @uses CONTEXT_COURSE 1237 * @param object $template the template 1238 * @return void 1239 */ 1240 function feedback_delete_template($template) { 1241 global $DB; 1242 1243 //deleting the files from the item is done by feedback_delete_item 1244 if ($t_items = $DB->get_records("feedback_item", array("template"=>$template->id))) { 1245 foreach ($t_items as $t_item) { 1246 feedback_delete_item($t_item->id, false, $template); 1247 } 1248 } 1249 $DB->delete_records("feedback_template", array("id"=>$template->id)); 1250 } 1251 1252 /** 1253 * creates new feedback_item-records from template. 1254 * if $deleteold is set true so the existing items of the given feedback will be deleted 1255 * if $deleteold is set false so the new items will be appanded to the old items 1256 * 1257 * @global object 1258 * @uses CONTEXT_COURSE 1259 * @uses CONTEXT_MODULE 1260 * @param object $feedback 1261 * @param int $templateid 1262 * @param boolean $deleteold 1263 */ 1264 function feedback_items_from_template($feedback, $templateid, $deleteold = false) { 1265 global $DB, $CFG; 1266 1267 require_once($CFG->libdir.'/completionlib.php'); 1268 1269 $fs = get_file_storage(); 1270 1271 if (!$template = $DB->get_record('feedback_template', array('id'=>$templateid))) { 1272 return false; 1273 } 1274 //get all templateitems 1275 if (!$templitems = $DB->get_records('feedback_item', array('template'=>$templateid))) { 1276 return false; 1277 } 1278 1279 //files in the template_item are in the context of the current course 1280 //files in the feedback_item are in the feedback_context of the feedback 1281 if ($template->ispublic) { 1282 $s_context = context_system::instance(); 1283 } else { 1284 $s_context = context_course::instance($feedback->course); 1285 } 1286 $course = $DB->get_record('course', array('id'=>$feedback->course)); 1287 $cm = get_coursemodule_from_instance('feedback', $feedback->id); 1288 $f_context = context_module::instance($cm->id); 1289 1290 //if deleteold then delete all old items before 1291 //get all items 1292 if ($deleteold) { 1293 if ($feedbackitems = $DB->get_records('feedback_item', array('feedback'=>$feedback->id))) { 1294 //delete all items of this feedback 1295 foreach ($feedbackitems as $item) { 1296 feedback_delete_item($item->id, false); 1297 } 1298 1299 $params = array('feedback'=>$feedback->id); 1300 if ($completeds = $DB->get_records('feedback_completed', $params)) { 1301 $completion = new completion_info($course); 1302 foreach ($completeds as $completed) { 1303 // Update completion state 1304 if ($completion->is_enabled($cm) && $feedback->completionsubmit) { 1305 $completion->update_state($cm, COMPLETION_INCOMPLETE, $completed->userid); 1306 } 1307 $DB->delete_records('feedback_completed', array('id'=>$completed->id)); 1308 } 1309 } 1310 $DB->delete_records('feedback_completedtmp', array('feedback'=>$feedback->id)); 1311 } 1312 $positionoffset = 0; 1313 } else { 1314 //if the old items are kept the new items will be appended 1315 //therefor the new position has an offset 1316 $positionoffset = $DB->count_records('feedback_item', array('feedback'=>$feedback->id)); 1317 } 1318 1319 //create items of this new template 1320 //depend items we are storing temporary in an mapping list array(new id => dependitem) 1321 //we also store a mapping of all items array(oldid => newid) 1322 $dependitemsmap = array(); 1323 $itembackup = array(); 1324 foreach ($templitems as $t_item) { 1325 $item = clone($t_item); 1326 unset($item->id); 1327 $item->feedback = $feedback->id; 1328 $item->template = 0; 1329 $item->position = $item->position + $positionoffset; 1330 1331 $item->id = $DB->insert_record('feedback_item', $item); 1332 1333 //moving the files to the new item 1334 $templatefiles = $fs->get_area_files($s_context->id, 1335 'mod_feedback', 1336 'template', 1337 $t_item->id, 1338 "id", 1339 false); 1340 if ($templatefiles) { 1341 foreach ($templatefiles as $tfile) { 1342 $file_record = new stdClass(); 1343 $file_record->contextid = $f_context->id; 1344 $file_record->component = 'mod_feedback'; 1345 $file_record->filearea = 'item'; 1346 $file_record->itemid = $item->id; 1347 $fs->create_file_from_storedfile($file_record, $tfile); 1348 } 1349 } 1350 1351 $itembackup[$t_item->id] = $item->id; 1352 if ($item->dependitem) { 1353 $dependitemsmap[$item->id] = $item->dependitem; 1354 } 1355 } 1356 1357 //remapping the dependency 1358 foreach ($dependitemsmap as $key => $dependitem) { 1359 $newitem = $DB->get_record('feedback_item', array('id'=>$key)); 1360 $newitem->dependitem = $itembackup[$newitem->dependitem]; 1361 $DB->update_record('feedback_item', $newitem); 1362 } 1363 } 1364 1365 /** 1366 * get the list of available templates. 1367 * if the $onlyown param is set true so only templates from own course will be served 1368 * this is important for droping templates 1369 * 1370 * @global object 1371 * @param object $course 1372 * @param string $onlyownorpublic 1373 * @return array the template recordsets 1374 */ 1375 function feedback_get_template_list($course, $onlyownorpublic = '') { 1376 global $DB, $CFG; 1377 1378 switch($onlyownorpublic) { 1379 case '': 1380 $templates = $DB->get_records_select('feedback_template', 1381 'course = ? OR ispublic = 1', 1382 array($course->id), 1383 'name'); 1384 break; 1385 case 'own': 1386 $templates = $DB->get_records('feedback_template', 1387 array('course'=>$course->id), 1388 'name'); 1389 break; 1390 case 'public': 1391 $templates = $DB->get_records('feedback_template', array('ispublic'=>1), 'name'); 1392 break; 1393 } 1394 return $templates; 1395 } 1396 1397 //////////////////////////////////////////////// 1398 //Handling der Items 1399 //////////////////////////////////////////////// 1400 //////////////////////////////////////////////// 1401 1402 /** 1403 * load the lib.php from item-plugin-dir and returns the instance of the itemclass 1404 * 1405 * @param string $typ 1406 * @return feedback_item_base the instance of itemclass 1407 */ 1408 function feedback_get_item_class($typ) { 1409 global $CFG; 1410 1411 //get the class of item-typ 1412 $itemclass = 'feedback_item_'.$typ; 1413 //get the instance of item-class 1414 if (!class_exists($itemclass)) { 1415 require_once($CFG->dirroot.'/mod/feedback/item/'.$typ.'/lib.php'); 1416 } 1417 return new $itemclass(); 1418 } 1419 1420 /** 1421 * load the available item plugins from given subdirectory of $CFG->dirroot 1422 * the default is "mod/feedback/item" 1423 * 1424 * @global object 1425 * @param string $dir the subdir 1426 * @return array pluginnames as string 1427 */ 1428 function feedback_load_feedback_items($dir = 'mod/feedback/item') { 1429 global $CFG; 1430 $names = get_list_of_plugins($dir); 1431 $ret_names = array(); 1432 1433 foreach ($names as $name) { 1434 require_once($CFG->dirroot.'/'.$dir.'/'.$name.'/lib.php'); 1435 if (class_exists('feedback_item_'.$name)) { 1436 $ret_names[] = $name; 1437 } 1438 } 1439 return $ret_names; 1440 } 1441 1442 /** 1443 * load the available item plugins to use as dropdown-options 1444 * 1445 * @global object 1446 * @return array pluginnames as string 1447 */ 1448 function feedback_load_feedback_items_options() { 1449 global $CFG; 1450 1451 $feedback_options = array("pagebreak" => get_string('add_pagebreak', 'feedback')); 1452 1453 if (!$feedback_names = feedback_load_feedback_items('mod/feedback/item')) { 1454 return array(); 1455 } 1456 1457 foreach ($feedback_names as $fn) { 1458 $feedback_options[$fn] = get_string($fn, 'feedback'); 1459 } 1460 asort($feedback_options); 1461 return $feedback_options; 1462 } 1463 1464 /** 1465 * load the available items for the depend item dropdown list shown in the edit_item form 1466 * 1467 * @global object 1468 * @param object $feedback 1469 * @param object $item the item of the edit_item form 1470 * @return array all items except the item $item, labels and pagebreaks 1471 */ 1472 function feedback_get_depend_candidates_for_item($feedback, $item) { 1473 global $DB; 1474 //all items for dependitem 1475 $where = "feedback = ? AND typ != 'pagebreak' AND hasvalue = 1"; 1476 $params = array($feedback->id); 1477 if (isset($item->id) AND $item->id) { 1478 $where .= ' AND id != ?'; 1479 $params[] = $item->id; 1480 } 1481 $dependitems = array(0 => get_string('choose')); 1482 $feedbackitems = $DB->get_records_select_menu('feedback_item', 1483 $where, 1484 $params, 1485 'position', 1486 'id, label'); 1487 1488 if (!$feedbackitems) { 1489 return $dependitems; 1490 } 1491 //adding the choose-option 1492 foreach ($feedbackitems as $key => $val) { 1493 if (trim(strval($val)) !== '') { 1494 $dependitems[$key] = format_string($val); 1495 } 1496 } 1497 return $dependitems; 1498 } 1499 1500 /** 1501 * creates a new item-record 1502 * 1503 * @deprecated since 3.1 1504 * @param object $data the data from edit_item_form 1505 * @return int the new itemid 1506 */ 1507 function feedback_create_item($data) { 1508 debugging('Function feedback_create_item() is deprecated because it was not used.', 1509 DEBUG_DEVELOPER); 1510 global $DB; 1511 1512 $item = new stdClass(); 1513 $item->feedback = $data->feedbackid; 1514 1515 $item->template=0; 1516 if (isset($data->templateid)) { 1517 $item->template = intval($data->templateid); 1518 } 1519 1520 $itemname = trim($data->itemname); 1521 $item->name = ($itemname ? $data->itemname : get_string('no_itemname', 'feedback')); 1522 1523 if (!empty($data->itemlabel)) { 1524 $item->label = trim($data->itemlabel); 1525 } else { 1526 $item->label = get_string('no_itemlabel', 'feedback'); 1527 } 1528 1529 $itemobj = feedback_get_item_class($data->typ); 1530 $item->presentation = ''; //the date comes from postupdate() of the itemobj 1531 1532 $item->hasvalue = $itemobj->get_hasvalue(); 1533 1534 $item->typ = $data->typ; 1535 $item->position = $data->position; 1536 1537 $item->required=0; 1538 if (!empty($data->required)) { 1539 $item->required = $data->required; 1540 } 1541 1542 $item->id = $DB->insert_record('feedback_item', $item); 1543 1544 //move all itemdata to the data 1545 $data->id = $item->id; 1546 $data->feedback = $item->feedback; 1547 $data->name = $item->name; 1548 $data->label = $item->label; 1549 $data->required = $item->required; 1550 return $itemobj->postupdate($data); 1551 } 1552 1553 /** 1554 * save the changes of a given item. 1555 * 1556 * @global object 1557 * @param object $item 1558 * @return boolean 1559 */ 1560 function feedback_update_item($item) { 1561 global $DB; 1562 return $DB->update_record("feedback_item", $item); 1563 } 1564 1565 /** 1566 * deletes an item and also deletes all related values 1567 * 1568 * @global object 1569 * @uses CONTEXT_MODULE 1570 * @param int $itemid 1571 * @param boolean $renumber should the kept items renumbered Yes/No 1572 * @param object $template if the template is given so the items are bound to it 1573 * @return void 1574 */ 1575 function feedback_delete_item($itemid, $renumber = true, $template = false) { 1576 global $DB; 1577 1578 $item = $DB->get_record('feedback_item', array('id'=>$itemid)); 1579 1580 //deleting the files from the item 1581 $fs = get_file_storage(); 1582 1583 if ($template) { 1584 if ($template->ispublic) { 1585 $context = context_system::instance(); 1586 } else { 1587 $context = context_course::instance($template->course); 1588 } 1589 $templatefiles = $fs->get_area_files($context->id, 1590 'mod_feedback', 1591 'template', 1592 $item->id, 1593 "id", 1594 false); 1595 1596 if ($templatefiles) { 1597 $fs->delete_area_files($context->id, 'mod_feedback', 'template', $item->id); 1598 } 1599 } else { 1600 if (!$cm = get_coursemodule_from_instance('feedback', $item->feedback)) { 1601 return false; 1602 } 1603 $context = context_module::instance($cm->id); 1604 1605 $itemfiles = $fs->get_area_files($context->id, 1606 'mod_feedback', 1607 'item', 1608 $item->id, 1609 "id", false); 1610 1611 if ($itemfiles) { 1612 $fs->delete_area_files($context->id, 'mod_feedback', 'item', $item->id); 1613 } 1614 } 1615 1616 $DB->delete_records("feedback_value", array("item"=>$itemid)); 1617 $DB->delete_records("feedback_valuetmp", array("item"=>$itemid)); 1618 1619 //remove all depends 1620 $DB->set_field('feedback_item', 'dependvalue', '', array('dependitem'=>$itemid)); 1621 $DB->set_field('feedback_item', 'dependitem', 0, array('dependitem'=>$itemid)); 1622 1623 $DB->delete_records("feedback_item", array("id"=>$itemid)); 1624 if ($renumber) { 1625 feedback_renumber_items($item->feedback); 1626 } 1627 } 1628 1629 /** 1630 * deletes all items of the given feedbackid 1631 * 1632 * @global object 1633 * @param int $feedbackid 1634 * @return void 1635 */ 1636 function feedback_delete_all_items($feedbackid) { 1637 global $DB, $CFG; 1638 require_once($CFG->libdir.'/completionlib.php'); 1639 1640 if (!$feedback = $DB->get_record('feedback', array('id'=>$feedbackid))) { 1641 return false; 1642 } 1643 1644 if (!$cm = get_coursemodule_from_instance('feedback', $feedback->id)) { 1645 return false; 1646 } 1647 1648 if (!$course = $DB->get_record('course', array('id'=>$feedback->course))) { 1649 return false; 1650 } 1651 1652 if (!$items = $DB->get_records('feedback_item', array('feedback'=>$feedbackid))) { 1653 return; 1654 } 1655 foreach ($items as $item) { 1656 feedback_delete_item($item->id, false); 1657 } 1658 if ($completeds = $DB->get_records('feedback_completed', array('feedback'=>$feedback->id))) { 1659 $completion = new completion_info($course); 1660 foreach ($completeds as $completed) { 1661 // Update completion state 1662 if ($completion->is_enabled($cm) && $feedback->completionsubmit) { 1663 $completion->update_state($cm, COMPLETION_INCOMPLETE, $completed->userid); 1664 } 1665 $DB->delete_records('feedback_completed', array('id'=>$completed->id)); 1666 } 1667 } 1668 1669 $DB->delete_records('feedback_completedtmp', array('feedback'=>$feedbackid)); 1670 1671 } 1672 1673 /** 1674 * this function toggled the item-attribute required (yes/no) 1675 * 1676 * @global object 1677 * @param object $item 1678 * @return boolean 1679 */ 1680 function feedback_switch_item_required($item) { 1681 global $DB, $CFG; 1682 1683 $itemobj = feedback_get_item_class($item->typ); 1684 1685 if ($itemobj->can_switch_require()) { 1686 $new_require_val = (int)!(bool)$item->required; 1687 $params = array('id'=>$item->id); 1688 $DB->set_field('feedback_item', 'required', $new_require_val, $params); 1689 } 1690 return true; 1691 } 1692 1693 /** 1694 * renumbers all items of the given feedbackid 1695 * 1696 * @global object 1697 * @param int $feedbackid 1698 * @return void 1699 */ 1700 function feedback_renumber_items($feedbackid) { 1701 global $DB; 1702 1703 $items = $DB->get_records('feedback_item', array('feedback'=>$feedbackid), 'position'); 1704 $pos = 1; 1705 if ($items) { 1706 foreach ($items as $item) { 1707 $DB->set_field('feedback_item', 'position', $pos, array('id'=>$item->id)); 1708 $pos++; 1709 } 1710 } 1711 } 1712 1713 /** 1714 * this decreases the position of the given item 1715 * 1716 * @global object 1717 * @param object $item 1718 * @return bool 1719 */ 1720 function feedback_moveup_item($item) { 1721 global $DB; 1722 1723 if ($item->position == 1) { 1724 return true; 1725 } 1726 1727 $params = array('feedback'=>$item->feedback); 1728 if (!$items = $DB->get_records('feedback_item', $params, 'position')) { 1729 return false; 1730 } 1731 1732 $itembefore = null; 1733 foreach ($items as $i) { 1734 if ($i->id == $item->id) { 1735 if (is_null($itembefore)) { 1736 return true; 1737 } 1738 $itembefore->position = $item->position; 1739 $item->position--; 1740 feedback_update_item($itembefore); 1741 feedback_update_item($item); 1742 feedback_renumber_items($item->feedback); 1743 return true; 1744 } 1745 $itembefore = $i; 1746 } 1747 return false; 1748 } 1749 1750 /** 1751 * this increased the position of the given item 1752 * 1753 * @global object 1754 * @param object $item 1755 * @return bool 1756 */ 1757 function feedback_movedown_item($item) { 1758 global $DB; 1759 1760 $params = array('feedback'=>$item->feedback); 1761 if (!$items = $DB->get_records('feedback_item', $params, 'position')) { 1762 return false; 1763 } 1764 1765 $movedownitem = null; 1766 foreach ($items as $i) { 1767 if (!is_null($movedownitem) AND $movedownitem->id == $item->id) { 1768 $movedownitem->position = $i->position; 1769 $i->position--; 1770 feedback_update_item($movedownitem); 1771 feedback_update_item($i); 1772 feedback_renumber_items($item->feedback); 1773 return true; 1774 } 1775 $movedownitem = $i; 1776 } 1777 return false; 1778 } 1779 1780 /** 1781 * here the position of the given item will be set to the value in $pos 1782 * 1783 * @global object 1784 * @param object $moveitem 1785 * @param int $pos 1786 * @return boolean 1787 */ 1788 function feedback_move_item($moveitem, $pos) { 1789 global $DB; 1790 1791 $params = array('feedback'=>$moveitem->feedback); 1792 if (!$allitems = $DB->get_records('feedback_item', $params, 'position')) { 1793 return false; 1794 } 1795 if (is_array($allitems)) { 1796 $index = 1; 1797 foreach ($allitems as $item) { 1798 if ($index == $pos) { 1799 $index++; 1800 } 1801 if ($item->id == $moveitem->id) { 1802 $moveitem->position = $pos; 1803 feedback_update_item($moveitem); 1804 continue; 1805 } 1806 $item->position = $index; 1807 feedback_update_item($item); 1808 $index++; 1809 } 1810 return true; 1811 } 1812 return false; 1813 } 1814 1815 /** 1816 * prints the given item as a preview. 1817 * each item-class has an own print_item_preview function implemented. 1818 * 1819 * @deprecated since Moodle 3.1 1820 * @global object 1821 * @param object $item the item what we want to print out 1822 * @return void 1823 */ 1824 function feedback_print_item_preview($item) { 1825 debugging('Function feedback_print_item_preview() is deprecated and does nothing. ' 1826 . 'Items must implement complete_form_element()', DEBUG_DEVELOPER); 1827 } 1828 1829 /** 1830 * prints the given item in the completion form. 1831 * each item-class has an own print_item_complete function implemented. 1832 * 1833 * @deprecated since Moodle 3.1 1834 * @param object $item the item what we want to print out 1835 * @param mixed $value the value 1836 * @param boolean $highlightrequire if this set true and the value are false on completing so the item will be highlighted 1837 * @return void 1838 */ 1839 function feedback_print_item_complete($item, $value = false, $highlightrequire = false) { 1840 debugging('Function feedback_print_item_complete() is deprecated and does nothing. ' 1841 . 'Items must implement complete_form_element()', DEBUG_DEVELOPER); 1842 } 1843 1844 /** 1845 * prints the given item in the show entries page. 1846 * each item-class has an own print_item_show_value function implemented. 1847 * 1848 * @deprecated since Moodle 3.1 1849 * @param object $item the item what we want to print out 1850 * @param mixed $value 1851 * @return void 1852 */ 1853 function feedback_print_item_show_value($item, $value = false) { 1854 debugging('Function feedback_print_item_show_value() is deprecated and does nothing. ' 1855 . 'Items must implement complete_form_element()', DEBUG_DEVELOPER); 1856 } 1857 1858 /** 1859 * if the user completes a feedback and there is a pagebreak so the values are saved temporary. 1860 * the values are not saved permanently until the user click on save button 1861 * 1862 * @global object 1863 * @param object $feedbackcompleted 1864 * @return object temporary saved completed-record 1865 */ 1866 function feedback_set_tmp_values($feedbackcompleted) { 1867 global $DB; 1868 debugging('Function feedback_set_tmp_values() is deprecated and since it is ' 1869 . 'no longer used in mod_feedback', DEBUG_DEVELOPER); 1870 1871 //first we create a completedtmp 1872 $tmpcpl = new stdClass(); 1873 foreach ($feedbackcompleted as $key => $value) { 1874 $tmpcpl->{$key} = $value; 1875 } 1876 unset($tmpcpl->id); 1877 $tmpcpl->timemodified = time(); 1878 $tmpcpl->id = $DB->insert_record('feedback_completedtmp', $tmpcpl); 1879 //get all values of original-completed 1880 if (!$values = $DB->get_records('feedback_value', array('completed'=>$feedbackcompleted->id))) { 1881 return; 1882 } 1883 foreach ($values as $value) { 1884 unset($value->id); 1885 $value->completed = $tmpcpl->id; 1886 $DB->insert_record('feedback_valuetmp', $value); 1887 } 1888 return $tmpcpl; 1889 } 1890 1891 /** 1892 * this saves the temporary saved values permanently 1893 * 1894 * @global object 1895 * @param object $feedbackcompletedtmp the temporary completed 1896 * @param object $feedbackcompleted the target completed 1897 * @return int the id of the completed 1898 */ 1899 function feedback_save_tmp_values($feedbackcompletedtmp, $feedbackcompleted) { 1900 global $DB; 1901 1902 $tmpcplid = $feedbackcompletedtmp->id; 1903 if ($feedbackcompleted) { 1904 //first drop all existing values 1905 $DB->delete_records('feedback_value', array('completed'=>$feedbackcompleted->id)); 1906 //update the current completed 1907 $feedbackcompleted->timemodified = time(); 1908 $DB->update_record('feedback_completed', $feedbackcompleted); 1909 } else { 1910 $feedbackcompleted = clone($feedbackcompletedtmp); 1911 $feedbackcompleted->id = ''; 1912 $feedbackcompleted->timemodified = time(); 1913 $feedbackcompleted->id = $DB->insert_record('feedback_completed', $feedbackcompleted); 1914 } 1915 1916 $allitems = $DB->get_records('feedback_item', array('feedback' => $feedbackcompleted->feedback)); 1917 1918 //save all the new values from feedback_valuetmp 1919 //get all values of tmp-completed 1920 $params = array('completed'=>$feedbackcompletedtmp->id); 1921 $values = $DB->get_records('feedback_valuetmp', $params); 1922 foreach ($values as $value) { 1923 //check if there are depend items 1924 $item = $DB->get_record('feedback_item', array('id'=>$value->item)); 1925 if ($item->dependitem > 0 && isset($allitems[$item->dependitem])) { 1926 $check = feedback_compare_item_value($tmpcplid, 1927 $allitems[$item->dependitem], 1928 $item->dependvalue, 1929 true); 1930 } else { 1931 $check = true; 1932 } 1933 if ($check) { 1934 unset($value->id); 1935 $value->completed = $feedbackcompleted->id; 1936 $DB->insert_record('feedback_value', $value); 1937 } 1938 } 1939 //drop all the tmpvalues 1940 $DB->delete_records('feedback_valuetmp', array('completed'=>$tmpcplid)); 1941 $DB->delete_records('feedback_completedtmp', array('id'=>$tmpcplid)); 1942 1943 // Trigger event for the delete action we performed. 1944 $cm = get_coursemodule_from_instance('feedback', $feedbackcompleted->feedback); 1945 $event = \mod_feedback\event\response_submitted::create_from_record($feedbackcompleted, $cm); 1946 $event->trigger(); 1947 return $feedbackcompleted->id; 1948 1949 } 1950 1951 /** 1952 * deletes the given temporary completed and all related temporary values 1953 * 1954 * @deprecated since Moodle 3.1 1955 * 1956 * @param int $tmpcplid 1957 * @return void 1958 */ 1959 function feedback_delete_completedtmp($tmpcplid) { 1960 global $DB; 1961 1962 debugging('Function feedback_delete_completedtmp() is deprecated because it is no longer used', 1963 DEBUG_DEVELOPER); 1964 1965 $DB->delete_records('feedback_valuetmp', array('completed'=>$tmpcplid)); 1966 $DB->delete_records('feedback_completedtmp', array('id'=>$tmpcplid)); 1967 } 1968 1969 //////////////////////////////////////////////// 1970 //////////////////////////////////////////////// 1971 //////////////////////////////////////////////// 1972 //functions to handle the pagebreaks 1973 //////////////////////////////////////////////// 1974 1975 /** 1976 * this creates a pagebreak. 1977 * a pagebreak is a special kind of item 1978 * 1979 * @global object 1980 * @param int $feedbackid 1981 * @return mixed false if there already is a pagebreak on last position or the id of the pagebreak-item 1982 */ 1983 function feedback_create_pagebreak($feedbackid) { 1984 global $DB; 1985 1986 //check if there already is a pagebreak on the last position 1987 $lastposition = $DB->count_records('feedback_item', array('feedback'=>$feedbackid)); 1988 if ($lastposition == feedback_get_last_break_position($feedbackid)) { 1989 return false; 1990 } 1991 1992 $item = new stdClass(); 1993 $item->feedback = $feedbackid; 1994 1995 $item->template=0; 1996 1997 $item->name = ''; 1998 1999 $item->presentation = ''; 2000 $item->hasvalue = 0; 2001 2002 $item->typ = 'pagebreak'; 2003 $item->position = $lastposition + 1; 2004 2005 $item->required=0; 2006 2007 return $DB->insert_record('feedback_item', $item); 2008 } 2009 2010 /** 2011 * get all positions of pagebreaks in the given feedback 2012 * 2013 * @global object 2014 * @param int $feedbackid 2015 * @return array all ordered pagebreak positions 2016 */ 2017 function feedback_get_all_break_positions($feedbackid) { 2018 global $DB; 2019 2020 $params = array('typ'=>'pagebreak', 'feedback'=>$feedbackid); 2021 $allbreaks = $DB->get_records_menu('feedback_item', $params, 'position', 'id, position'); 2022 if (!$allbreaks) { 2023 return false; 2024 } 2025 return array_values($allbreaks); 2026 } 2027 2028 /** 2029 * get the position of the last pagebreak 2030 * 2031 * @param int $feedbackid 2032 * @return int the position of the last pagebreak 2033 */ 2034 function feedback_get_last_break_position($feedbackid) { 2035 if (!$allbreaks = feedback_get_all_break_positions($feedbackid)) { 2036 return false; 2037 } 2038 return $allbreaks[count($allbreaks) - 1]; 2039 } 2040 2041 /** 2042 * this returns the position where the user can continue the completing. 2043 * 2044 * @deprecated since Moodle 3.1 2045 * @global object 2046 * @global object 2047 * @global object 2048 * @param int $feedbackid 2049 * @param int $courseid 2050 * @param string $guestid this id will be saved temporary and is unique 2051 * @return int the position to continue 2052 */ 2053 function feedback_get_page_to_continue($feedbackid, $courseid = false, $guestid = false) { 2054 global $CFG, $USER, $DB; 2055 2056 debugging('Function feedback_get_page_to_continue() is deprecated and since it is ' 2057 . 'no longer used in mod_feedback', DEBUG_DEVELOPER); 2058 2059 //is there any break? 2060 2061 if (!$allbreaks = feedback_get_all_break_positions($feedbackid)) { 2062 return false; 2063 } 2064 2065 $params = array(); 2066 if ($courseid) { 2067 $courseselect = "AND fv.course_id = :courseid"; 2068 $params['courseid'] = $courseid; 2069 } else { 2070 $courseselect = ''; 2071 } 2072 2073 if ($guestid) { 2074 $userselect = "AND fc.guestid = :guestid"; 2075 $usergroup = "GROUP BY fc.guestid"; 2076 $params['guestid'] = $guestid; 2077 } else { 2078 $userselect = "AND fc.userid = :userid"; 2079 $usergroup = "GROUP BY fc.userid"; 2080 $params['userid'] = $USER->id; 2081 } 2082 2083 $sql = "SELECT MAX(fi.position) 2084 FROM {feedback_completedtmp} fc, {feedback_valuetmp} fv, {feedback_item} fi 2085 WHERE fc.id = fv.completed 2086 $userselect 2087 AND fc.feedback = :feedbackid 2088 $courseselect 2089 AND fi.id = fv.item 2090 $usergroup"; 2091 $params['feedbackid'] = $feedbackid; 2092 2093 $lastpos = $DB->get_field_sql($sql, $params); 2094 2095 //the index of found pagebreak is the searched pagenumber 2096 foreach ($allbreaks as $pagenr => $br) { 2097 if ($lastpos < $br) { 2098 return $pagenr; 2099 } 2100 } 2101 return count($allbreaks); 2102 } 2103 2104 //////////////////////////////////////////////// 2105 //////////////////////////////////////////////// 2106 //////////////////////////////////////////////// 2107 //functions to handle the values 2108 //////////////////////////////////////////////// 2109 2110 /** 2111 * cleans the userinput while submitting the form. 2112 * 2113 * @deprecated since Moodle 3.1 2114 * @param mixed $value 2115 * @return mixed 2116 */ 2117 function feedback_clean_input_value($item, $value) { 2118 debugging('Function feedback_clean_input_value() is deprecated and does nothing. ' 2119 . 'Items must implement complete_form_element()', DEBUG_DEVELOPER); 2120 } 2121 2122 /** 2123 * this saves the values of an completed. 2124 * if the param $tmp is set true so the values are saved temporary in table feedback_valuetmp. 2125 * if there is already a completed and the userid is set so the values are updated. 2126 * on all other things new value records will be created. 2127 * 2128 * @deprecated since Moodle 3.1 2129 * 2130 * @param int $usrid 2131 * @param boolean $tmp 2132 * @return mixed false on error or the completeid 2133 */ 2134 function feedback_save_values($usrid, $tmp = false) { 2135 global $DB; 2136 2137 debugging('Function feedback_save_values() was deprecated because it did not have '. 2138 'enough arguments, was not suitable for non-temporary table and was taking '. 2139 'data directly from input', DEBUG_DEVELOPER); 2140 2141 $completedid = optional_param('completedid', 0, PARAM_INT); 2142 $tmpstr = $tmp ? 'tmp' : ''; 2143 $time = time(); 2144 $timemodified = mktime(0, 0, 0, date('m', $time), date('d', $time), date('Y', $time)); 2145 2146 if ($usrid == 0) { 2147 return feedback_create_values($usrid, $timemodified, $tmp); 2148 } 2149 $completed = $DB->get_record('feedback_completed'.$tmpstr, array('id'=>$completedid)); 2150 if (!$completed) { 2151 return feedback_create_values($usrid, $timemodified, $tmp); 2152 } else { 2153 $completed->timemodified = $timemodified; 2154 return feedback_update_values($completed, $tmp); 2155 } 2156 } 2157 2158 /** 2159 * this saves the values from anonymous user such as guest on the main-site 2160 * 2161 * @deprecated since Moodle 3.1 2162 * 2163 * @param string $guestid the unique guestidentifier 2164 * @return mixed false on error or the completeid 2165 */ 2166 function feedback_save_guest_values($guestid) { 2167 global $DB; 2168 2169 debugging('Function feedback_save_guest_values() was deprecated because it did not have '. 2170 'enough arguments, was not suitable for non-temporary table and was taking '. 2171 'data directly from input', DEBUG_DEVELOPER); 2172 2173 $completedid = optional_param('completedid', false, PARAM_INT); 2174 2175 $timemodified = time(); 2176 if (!$completed = $DB->get_record('feedback_completedtmp', array('id'=>$completedid))) { 2177 return feedback_create_values(0, $timemodified, true, $guestid); 2178 } else { 2179 $completed->timemodified = $timemodified; 2180 return feedback_update_values($completed, true); 2181 } 2182 } 2183 2184 /** 2185 * get the value from the given item related to the given completed. 2186 * the value can come as temporary or as permanently value. the deciding is done by $tmp 2187 * 2188 * @global object 2189 * @param int $completeid 2190 * @param int $itemid 2191 * @param boolean $tmp 2192 * @return mixed the value, the type depends on plugin-definition 2193 */ 2194 function feedback_get_item_value($completedid, $itemid, $tmp = false) { 2195 global $DB; 2196 2197 $tmpstr = $tmp ? 'tmp' : ''; 2198 $params = array('completed'=>$completedid, 'item'=>$itemid); 2199 return $DB->get_field('feedback_value'.$tmpstr, 'value', $params); 2200 } 2201 2202 /** 2203 * compares the value of the itemid related to the completedid with the dependvalue. 2204 * this is used if a depend item is set. 2205 * the value can come as temporary or as permanently value. the deciding is done by $tmp. 2206 * 2207 * @param int $completedid 2208 * @param stdClass|int $item 2209 * @param mixed $dependvalue 2210 * @param bool $tmp 2211 * @return bool 2212 */ 2213 function feedback_compare_item_value($completedid, $item, $dependvalue, $tmp = false) { 2214 global $DB; 2215 2216 if (is_int($item)) { 2217 $item = $DB->get_record('feedback_item', array('id' => $item)); 2218 } 2219 2220 $dbvalue = feedback_get_item_value($completedid, $item->id, $tmp); 2221 2222 $itemobj = feedback_get_item_class($item->typ); 2223 return $itemobj->compare_value($item, $dbvalue, $dependvalue); //true or false 2224 } 2225 2226 /** 2227 * this function checks the correctness of values. 2228 * the rules for this are implemented in the class of each item. 2229 * it can be the required attribute or the value self e.g. numeric. 2230 * the params first/lastitem are given to determine the visible range between pagebreaks. 2231 * 2232 * @global object 2233 * @param int $firstitem the position of firstitem for checking 2234 * @param int $lastitem the position of lastitem for checking 2235 * @return boolean 2236 */ 2237 function feedback_check_values($firstitem, $lastitem) { 2238 debugging('Function feedback_check_values() is deprecated and does nothing. ' 2239 . 'Items must implement complete_form_element()', DEBUG_DEVELOPER); 2240 return true; 2241 } 2242 2243 /** 2244 * this function create a complete-record and the related value-records. 2245 * depending on the $tmp (true/false) the values are saved temporary or permanently 2246 * 2247 * @deprecated since Moodle 3.1 2248 * 2249 * @param int $userid 2250 * @param int $timemodified 2251 * @param boolean $tmp 2252 * @param string $guestid a unique identifier to save temporary data 2253 * @return mixed false on error or the completedid 2254 */ 2255 function feedback_create_values($usrid, $timemodified, $tmp = false, $guestid = false) { 2256 global $DB; 2257 2258 debugging('Function feedback_create_values() was deprecated because it did not have '. 2259 'enough arguments, was not suitable for non-temporary table and was taking '. 2260 'data directly from input', DEBUG_DEVELOPER); 2261 2262 $tmpstr = $tmp ? 'tmp' : ''; 2263 //first we create a new completed record 2264 $completed = new stdClass(); 2265 $completed->feedback = $feedbackid; 2266 $completed->userid = $usrid; 2267 $completed->guestid = $guestid; 2268 $completed->timemodified = $timemodified; 2269 $completed->anonymous_response = $anonymous_response; 2270 2271 $completedid = $DB->insert_record('feedback_completed'.$tmpstr, $completed); 2272 2273 $completed = $DB->get_record('feedback_completed'.$tmpstr, array('id'=>$completedid)); 2274 2275 //the keys are in the form like abc_xxx 2276 //with explode we make an array with(abc, xxx) and (abc=typ und xxx=itemnr) 2277 2278 //get the items of the feedback 2279 if (!$allitems = $DB->get_records('feedback_item', array('feedback'=>$completed->feedback))) { 2280 return false; 2281 } 2282 foreach ($allitems as $item) { 2283 if (!$item->hasvalue) { 2284 continue; 2285 } 2286 //get the class of item-typ 2287 $itemobj = feedback_get_item_class($item->typ); 2288 2289 $keyname = $item->typ.'_'.$item->id; 2290 2291 if ($item->typ === 'multichoice') { 2292 $itemvalue = optional_param_array($keyname, null, PARAM_INT); 2293 } else { 2294 $itemvalue = optional_param($keyname, null, PARAM_NOTAGS); 2295 } 2296 2297 if (is_null($itemvalue)) { 2298 continue; 2299 } 2300 2301 $value = new stdClass(); 2302 $value->item = $item->id; 2303 $value->completed = $completed->id; 2304 $value->course_id = $courseid; 2305 2306 //the kind of values can be absolutely different 2307 //so we run create_value directly by the item-class 2308 $value->value = $itemobj->create_value($itemvalue); 2309 $DB->insert_record('feedback_value'.$tmpstr, $value); 2310 } 2311 return $completed->id; 2312 } 2313 2314 /** 2315 * this function updates a complete-record and the related value-records. 2316 * depending on the $tmp (true/false) the values are saved temporary or permanently 2317 * 2318 * @global object 2319 * @param object $completed 2320 * @param boolean $tmp 2321 * @return int the completedid 2322 */ 2323 function feedback_update_values($completed, $tmp = false) { 2324 global $DB; 2325 2326 debugging('Function feedback_update_values() was deprecated because it did not have '. 2327 'enough arguments, was not suitable for non-temporary table and was taking '. 2328 'data directly from input', DEBUG_DEVELOPER); 2329 2330 $courseid = optional_param('courseid', false, PARAM_INT); 2331 $tmpstr = $tmp ? 'tmp' : ''; 2332 2333 $DB->update_record('feedback_completed'.$tmpstr, $completed); 2334 //get the values of this completed 2335 $values = $DB->get_records('feedback_value'.$tmpstr, array('completed'=>$completed->id)); 2336 2337 //get the items of the feedback 2338 if (!$allitems = $DB->get_records('feedback_item', array('feedback'=>$completed->feedback))) { 2339 return false; 2340 } 2341 foreach ($allitems as $item) { 2342 if (!$item->hasvalue) { 2343 continue; 2344 } 2345 //get the class of item-typ 2346 $itemobj = feedback_get_item_class($item->typ); 2347 2348 $keyname = $item->typ.'_'.$item->id; 2349 2350 if ($item->typ === 'multichoice') { 2351 $itemvalue = optional_param_array($keyname, null, PARAM_INT); 2352 } else { 2353 $itemvalue = optional_param($keyname, null, PARAM_NOTAGS); 2354 } 2355 2356 //is the itemvalue set (could be a subset of items because pagebreak)? 2357 if (is_null($itemvalue)) { 2358 continue; 2359 } 2360 2361 $newvalue = new stdClass(); 2362 $newvalue->item = $item->id; 2363 $newvalue->completed = $completed->id; 2364 $newvalue->course_id = $courseid; 2365 2366 //the kind of values can be absolutely different 2367 //so we run create_value directly by the item-class 2368 $newvalue->value = $itemobj->create_value($itemvalue); 2369 2370 //check, if we have to create or update the value 2371 $exist = false; 2372 foreach ($values as $value) { 2373 if ($value->item == $newvalue->item) { 2374 $newvalue->id = $value->id; 2375 $exist = true; 2376 break; 2377 } 2378 } 2379 if ($exist) { 2380 $DB->update_record('feedback_value'.$tmpstr, $newvalue); 2381 } else { 2382 $DB->insert_record('feedback_value'.$tmpstr, $newvalue); 2383 } 2384 } 2385 2386 return $completed->id; 2387 } 2388 2389 /** 2390 * get the values of an item depending on the given groupid. 2391 * if the feedback is anonymous so the values are shuffled 2392 * 2393 * @global object 2394 * @global object 2395 * @param object $item 2396 * @param int $groupid 2397 * @param int $courseid 2398 * @param bool $ignore_empty if this is set true so empty values are not delivered 2399 * @return array the value-records 2400 */ 2401 function feedback_get_group_values($item, 2402 $groupid = false, 2403 $courseid = false, 2404 $ignore_empty = false) { 2405 2406 global $CFG, $DB; 2407 2408 //if the groupid is given? 2409 if (intval($groupid) > 0) { 2410 $params = array(); 2411 if ($ignore_empty) { 2412 $value = $DB->sql_compare_text('fbv.value'); 2413 $ignore_empty_select = "AND $value != :emptyvalue AND $value != :zerovalue"; 2414 $params += array('emptyvalue' => '', 'zerovalue' => '0'); 2415 } else { 2416 $ignore_empty_select = ""; 2417 } 2418 2419 $query = 'SELECT fbv . * 2420 FROM {feedback_value} fbv, {feedback_completed} fbc, {groups_members} gm 2421 WHERE fbv.item = :itemid 2422 AND fbv.completed = fbc.id 2423 AND fbc.userid = gm.userid 2424 '.$ignore_empty_select.' 2425 AND gm.groupid = :groupid 2426 ORDER BY fbc.timemodified'; 2427 $params += array('itemid' => $item->id, 'groupid' => $groupid); 2428 $values = $DB->get_records_sql($query, $params); 2429 2430 } else { 2431 $params = array(); 2432 if ($ignore_empty) { 2433 $value = $DB->sql_compare_text('value'); 2434 $ignore_empty_select = "AND $value != :emptyvalue AND $value != :zerovalue"; 2435 $params += array('emptyvalue' => '', 'zerovalue' => '0'); 2436 } else { 2437 $ignore_empty_select = ""; 2438 } 2439 2440 if ($courseid) { 2441 $select = "item = :itemid AND course_id = :courseid ".$ignore_empty_select; 2442 $params += array('itemid' => $item->id, 'courseid' => $courseid); 2443 $values = $DB->get_records_select('feedback_value', $select, $params); 2444 } else { 2445 $select = "item = :itemid ".$ignore_empty_select; 2446 $params += array('itemid' => $item->id); 2447 $values = $DB->get_records_select('feedback_value', $select, $params); 2448 } 2449 } 2450 $params = array('id'=>$item->feedback); 2451 if ($DB->get_field('feedback', 'anonymous', $params) == FEEDBACK_ANONYMOUS_YES) { 2452 if (is_array($values)) { 2453 shuffle($values); 2454 } 2455 } 2456 return $values; 2457 } 2458 2459 /** 2460 * check for multiple_submit = false. 2461 * if the feedback is global so the courseid must be given 2462 * 2463 * @global object 2464 * @global object 2465 * @param int $feedbackid 2466 * @param int $courseid 2467 * @return boolean true if the feedback already is submitted otherwise false 2468 */ 2469 function feedback_is_already_submitted($feedbackid, $courseid = false) { 2470 global $USER, $DB; 2471 2472 if (!isloggedin() || isguestuser()) { 2473 return false; 2474 } 2475 2476 $params = array('userid' => $USER->id, 'feedback' => $feedbackid); 2477 if ($courseid) { 2478 $params['courseid'] = $courseid; 2479 } 2480 return $DB->record_exists('feedback_completed', $params); 2481 } 2482 2483 /** 2484 * if the completion of a feedback will be continued eg. 2485 * by pagebreak or by multiple submit so the complete must be found. 2486 * if the param $tmp is set true so all things are related to temporary completeds 2487 * 2488 * @deprecated since Moodle 3.1 2489 * @param int $feedbackid 2490 * @param boolean $tmp 2491 * @param int $courseid 2492 * @param string $guestid 2493 * @return int the id of the found completed 2494 */ 2495 function feedback_get_current_completed($feedbackid, 2496 $tmp = false, 2497 $courseid = false, 2498 $guestid = false) { 2499 2500 debugging('Function feedback_get_current_completed() is deprecated. Please use either '. 2501 'feedback_get_current_completed_tmp() or feedback_get_last_completed()', 2502 DEBUG_DEVELOPER); 2503 2504 global $USER, $CFG, $DB; 2505 2506 $tmpstr = $tmp ? 'tmp' : ''; 2507 2508 if (!$courseid) { 2509 if ($guestid) { 2510 $params = array('feedback'=>$feedbackid, 'guestid'=>$guestid); 2511 return $DB->get_record('feedback_completed'.$tmpstr, $params); 2512 } else { 2513 $params = array('feedback'=>$feedbackid, 'userid'=>$USER->id); 2514 return $DB->get_record('feedback_completed'.$tmpstr, $params); 2515 } 2516 } 2517 2518 $params = array(); 2519 2520 if ($guestid) { 2521 $userselect = "AND fc.guestid = :guestid"; 2522 $params['guestid'] = $guestid; 2523 } else { 2524 $userselect = "AND fc.userid = :userid"; 2525 $params['userid'] = $USER->id; 2526 } 2527 //if courseid is set the feedback is global. 2528 //there can be more than one completed on one feedback 2529 $sql = "SELECT DISTINCT fc.* 2530 FROM {feedback_value{$tmpstr}} fv, {feedback_completed{$tmpstr}} fc 2531 WHERE fv.course_id = :courseid 2532 AND fv.completed = fc.id 2533 $userselect 2534 AND fc.feedback = :feedbackid"; 2535 $params['courseid'] = intval($courseid); 2536 $params['feedbackid'] = $feedbackid; 2537 2538 if (!$sqlresult = $DB->get_records_sql($sql, $params)) { 2539 return false; 2540 } 2541 foreach ($sqlresult as $r) { 2542 return $DB->get_record('feedback_completed'.$tmpstr, array('id'=>$r->id)); 2543 } 2544 } 2545 2546 /** 2547 * get the completeds depending on the given groupid. 2548 * 2549 * @global object 2550 * @global object 2551 * @param object $feedback 2552 * @param int $groupid 2553 * @param int $courseid 2554 * @return mixed array of found completeds otherwise false 2555 */ 2556 function feedback_get_completeds_group($feedback, $groupid = false, $courseid = false) { 2557 global $CFG, $DB; 2558 2559 if (intval($groupid) > 0) { 2560 $query = "SELECT fbc.* 2561 FROM {feedback_completed} fbc, {groups_members} gm 2562 WHERE fbc.feedback = ? 2563 AND gm.groupid = ? 2564 AND fbc.userid = gm.userid"; 2565 if ($values = $DB->get_records_sql($query, array($feedback->id, $groupid))) { 2566 return $values; 2567 } else { 2568 return false; 2569 } 2570 } else { 2571 if ($courseid) { 2572 $query = "SELECT DISTINCT fbc.* 2573 FROM {feedback_completed} fbc, {feedback_value} fbv 2574 WHERE fbc.id = fbv.completed 2575 AND fbc.feedback = ? 2576 AND fbv.course_id = ? 2577 ORDER BY random_response"; 2578 if ($values = $DB->get_records_sql($query, array($feedback->id, $courseid))) { 2579 return $values; 2580 } else { 2581 return false; 2582 } 2583 } else { 2584 if ($values = $DB->get_records('feedback_completed', array('feedback'=>$feedback->id))) { 2585 return $values; 2586 } else { 2587 return false; 2588 } 2589 } 2590 } 2591 } 2592 2593 /** 2594 * get the count of completeds depending on the given groupid. 2595 * 2596 * @global object 2597 * @global object 2598 * @param object $feedback 2599 * @param int $groupid 2600 * @param int $courseid 2601 * @return mixed count of completeds or false 2602 */ 2603 function feedback_get_completeds_group_count($feedback, $groupid = false, $courseid = false) { 2604 global $CFG, $DB; 2605 2606 if ($courseid > 0 AND !$groupid <= 0) { 2607 $sql = "SELECT id, COUNT(item) AS ci 2608 FROM {feedback_value} 2609 WHERE course_id = ? 2610 GROUP BY item ORDER BY ci DESC"; 2611 if ($foundrecs = $DB->get_records_sql($sql, array($courseid))) { 2612 $foundrecs = array_values($foundrecs); 2613 return $foundrecs[0]->ci; 2614 } 2615 return false; 2616 } 2617 if ($values = feedback_get_completeds_group($feedback, $groupid)) { 2618 return count($values); 2619 } else { 2620 return false; 2621 } 2622 } 2623 2624 /** 2625 * deletes all completed-recordsets from a feedback. 2626 * all related data such as values also will be deleted 2627 * 2628 * @param stdClass|int $feedback 2629 * @param stdClass|cm_info $cm 2630 * @param stdClass $course 2631 * @return void 2632 */ 2633 function feedback_delete_all_completeds($feedback, $cm = null, $course = null) { 2634 global $DB; 2635 2636 if (is_int($feedback)) { 2637 $feedback = $DB->get_record('feedback', array('id' => $feedback)); 2638 } 2639 2640 if (!$completeds = $DB->get_records('feedback_completed', array('feedback' => $feedback->id))) { 2641 return; 2642 } 2643 2644 if (!$course && !($course = $DB->get_record('course', array('id' => $feedback->course)))) { 2645 return false; 2646 } 2647 2648 if (!$cm && !($cm = get_coursemodule_from_instance('feedback', $feedback->id))) { 2649 return false; 2650 } 2651 2652 foreach ($completeds as $completed) { 2653 feedback_delete_completed($completed, $feedback, $cm, $course); 2654 } 2655 } 2656 2657 /** 2658 * deletes a completed given by completedid. 2659 * all related data such values or tracking data also will be deleted 2660 * 2661 * @param int|stdClass $completed 2662 * @param stdClass $feedback 2663 * @param stdClass|cm_info $cm 2664 * @param stdClass $course 2665 * @return boolean 2666 */ 2667 function feedback_delete_completed($completed, $feedback = null, $cm = null, $course = null) { 2668 global $DB, $CFG; 2669 require_once($CFG->libdir.'/completionlib.php'); 2670 2671 if (!isset($completed->id)) { 2672 if (!$completed = $DB->get_record('feedback_completed', array('id' => $completed))) { 2673 return false; 2674 } 2675 } 2676 2677 if (!$feedback && !($feedback = $DB->get_record('feedback', array('id' => $completed->feedback)))) { 2678 return false; 2679 } 2680 2681 if (!$course && !($course = $DB->get_record('course', array('id' => $feedback->course)))) { 2682 return false; 2683 } 2684 2685 if (!$cm && !($cm = get_coursemodule_from_instance('feedback', $feedback->id))) { 2686 return false; 2687 } 2688 2689 //first we delete all related values 2690 $DB->delete_records('feedback_value', array('completed' => $completed->id)); 2691 2692 // Update completion state 2693 $completion = new completion_info($course); 2694 if ($completion->is_enabled($cm) && $feedback->completionsubmit) { 2695 $completion->update_state($cm, COMPLETION_INCOMPLETE, $completed->userid); 2696 } 2697 // Last we delete the completed-record. 2698 $return = $DB->delete_records('feedback_completed', array('id' => $completed->id)); 2699 2700 // Trigger event for the delete action we performed. 2701 $event = \mod_feedback\event\response_deleted::create_from_record($completed, $cm, $feedback); 2702 $event->trigger(); 2703 2704 return $return; 2705 } 2706 2707 //////////////////////////////////////////////// 2708 //////////////////////////////////////////////// 2709 //////////////////////////////////////////////// 2710 //functions to handle sitecourse mapping 2711 //////////////////////////////////////////////// 2712 2713 /** 2714 * checks if the course and the feedback is in the table feedback_sitecourse_map. 2715 * 2716 * @deprecated since 3.1 2717 * @param int $feedbackid 2718 * @param int $courseid 2719 * @return int the count of records 2720 */ 2721 function feedback_is_course_in_sitecourse_map($feedbackid, $courseid) { 2722 debugging('Function feedback_is_course_in_sitecourse_map() is deprecated because it was not used.', 2723 DEBUG_DEVELOPER); 2724 global $DB; 2725 $params = array('feedbackid'=>$feedbackid, 'courseid'=>$courseid); 2726 return $DB->count_records('feedback_sitecourse_map', $params); 2727 } 2728 2729 /** 2730 * checks if the feedback is in the table feedback_sitecourse_map. 2731 * 2732 * @deprecated since 3.1 2733 * @param int $feedbackid 2734 * @return boolean 2735 */ 2736 function feedback_is_feedback_in_sitecourse_map($feedbackid) { 2737 debugging('Function feedback_is_feedback_in_sitecourse_map() is deprecated because it was not used.', 2738 DEBUG_DEVELOPER); 2739 global $DB; 2740 return $DB->record_exists('feedback_sitecourse_map', array('feedbackid'=>$feedbackid)); 2741 } 2742 2743 /** 2744 * gets the feedbacks from table feedback_sitecourse_map. 2745 * this is used to show the global feedbacks on the feedback block 2746 * all feedbacks with the following criteria will be selected:<br /> 2747 * 2748 * 1) all feedbacks which id are listed together with the courseid in sitecoursemap and<br /> 2749 * 2) all feedbacks which not are listed in sitecoursemap 2750 * 2751 * @global object 2752 * @param int $courseid 2753 * @return array the feedback-records 2754 */ 2755 function feedback_get_feedbacks_from_sitecourse_map($courseid) { 2756 global $DB; 2757 2758 //first get all feedbacks listed in sitecourse_map with named courseid 2759 $sql = "SELECT f.id AS id, 2760 cm.id AS cmid, 2761 f.name AS name, 2762 f.timeopen AS timeopen, 2763 f.timeclose AS timeclose 2764 FROM {feedback} f, {course_modules} cm, {feedback_sitecourse_map} sm, {modules} m 2765 WHERE f.id = cm.instance 2766 AND f.course = '".SITEID."' 2767 AND m.id = cm.module 2768 AND m.name = 'feedback' 2769 AND sm.courseid = ? 2770 AND sm.feedbackid = f.id"; 2771 2772 if (!$feedbacks1 = $DB->get_records_sql($sql, array($courseid))) { 2773 $feedbacks1 = array(); 2774 } 2775 2776 //second get all feedbacks not listed in sitecourse_map 2777 $feedbacks2 = array(); 2778 $sql = "SELECT f.id AS id, 2779 cm.id AS cmid, 2780 f.name AS name, 2781 f.timeopen AS timeopen, 2782 f.timeclose AS timeclose 2783 FROM {feedback} f, {course_modules} cm, {modules} m 2784 WHERE f.id = cm.instance 2785 AND f.course = '".SITEID."' 2786 AND m.id = cm.module 2787 AND m.name = 'feedback'"; 2788 if (!$allfeedbacks = $DB->get_records_sql($sql)) { 2789 $allfeedbacks = array(); 2790 } 2791 foreach ($allfeedbacks as $a) { 2792 if (!$DB->record_exists('feedback_sitecourse_map', array('feedbackid'=>$a->id))) { 2793 $feedbacks2[] = $a; 2794 } 2795 } 2796 2797 $feedbacks = array_merge($feedbacks1, $feedbacks2); 2798 $modinfo = get_fast_modinfo(SITEID); 2799 return array_filter($feedbacks, function($f) use ($modinfo) { 2800 return ($cm = $modinfo->get_cm($f->cmid)) && $cm->uservisible; 2801 }); 2802 2803 } 2804 2805 /** 2806 * Gets the courses from table feedback_sitecourse_map 2807 * 2808 * @param int $feedbackid 2809 * @return array the course-records 2810 */ 2811 function feedback_get_courses_from_sitecourse_map($feedbackid) { 2812 global $DB; 2813 2814 $sql = "SELECT c.id, c.fullname, c.shortname 2815 FROM {feedback_sitecourse_map} f, {course} c 2816 WHERE c.id = f.courseid 2817 AND f.feedbackid = ? 2818 ORDER BY c.fullname"; 2819 2820 return $DB->get_records_sql($sql, array($feedbackid)); 2821 2822 } 2823 2824 /** 2825 * Updates the course mapping for the feedback 2826 * 2827 * @param stdClass $feedback 2828 * @param array $courses array of course ids 2829 */ 2830 function feedback_update_sitecourse_map($feedback, $courses) { 2831 global $DB; 2832 if (empty($courses)) { 2833 $courses = array(); 2834 } 2835 $currentmapping = $DB->get_fieldset_select('feedback_sitecourse_map', 'courseid', 'feedbackid=?', array($feedback->id)); 2836 foreach (array_diff($courses, $currentmapping) as $courseid) { 2837 $DB->insert_record('feedback_sitecourse_map', array('feedbackid' => $feedback->id, 'courseid' => $courseid)); 2838 } 2839 foreach (array_diff($currentmapping, $courses) as $courseid) { 2840 $DB->delete_records('feedback_sitecourse_map', array('feedbackid' => $feedback->id, 'courseid' => $courseid)); 2841 } 2842 // TODO MDL-53574 add events. 2843 } 2844 2845 /** 2846 * removes non existing courses or feedbacks from sitecourse_map. 2847 * it shouldn't be called all too often 2848 * a good place for it could be the mapcourse.php or unmapcourse.php 2849 * 2850 * @deprecated since 3.1 2851 * @global object 2852 * @return void 2853 */ 2854 function feedback_clean_up_sitecourse_map() { 2855 global $DB; 2856 debugging('Function feedback_clean_up_sitecourse_map() is deprecated because it was not used.', 2857 DEBUG_DEVELOPER); 2858 2859 $maps = $DB->get_records('feedback_sitecourse_map'); 2860 foreach ($maps as $map) { 2861 if (!$DB->get_record('course', array('id'=>$map->courseid))) { 2862 $params = array('courseid'=>$map->courseid, 'feedbackid'=>$map->feedbackid); 2863 $DB->delete_records('feedback_sitecourse_map', $params); 2864 continue; 2865 } 2866 if (!$DB->get_record('feedback', array('id'=>$map->feedbackid))) { 2867 $params = array('courseid'=>$map->courseid, 'feedbackid'=>$map->feedbackid); 2868 $DB->delete_records('feedback_sitecourse_map', $params); 2869 continue; 2870 } 2871 2872 } 2873 } 2874 2875 //////////////////////////////////////////////// 2876 //////////////////////////////////////////////// 2877 //////////////////////////////////////////////// 2878 //not relatable functions 2879 //////////////////////////////////////////////// 2880 2881 /** 2882 * prints the option items of a selection-input item (dropdownlist). 2883 * @deprecated since 3.1 2884 * @param int $startval the first value of the list 2885 * @param int $endval the last value of the list 2886 * @param int $selectval which item should be selected 2887 * @param int $interval the stepsize from the first to the last value 2888 * @return void 2889 */ 2890 function feedback_print_numeric_option_list($startval, $endval, $selectval = '', $interval = 1) { 2891 debugging('Function feedback_print_numeric_option_list() is deprecated because it was not used.', 2892 DEBUG_DEVELOPER); 2893 for ($i = $startval; $i <= $endval; $i += $interval) { 2894 if ($selectval == ($i)) { 2895 $selected = 'selected="selected"'; 2896 } else { 2897 $selected = ''; 2898 } 2899 echo '<option '.$selected.'>'.$i.'</option>'; 2900 } 2901 } 2902 2903 /** 2904 * sends an email to the teachers of the course where the given feedback is placed. 2905 * 2906 * @global object 2907 * @global object 2908 * @uses FEEDBACK_ANONYMOUS_NO 2909 * @uses FORMAT_PLAIN 2910 * @param object $cm the coursemodule-record 2911 * @param object $feedback 2912 * @param object $course 2913 * @param stdClass|int $user 2914 * @return void 2915 */ 2916 function feedback_send_email($cm, $feedback, $course, $user) { 2917 global $CFG, $DB; 2918 2919 if ($feedback->email_notification == 0) { // No need to do anything 2920 return; 2921 } 2922 2923 if (is_int($user)) { 2924 $user = $DB->get_record('user', array('id' => $user)); 2925 } 2926 2927 if (isset($cm->groupmode) && empty($course->groupmodeforce)) { 2928 $groupmode = $cm->groupmode; 2929 } else { 2930 $groupmode = $course->groupmode; 2931 } 2932 2933 if ($groupmode == SEPARATEGROUPS) { 2934 $groups = $DB->get_records_sql_menu("SELECT g.name, g.id 2935 FROM {groups} g, {groups_members} m 2936 WHERE g.courseid = ? 2937 AND g.id = m.groupid 2938 AND m.userid = ? 2939 ORDER BY name ASC", array($course->id, $user->id)); 2940 $groups = array_values($groups); 2941 2942 $teachers = feedback_get_receivemail_users($cm->id, $groups); 2943 } else { 2944 $teachers = feedback_get_receivemail_users($cm->id); 2945 } 2946 2947 if ($teachers) { 2948 2949 $strfeedbacks = get_string('modulenameplural', 'feedback'); 2950 $strfeedback = get_string('modulename', 'feedback'); 2951 2952 if ($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) { 2953 $printusername = fullname($user); 2954 } else { 2955 $printusername = get_string('anonymous_user', 'feedback'); 2956 } 2957 2958 foreach ($teachers as $teacher) { 2959 $info = new stdClass(); 2960 $info->username = $printusername; 2961 $info->feedback = format_string($feedback->name, true); 2962 $info->url = $CFG->wwwroot.'/mod/feedback/show_entries.php?'. 2963 'id='.$cm->id.'&'. 2964 'userid=' . $user->id; 2965 2966 $a = array('username' => $info->username, 'feedbackname' => $feedback->name); 2967 2968 $postsubject = get_string('feedbackcompleted', 'feedback', $a); 2969 $posttext = feedback_send_email_text($info, $course); 2970 2971 if ($teacher->mailformat == 1) { 2972 $posthtml = feedback_send_email_html($info, $course, $cm); 2973 } else { 2974 $posthtml = ''; 2975 } 2976 2977 if ($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) { 2978 $eventdata = new stdClass(); 2979 $eventdata->name = 'submission'; 2980 $eventdata->component = 'mod_feedback'; 2981 $eventdata->userfrom = $user; 2982 $eventdata->userto = $teacher; 2983 $eventdata->subject = $postsubject; 2984 $eventdata->fullmessage = $posttext; 2985 $eventdata->fullmessageformat = FORMAT_PLAIN; 2986 $eventdata->fullmessagehtml = $posthtml; 2987 $eventdata->smallmessage = ''; 2988 message_send($eventdata); 2989 } else { 2990 $eventdata = new stdClass(); 2991 $eventdata->name = 'submission'; 2992 $eventdata->component = 'mod_feedback'; 2993 $eventdata->userfrom = $teacher; 2994 $eventdata->userto = $teacher; 2995 $eventdata->subject = $postsubject; 2996 $eventdata->fullmessage = $posttext; 2997 $eventdata->fullmessageformat = FORMAT_PLAIN; 2998 $eventdata->fullmessagehtml = $posthtml; 2999 $eventdata->smallmessage = ''; 3000 message_send($eventdata); 3001 } 3002 } 3003 } 3004 } 3005 3006 /** 3007 * sends an email to the teachers of the course where the given feedback is placed. 3008 * 3009 * @global object 3010 * @uses FORMAT_PLAIN 3011 * @param object $cm the coursemodule-record 3012 * @param object $feedback 3013 * @param object $course 3014 * @return void 3015 */ 3016 function feedback_send_email_anonym($cm, $feedback, $course) { 3017 global $CFG; 3018 3019 if ($feedback->email_notification == 0) { // No need to do anything 3020 return; 3021 } 3022 3023 $teachers = feedback_get_receivemail_users($cm->id); 3024 3025 if ($teachers) { 3026 3027 $strfeedbacks = get_string('modulenameplural', 'feedback'); 3028 $strfeedback = get_string('modulename', 'feedback'); 3029 $printusername = get_string('anonymous_user', 'feedback'); 3030 3031 foreach ($teachers as $teacher) { 3032 $info = new stdClass(); 3033 $info->username = $printusername; 3034 $info->feedback = format_string($feedback->name, true); 3035 $info->url = $CFG->wwwroot.'/mod/feedback/show_entries.php?id=' . $cm->id; 3036 3037 $a = array('username' => $info->username, 'feedbackname' => $feedback->name); 3038 3039 $postsubject = get_string('feedbackcompleted', 'feedback', $a); 3040 $posttext = feedback_send_email_text($info, $course); 3041 3042 if ($teacher->mailformat == 1) { 3043 $posthtml = feedback_send_email_html($info, $course, $cm); 3044 } else { 3045 $posthtml = ''; 3046 } 3047 3048 $eventdata = new stdClass(); 3049 $eventdata->name = 'submission'; 3050 $eventdata->component = 'mod_feedback'; 3051 $eventdata->userfrom = $teacher; 3052 $eventdata->userto = $teacher; 3053 $eventdata->subject = $postsubject; 3054 $eventdata->fullmessage = $posttext; 3055 $eventdata->fullmessageformat = FORMAT_PLAIN; 3056 $eventdata->fullmessagehtml = $posthtml; 3057 $eventdata->smallmessage = ''; 3058 message_send($eventdata); 3059 } 3060 } 3061 } 3062 3063 /** 3064 * send the text-part of the email 3065 * 3066 * @param object $info includes some infos about the feedback you want to send 3067 * @param object $course 3068 * @return string the text you want to post 3069 */ 3070 function feedback_send_email_text($info, $course) { 3071 $coursecontext = context_course::instance($course->id); 3072 $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext)); 3073 $posttext = $courseshortname.' -> '.get_string('modulenameplural', 'feedback').' -> '. 3074 $info->feedback."\n"; 3075 $posttext .= '---------------------------------------------------------------------'."\n"; 3076 $posttext .= get_string("emailteachermail", "feedback", $info)."\n"; 3077 $posttext .= '---------------------------------------------------------------------'."\n"; 3078 return $posttext; 3079 } 3080 3081 3082 /** 3083 * send the html-part of the email 3084 * 3085 * @global object 3086 * @param object $info includes some infos about the feedback you want to send 3087 * @param object $course 3088 * @return string the text you want to post 3089 */ 3090 function feedback_send_email_html($info, $course, $cm) { 3091 global $CFG; 3092 $coursecontext = context_course::instance($course->id); 3093 $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext)); 3094 $course_url = $CFG->wwwroot.'/course/view.php?id='.$course->id; 3095 $feedback_all_url = $CFG->wwwroot.'/mod/feedback/index.php?id='.$course->id; 3096 $feedback_url = $CFG->wwwroot.'/mod/feedback/view.php?id='.$cm->id; 3097 3098 $posthtml = '<p><font face="sans-serif">'. 3099 '<a href="'.$course_url.'">'.$courseshortname.'</a> ->'. 3100 '<a href="'.$feedback_all_url.'">'.get_string('modulenameplural', 'feedback').'</a> ->'. 3101 '<a href="'.$feedback_url.'">'.$info->feedback.'</a></font></p>'; 3102 $posthtml .= '<hr /><font face="sans-serif">'; 3103 $posthtml .= '<p>'.get_string('emailteachermailhtml', 'feedback', $info).'</p>'; 3104 $posthtml .= '</font><hr />'; 3105 return $posthtml; 3106 } 3107 3108 /** 3109 * @param string $url 3110 * @return string 3111 */ 3112 function feedback_encode_target_url($url) { 3113 if (strpos($url, '?')) { 3114 list($part1, $part2) = explode('?', $url, 2); //maximal 2 parts 3115 return $part1 . '?' . htmlentities($part2); 3116 } else { 3117 return $url; 3118 } 3119 } 3120 3121 /** 3122 * Adds module specific settings to the settings block 3123 * 3124 * @param settings_navigation $settings The settings navigation object 3125 * @param navigation_node $feedbacknode The node to add module settings to 3126 */ 3127 function feedback_extend_settings_navigation(settings_navigation $settings, 3128 navigation_node $feedbacknode) { 3129 3130 global $PAGE; 3131 3132 if (!$context = context_module::instance($PAGE->cm->id, IGNORE_MISSING)) { 3133 print_error('badcontext'); 3134 } 3135 3136 if (has_capability('mod/feedback:edititems', $context)) { 3137 $questionnode = $feedbacknode->add(get_string('questions', 'feedback')); 3138 3139 $questionnode->add(get_string('edit_items', 'feedback'), 3140 new moodle_url('/mod/feedback/edit.php', 3141 array('id' => $PAGE->cm->id, 3142 'do_show' => 'edit'))); 3143 3144 $questionnode->add(get_string('export_questions', 'feedback'), 3145 new moodle_url('/mod/feedback/export.php', 3146 array('id' => $PAGE->cm->id, 3147 'action' => 'exportfile'))); 3148 3149 $questionnode->add(get_string('import_questions', 'feedback'), 3150 new moodle_url('/mod/feedback/import.php', 3151 array('id' => $PAGE->cm->id))); 3152 3153 $questionnode->add(get_string('templates', 'feedback'), 3154 new moodle_url('/mod/feedback/edit.php', 3155 array('id' => $PAGE->cm->id, 3156 'do_show' => 'templates'))); 3157 } 3158 3159 if (has_capability('mod/feedback:mapcourse', $context) && $PAGE->course->id == SITEID) { 3160 $feedbacknode->add(get_string('mappedcourses', 'feedback'), 3161 new moodle_url('/mod/feedback/mapcourse.php', 3162 array('id' => $PAGE->cm->id))); 3163 } 3164 3165 if (has_capability('mod/feedback:viewreports', $context)) { 3166 $feedback = $PAGE->activityrecord; 3167 if ($feedback->course == SITEID) { 3168 $feedbacknode->add(get_string('analysis', 'feedback'), 3169 new moodle_url('/mod/feedback/analysis_course.php', 3170 array('id' => $PAGE->cm->id))); 3171 } else { 3172 $feedbacknode->add(get_string('analysis', 'feedback'), 3173 new moodle_url('/mod/feedback/analysis.php', 3174 array('id' => $PAGE->cm->id))); 3175 } 3176 3177 $feedbacknode->add(get_string('show_entries', 'feedback'), 3178 new moodle_url('/mod/feedback/show_entries.php', 3179 array('id' => $PAGE->cm->id))); 3180 3181 if ($feedback->anonymous == FEEDBACK_ANONYMOUS_NO AND $feedback->course != SITEID) { 3182 $feedbacknode->add(get_string('show_nonrespondents', 'feedback'), 3183 new moodle_url('/mod/feedback/show_nonrespondents.php', 3184 array('id' => $PAGE->cm->id))); 3185 } 3186 } 3187 } 3188 3189 function feedback_init_feedback_session() { 3190 //initialize the feedback-Session - not nice at all!! 3191 global $SESSION; 3192 if (!empty($SESSION)) { 3193 if (!isset($SESSION->feedback) OR !is_object($SESSION->feedback)) { 3194 $SESSION->feedback = new stdClass(); 3195 } 3196 } 3197 } 3198 3199 /** 3200 * Return a list of page types 3201 * @param string $pagetype current page type 3202 * @param stdClass $parentcontext Block's parent context 3203 * @param stdClass $currentcontext Current context of block 3204 */ 3205 function feedback_page_type_list($pagetype, $parentcontext, $currentcontext) { 3206 $module_pagetype = array('mod-feedback-*'=>get_string('page-mod-feedback-x', 'feedback')); 3207 return $module_pagetype; 3208 } 3209 3210 /** 3211 * Move save the items of the given $feedback in the order of $itemlist. 3212 * @param string $itemlist a comma separated list with item ids 3213 * @param stdClass $feedback 3214 * @return bool true if success 3215 */ 3216 function feedback_ajax_saveitemorder($itemlist, $feedback) { 3217 global $DB; 3218 3219 $result = true; 3220 $position = 0; 3221 foreach ($itemlist as $itemid) { 3222 $position++; 3223 $result = $result && $DB->set_field('feedback_item', 3224 'position', 3225 $position, 3226 array('id'=>$itemid, 'feedback'=>$feedback->id)); 3227 } 3228 return $result; 3229 } 3230 3231 /** 3232 * Checks if current user is able to view feedback on this course. 3233 * 3234 * @param stdClass $feedback 3235 * @param context_module $context 3236 * @param int $courseid 3237 * @return bool 3238 */ 3239 function feedback_can_view_analysis($feedback, $context, $courseid = false) { 3240 if (has_capability('mod/feedback:viewreports', $context)) { 3241 return true; 3242 } 3243 3244 if (intval($feedback->publish_stats) != 1 || 3245 !has_capability('mod/feedback:viewanalysepage', $context)) { 3246 return false; 3247 } 3248 3249 if (!isloggedin() || isguestuser()) { 3250 // There is no tracking for the guests, assume that they can view analysis if condition above is satisfied. 3251 return $feedback->course == SITEID; 3252 } 3253 3254 return feedback_is_already_submitted($feedback->id, $courseid); 3255 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |