]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14493 First checkin of Feedback module into HEAD.
authormoodler <moodler>
Wed, 23 Apr 2008 09:33:54 +0000 (09:33 +0000)
committermoodler <moodler>
Wed, 23 Apr 2008 09:33:54 +0000 (09:33 +0000)
I made a number of small tidy-ups to the contrib version before adding this here:

  - fixed some language string names
  - renamed a capability from deletecompleteds to deletesubmissions (can we use "submissions" everywhere?)
  - got rid of language packs (moved english to correct location)
  - deleted 'pics' type (it needs to be rewritten to use user files in moodledata)
  - moved changelog into README.txt
  - moved captcha font out of subdir
  - bumped version to today

Thanks very much to Andreas Grabs for all your work on this module so far, and congratulations!   :-)

67 files changed:
lang/en_utf8/feedback.php [new file with mode: 0644]
mod/feedback/README.txt [new file with mode: 0644]
mod/feedback/TODO.txt [new file with mode: 0644]
mod/feedback/analysis.php [new file with mode: 0644]
mod/feedback/analysis_course.php [new file with mode: 0644]
mod/feedback/analysis_to_excel.php [new file with mode: 0644]
mod/feedback/backuplib.php [new file with mode: 0644]
mod/feedback/choose_group_form.php [new file with mode: 0644]
mod/feedback/complete.php [new file with mode: 0644]
mod/feedback/complete_guest.php [new file with mode: 0644]
mod/feedback/db/access.php [new file with mode: 0644]
mod/feedback/db/install.xml [new file with mode: 0644]
mod/feedback/db/upgrade.php [new file with mode: 0644]
mod/feedback/delete_completed.php [new file with mode: 0644]
mod/feedback/delete_completed_form.php [new file with mode: 0644]
mod/feedback/delete_item.php [new file with mode: 0644]
mod/feedback/delete_item_form.php [new file with mode: 0644]
mod/feedback/delete_template.php [new file with mode: 0644]
mod/feedback/delete_template_form.php [new file with mode: 0644]
mod/feedback/easy_excel.php [new file with mode: 0644]
mod/feedback/edit.php [new file with mode: 0644]
mod/feedback/edit_form.php [new file with mode: 0644]
mod/feedback/edit_item.php [new file with mode: 0644]
mod/feedback/export.php [new file with mode: 0644]
mod/feedback/icon.gif [new file with mode: 0644]
mod/feedback/import.php [new file with mode: 0644]
mod/feedback/index.php [new file with mode: 0644]
mod/feedback/item/captcha/default.ttf [new file with mode: 0644]
mod/feedback/item/captcha/lib.php [new file with mode: 0644]
mod/feedback/item/captcha/print_captcha.php [new file with mode: 0644]
mod/feedback/item/check/lib.php [new file with mode: 0644]
mod/feedback/item/dropdown/lib.php [new file with mode: 0644]
mod/feedback/item/dropdownrated/lib.php [new file with mode: 0644]
mod/feedback/item/feedback_item_class.php [new file with mode: 0644]
mod/feedback/item/label/lib.php [new file with mode: 0644]
mod/feedback/item/numeric/lib.php [new file with mode: 0644]
mod/feedback/item/radio/lib.php [new file with mode: 0644]
mod/feedback/item/radiorated/lib.php [new file with mode: 0644]
mod/feedback/item/textarea/lib.php [new file with mode: 0644]
mod/feedback/item/textfield/lib.php [new file with mode: 0644]
mod/feedback/lib.php [new file with mode: 0644]
mod/feedback/mapcourse.php [new file with mode: 0644]
mod/feedback/mod.html [new file with mode: 0644]
mod/feedback/mod_form.php [new file with mode: 0644]
mod/feedback/pics/0.gif [new file with mode: 0644]
mod/feedback/pics/1.gif [new file with mode: 0644]
mod/feedback/pics/2.gif [new file with mode: 0644]
mod/feedback/pics/3.gif [new file with mode: 0644]
mod/feedback/pics/4.gif [new file with mode: 0644]
mod/feedback/pics/5.gif [new file with mode: 0644]
mod/feedback/pics/6.gif [new file with mode: 0644]
mod/feedback/pics/7.gif [new file with mode: 0644]
mod/feedback/pics/8.gif [new file with mode: 0644]
mod/feedback/pics/9.gif [new file with mode: 0644]
mod/feedback/pics/notrequired.gif [new file with mode: 0644]
mod/feedback/pics/required.gif [new file with mode: 0644]
mod/feedback/print.php [new file with mode: 0644]
mod/feedback/restorelib.php [new file with mode: 0644]
mod/feedback/show_entries.php [new file with mode: 0644]
mod/feedback/show_entries_anonym.php [new file with mode: 0644]
mod/feedback/styles.php [new file with mode: 0644]
mod/feedback/tabs.php [new file with mode: 0644]
mod/feedback/unmapcourse.php [new file with mode: 0644]
mod/feedback/use_templ.php [new file with mode: 0644]
mod/feedback/use_templ_form.php [new file with mode: 0644]
mod/feedback/version.php [new file with mode: 0644]
mod/feedback/view.php [new file with mode: 0644]

diff --git a/lang/en_utf8/feedback.php b/lang/en_utf8/feedback.php
new file mode 100644 (file)
index 0000000..7e56e7f
--- /dev/null
@@ -0,0 +1,177 @@
+<?PHP //   $Id$
+$string['add_item'] = 'Add question to activity';
+$string['add_items'] = 'Add question to activity';
+$string['add_pagebreak'] = 'Add a pagebreak';
+$string['adjustment'] = 'Adjustment';
+$string['after_submit'] = 'After submitting';
+$string['oldvalueswillbedeleted'] = 'The current questions and all your user\'s responses will be deleted';
+$string['oldvaluespreserved'] = 'All old questions and the assigned values will be preserved';
+$string['relateditemsdeleted'] = 'All your user\'s responses for this question will also be deleted'; 
+$string['analysis'] = 'Analysis';
+$string['anonymous'] = 'Anonymous';
+$string['anonymous_edit'] = 'Record user names';
+$string['anonymous_entries'] = 'Anonymous entries';
+$string['anonymous_user'] = 'Anonymous user';
+$string['append_new_items'] = 'Append new items';
+$string['confirmdeleteentry'] = 'Are you sure you want to delete this entry?';
+$string['confirmdeleteitem'] = 'Are you sure you want to delete this element?';
+$string['confirmdeletetemplate'] = 'Are you sure you want to delete this template?';
+$string['confirmusetemplate'] = 'Are you sure you want to use this template?';
+$string['average'] = 'Average';
+$string['bold'] = 'Bold';
+$string['cancel_moving'] = 'Cancel moving';
+$string['captcha'] = 'Captcha';
+$string['check_values'] = 'Possible responses';
+$string['checkbox'] = 'Multiple choice - multiple answers allowed (check boxes)';
+$string['check'] = 'Multiple choice - multiple answers';
+$string['choosefile'] = 'Choose a file';
+$string['chosen_feedback_response'] = 'chosen feedback response';
+$string['completed'] = 'completed';
+$string['complete_the_form'] = 'Answer the questions...';
+$string['completed_feedbacks'] = 'Submitted answers';
+$string['continue_the_form'] = 'Continue the form';
+$string['count_of_nums'] = 'Count of numbers';
+$string['courseid'] = 'courseid';
+$string['creating_templates'] = 'Save these questions as a new template';
+$string['delete_entry'] = 'Delete entry';
+$string['delete_item'] = 'Delete question';
+$string['delete_old_items'] = 'Delete old items';
+$string['delete_template'] = 'Delete template';
+$string['delete_templates'] = 'Delete template...';
+$string['description'] = 'Description';
+$string['drop_feedback'] = 'Remove from this course';
+$string['dropdown'] = 'Multiple choice - single answer allowed (dropdownlist)';
+$string['dropdown_values'] = 'Answers';
+$string['dropdownlist'] = 'Multiple choice - single answer (dropdown)';
+$string['dropdownrated'] = 'Dropdownlist (rated)';
+$string['edit_item'] = 'Edit question';
+$string['edit_items'] = 'Edit questions';
+$string['email_notification'] = 'Send e-mail notifications';
+$string['emailteachermail'] = '$a->username has completed feedback activity : \'$a->feedback\'                               
+                                       
+You can view it here:                                   
+                                       
+$a->url';
+$string['emailteachermailhtml'] = '$a->username has completed feedback activity : <i>\'$a->feedback\'</i><br /><br />                             
+You can view it <a href=\"$a->url\">here</a>.';
+$string['entries_saved'] = 'Your answers have been saved. Thank you.';
+$string['export_questions'] = 'Export questions';
+$string['export_to_excel'] = 'Export to Excel';
+$string['feedback:complete'] = 'Complete a feedback';
+$string['feedback:createprivatetemplate'] = 'Create private template';
+$string['feedback:createpublictemplate'] = 'Create public template';
+$string['feedback:deletesubmissions'] = 'Delete completed submissions';
+$string['feedback:deletetemplate'] = 'Delete template';
+$string['feedback:edititems'] = 'Edit items';
+$string['feedback:mapcourse'] = 'Map courses to global feedbacks';
+$string['feedback:view'] = 'View a feedback';
+$string['feedback:viewreports'] = 'View reports';
+$string['feedback_is_not_open'] = 'The feedback is not open';
+$string['feedback_options'] = 'Feedback options';
+$string['feedbackclose'] = 'Close the feedback at';
+$string['feedbackcloses'] = 'Feedback closes';
+$string['feedbackopen'] = 'Open the feedback at';
+$string['feedbackopens'] = 'Feedback opens';
+$string['file'] = 'File';
+$string['filter_by_course'] = 'Filter by course';
+$string['handling_error']='Error occurred in feedback module action handling';
+$string['horizontal']='horizontal';
+$string['insufficient_responses_for_this_group'] = 'There are insufficient responses for this group';$string['import_questions'] = 'Import questions';
+$string['importfromthisfile'] = 'Import from this file';
+$string['import_successfully'] = 'Import successfully';
+$string['item_name'] = 'Question';
+$string['items_are_required'] = 'Answers are required to starred questions.';
+$string['label'] = 'Label';
+$string['line_labels'] = 'Label';
+$string['line_values'] = 'Rating';
+$string['mapcourse'] = 'Map course';
+$string['mapcourses'] = 'Map feedback to courses';
+$string['mapcourseinfo'] = 'This is a sitewide feedback that is available to all courses using the feedback block. You can however limit the courses to which it will appear by mapping them. Search the course and map it to this feedback.';
+$string['mapcoursenone'] = 'No courses mapped. Feedback available to all courses';
+$string['mappedcourses'] = 'Mapped courses';
+$string['max_args_exceeded'] = 'Max 6 arguments can be handled, too many arguments for';
+$string['maximal'] = 'maximal';
+$string['mode'] = 'Mode';
+$string['modulename'] = 'Feedback';
+$string['modulenameplural'] = 'Feedback';
+$string['move_item'] = 'Move this question';
+$string['movedown_item'] = 'Move this question down';
+$string['move_here'] = 'Move here';
+$string['moveup_item'] = 'Move this question up';
+$string['multiple_submit'] = 'Multiple submit';               
+$string['name'] = 'Name';
+$string['name_required'] = 'Name required';
+$string['next_page'] = 'Next page';
+$string['no_handler']='No action handler exists for';
+$string['no_itemname'] = 'No itemname';
+$string['no_items_available_yet'] = 'No questions have been set up yet';
+$string['no_templates_available_yet'] = 'No templates available yet';
+$string['non_anonymous'] = 'User\'s name will be logged and shown with answers';
+$string['non_anonymous_entries'] = 'non anonymous entries';
+$string['not_completed_yet'] = 'Not completed yet';
+$string['not_selected'] = 'Not selected';
+$string['numeric'] = 'Numeric answer';
+$string['numeric_range_from'] = 'Range from';
+$string['numeric_range_to'] = 'Range to';
+$string['of'] = 'of';
+$string['overview'] = 'Overview';
+$string['page'] = 'Page';
+$string['page_after_submit'] = 'Page after submit';
+$string['pagebreak']='Page break';
+$string['parameters_missing']='Parameters missing from';
+$string['picture_file_list'] = 'List of pictures';
+$string['picture_values'] = 'Choose one or more<br />picture files from the list:';
+$string['picture'] = 'Picture';
+$string['position'] = 'Position';
+$string['preview'] = 'Preview';
+$string['previous_page'] = 'Previous page';
+$string['public'] = 'Public';
+$string['publish_stats_on_students'] = 'Show analysis to students';
+$string['question'] = 'Question';
+$string['questions'] = 'Questions';
+$string['radio'] = 'Multiple choice - single answer';;
+$string['radio_values'] = 'Responses';
+$string['radiobutton'] = 'Multiple choice - single answer allowed (radio buttons)';;
+$string['radiobutton_rated'] = 'Radiobutton (rated)';
+$string['radiorated'] = 'Radiobutton (rated)';
+$string['ready_feedbacks'] = 'Ready feedbacks';
+$string['required'] = 'Required';
+$string['resetting_data'] = 'Reset feedback responses';
+$string['resetting_feedbacks'] = 'Resetting feedbacks';
+$string['response_nr'] = 'Response Nr.';
+$string['responses'] = 'Responses';
+$string['save_as_new_template'] = 'Save as new template';
+$string['save_entries'] = 'Submit your answers';
+$string['save_item'] = 'Save question';
+$string['saving_failed'] = 'Saving failed';
+$string['saving_failed_because_missing_or_false_values'] = 'Saving failed because missing or false values';
+$string['search_course'] = 'Search course';
+$string['selected_dump']='Selected indexes of \$SESSION variable are dumped below:';
+$string['separator_decimal'] = '.';
+$string['separator_thousand'] = ',';
+$string['show_all'] = 'Show all';
+$string['show_entries'] = 'Show responses';
+$string['show_entry'] = 'Show response';
+$string['sort_by_course'] = 'Sort by course';
+$string['start'] = 'Start';
+$string['stop'] = 'End';
+$string['switch_group'] = 'Switch group';
+$string['switch_item_to_not_required'] = 'switch to: answer not required';
+$string['switch_item_to_required'] = 'switch to: answer required';
+$string['template'] = 'Template';
+$string['template_saved'] = 'Template saved';
+$string['templates'] = 'Templates';
+$string['textarea'] = 'Longer text answer';
+$string['textarea_height'] = 'Number of lines';
+$string['textarea_width'] = 'Width';
+$string['textfield'] = 'Short text answer';
+$string['textfield_maxlength'] = 'Maximum characters accepted';
+$string['textfield_size'] = 'Textfield width';
+$string['this_feedback_is_already_submitted'] = 'You\'ve already completed this activity.';
+$string['update_item'] = 'Save changes to question';
+$string['use_one_line_for_each_value'] = '<br />Use one line for each answer!';
+$string['use_this_template'] = 'Use this template';
+$string['using_templates'] = 'Use a template';
+$string['vertical'] = 'vertical';
+
+?>
diff --git a/mod/feedback/README.txt b/mod/feedback/README.txt
new file mode 100644 (file)
index 0000000..b0df9b5
--- /dev/null
@@ -0,0 +1,211 @@
+Feedback-Module
+===============
+Overview
+--------
+The Feedback-Module is intended to create individual surveys in an easy way.
+
+This module consists of two parts
+a) the "activity" feedback (required)
+b) the "sideblock" feedback (optional)
+
+The activity is the main part an can run without the block. Here you can create, fill out or analyse the surveys.
+The sideblock is an optional part. It works as a bridge between different courses and
+an central placed feedback-activity. So you can create one feedback on the main site of moodle and then publish
+it in many courses.
+
+Requirements
+------------
+Moodle 1.9 or later
+
+Installation 
+------------
+   The zip-archive includes the same directory hierarchy as moodle
+   So you only have to copy the files to the correspondent place.
+   copy the folder feedback.zip/mod/feedback --> moodle/mod/feedback
+   and the folder feedback.zip/blocks/feedback --> moodle/blocks/feedback
+   The langfiles normaly can be left into the folder mod/feedback/lang.
+   The only exception is the feedback-block. The langfile is block_feedback.php and
+   have to be copied into the correspondent lang folder of moodle/moodledata.
+   All languages should be encoded with utf8.
+
+After it you have to run the admin-page of moodle (http://your-moodle-site/admin)
+in your browser. You have to loged in as admin before.
+The installation process will be displayed on the screen.
+That's all.
+
+using the block-feature
+-----------------------
+   1. create one or more new feedback-activitys on the moodle main-site
+   2. go into some course and enable the feedback-block. This block now shows the feedbacks from the main-site.
+   3. login as student and go into the course where the feedback-block is enabled
+   4. fill out the feedback chosen from block
+   5. login as admin and look at the feedback you created above
+   6. now you can analyse the answers over the courses
+
+good luck
+
+
+
+
+
+CHANGELOG
+=========
+
+04.04.2008
+- the heading has not supported multilang strings
+
+03.04.2008
+- anonymous feedback was send the userid on email-notification
+  (http://tracker.moodle.org/browse/CONTRIB-355)
+- users can not see the own values if there are chars like single-(') or doublequotas (")
+
+08.03.2008
+- admin users now respect capability-setting
+  (http://tracker.moodle.org/browse/CONTRIB-321)
+
+17.12.2007
+- resolved issue http://tracker.moodle.org/browse/CONTRIB-231
+
+03.12.2007
+- changing the table feedback_template, field public -> ispublic, public is reserved in oracle
+- resolved issue http://tracker.moodle.org/browse/CONTRIB-95
+
+16.09.2007
+- changing access.php, removed the lines with coursecreator, added some RISK_xxx
+- removed the check of legacy roles on has_capability()
+- coursesearch now use unicode characters
+
+13.09.2007
+- updated edit.php to make the output more xhtml 1.0 strict like
+
+11.09.2007
+- Update feedback settings has help showing wrongly
+- Menu on "Add question to activity" should be sorted alphabetically
+- missing "Add Pagebreak" is now at the item-list
+- no hardcoded css
+- use new print_header() (note it only is available on moodle 1.9!!!)
+- missing sesskey checks in feedback
+- uninitialised $filename when importing into feedback
+
+31.07.2007
+- fixed bug with missing numbers after xml Question-Import.
+
+29.07.2007
+- added "require_course_login()" in view.php
+- added missing langstring "no_itemname"
+
+25.07.2007
+- now defined in applicable_formats() to hide the block in moodle My-Site
+
+07.07.2007
+- all functions in lib.php now are with comments in phpdoc-style
+- removed all depricated function-calls
+- some code-styling changes (http://docs.moodle.org/en/Coding)
+
+06.07.2007
+- Adding some missing lang-strings
+- fixing some notice-messages with $SESSION-lstgroupid
+- excelexport now uses the localwincharset from langconfig.php
+    Now it is possible to export excel with utf8. But to many data will crash the excel
+    file. If the excefile crashes so you switch to latin-export in lang-settings
+- adding the default permission CAP_ALLOW to the legacy-role:user for the capabilities view and complete
+
+24.06.2007
+- fixed excel-problem with tempfiles
+- added new field "idnumber" into excel detailed report
+
+21.06.2007
+- better support for xhtml
+
+09.05.2007
+- items now are classes
+- most of forms use formslib
+- gui now uses tabs
+- new item "captcha"
+Now it only runs on Moodle 1.8 or later
+
+09.05.2007
+- added two columns (random_response,anonymous_response) to feedback_complete and feedback_complete_tmp
+- userids now will be logged even if the feedback is anonymous so you now can filter by group
+- excelexport now use pear so cell-values can be greater then 255 chars
+- logs now include the cm->id
+
+16.01.2007
+- the installation now uses the install.xml
+- roles are full implemented
+- now radiobuttons and checkboxes can be aligned horizontally or vertically
+- now you can insert pagebreakes
+- a feedback what is switch to the next page is saved temporary. the user can cancel the completion and later continue at the last filled page.
+- now you can ex-/import feedbacks into/from a xml-file
+- course-reseting is supported
+
+01.01.2007
+happy new year!
+
+14.09.2006 21:22
+improve the layout of analysis (thanks to Katja Krueger)
+
+02.06.2006 21:22
+several bugfixes
+improve the block "feedback"
+
+20.05.2006 01:00
+adding the block "feedback" to publish feedback over all courses
+Thanks to Jun Yamog!
+
+21.04.2006 16:00
+version 2006042102
+adding moving behavior like moodle activities
+adding a dropdownlist on create/update item page to adjust the position
+
+21.04.2006 16:00
+version 2006042101
+prefixed all function-names like "feedback_"
+fixed security issues (e.g. optional_variable() >> optional_param())
+improve group-feature
+
+03.01.2006 16:00
+Added "addslashes" and "stripslashes_safe" for preserving (')
+
+03.10.2005 13:00
+action handling error recovery improved (failed when debug=false)
+function feedback_action_handler() argument list changed
+added action handler debug modes: silent, normal, verbose
+
+30.09.2005 00:00
+version 2005300900
+action handling functions added
+picture item (an example for action handling added)
+XHTML compliance improved
+number of PHP Notify-level errors reduced
+source code transferred to CVS
+
+14.09.2005 00:20
+fixed problem with restoring
+new feature user-tracking (prevent multiple_submit)
+new feature deleting of some completeds
+
+22.08.2005 19:12
+fixed problem with secureforms-option
+
+16.08.2005 14:07
+fixed html-syntax in edit.php
+
+12.08.2005 21:38
+fixed problem with IE
+If feedback is not anonym now guest is it not allowed to fill it out
+
+11.08.2005 22:00
+added email-notification
+anonymous feedbacks can be filled out by anonymous users
+
+03.08.2005 01:20
+item specific functions were moved into the items-librarys
+now developers can create individual feedback-items
+javascript based filling-control was replaced by php-based control
+
+version = 2005072000
+20.07.2005 01:09
+adding group-ability
+fixed missing bcmod()-Function-Problem
+fixed referer-problem under https
diff --git a/mod/feedback/TODO.txt b/mod/feedback/TODO.txt
new file mode 100644 (file)
index 0000000..5c1347c
--- /dev/null
@@ -0,0 +1,6 @@
+- items use formslib
+- structured Numbering and switching visible or not
+- printview
+- css
+- the email displays the completed feedback
+-
diff --git a/mod/feedback/analysis.php b/mod/feedback/analysis.php
new file mode 100644 (file)
index 0000000..a48a622
--- /dev/null
@@ -0,0 +1,161 @@
+<?php // $Id$
+/**
+* shows an analysed view of feedback
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    // $SESSION->feedback->current_tab = 'analysis';
+    $current_tab = 'analysis';
+
+    $id = required_param('id', PARAM_INT);  //the POST dominated the GET
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    $lstgroupid = optional_param('lstgroupid', -2, PARAM_INT); //groupid (aus der Listbox gewaehlt)
+
+    //check, whether a group is selected
+    if($lstgroupid == -1) {
+        $SESSION->feedback->lstgroupid = false;
+    }else {
+        if((!isset($SESSION->feedback->lstgroupid)) || $lstgroupid != -2)
+            $SESSION->feedback->lstgroupid = $lstgroupid;
+    }
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+
+    if(isset($SESSION->feedback->lstgroupid)) {
+        if($tmpgroup = groups_get_group($SESSION->feedback->lstgroupid)) {
+            if($tmpgroup->courseid != $course->id) {
+                $SESSION->feedback->lstgroupid = false;
+            }
+        }else {
+            $SESSION->feedback->lstgroupid = false;
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+
+    if( !( (intval($feedback->publish_stats) == 1) || $capabilities->viewreports)) {
+        error(get_string('error'));
+    }
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// print the tabs
+    include('tabs.php');
+
+
+    //print analysed items
+    // print_simple_box_start("center", '80%');
+    print_box_start('generalbox boxaligncenter boxwidthwide');
+
+    //get the groupid
+    //lstgroupid is the choosen id
+    $mygroupid = $SESSION->feedback->lstgroupid;
+
+    if( $capabilities->viewreports ) {
+
+        //available group modes (NOGROUPS, SEPARATEGROUPS or VISIBLEGROUPS)
+        $feedbackgroups = get_groups($course->id);
+        //get the effective groupmode of this course and module
+        $groupmode = groupmode($course, $cm);
+        if(is_array($feedbackgroups) && $groupmode > 0){
+            require_once('choose_group_form.php');
+            //the use_template-form
+            $choose_group_form = new feedback_choose_group_form();
+            $choose_group_form->set_feedbackdata(array('groups'=>$feedbackgroups, 'mygroupid'=>$mygroupid));
+            $choose_group_form->set_form_elements();
+            $choose_group_form->set_data(array('id'=>$id, 'lstgroupid'=>$SESSION->feedback->lstgroupid));
+            $choose_group_form->display();
+        }
+
+        //button "export to excel"
+        //echo '<div align="center">';
+        // echo '<div class="feedback_centered_button">';
+        echo '<div class="form-buttons">';
+        $export_button_link = 'analysis_to_excel.php';
+        $export_button_options = array('sesskey'=>$USER->sesskey, 'id'=>$id);
+        $export_button_label = get_string('export_to_excel', 'feedback');
+        print_single_button($export_button_link, $export_button_options, $export_button_label, 'post');
+        echo '</div>';
+    }
+
+    //get completed feedbacks
+    $completedscount = feedback_get_completeds_group_count($feedback, $mygroupid);
+
+    //show the group, if available
+    if($mygroupid and $group = get_record('groups', 'id', $mygroupid)) {
+        echo '<b>'.get_string('group').': '.$group->name. '</b><br />';
+    }
+    //show the count
+    echo '<b>'.get_string('completed_feedbacks', 'feedback').': '.$completedscount. '</b><br />';
+
+    // get the items of the feedback
+    $items = get_records_select('feedback_item', 'feedback = '. $feedback->id . ' AND hasvalue = 1', 'position');
+    //show the count
+    if(is_array($items)){
+        echo '<b>'.get_string('questions', 'feedback').': ' .sizeof($items). ' </b><hr />';
+    } else {
+        $items=array();
+    }
+    $check_anonymously = true;
+    if($mygroupid > 0 AND $feedback->anonymous == FEEDBACK_ANONYMOUS_YES) {
+        if($completedscount < FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP) {
+            $check_anonymously = false;
+        }
+    }
+    // echo '<div align="center"><table width="80%" cellpadding="10"><tr><td>';
+    echo '<div><table width="80%" cellpadding="10"><tr><td>';
+    if($check_anonymously) {
+        $itemnr = 0;
+        //print the items in an analysed form
+        foreach($items as $item) {
+            if($item->hasvalue == 0) continue;
+            echo '<table width="100%" class="generalbox">';
+            //get the class of item-typ
+            $itemclass = 'feedback_item_'.$item->typ;
+            //get the instance of the item-class
+            $itemobj = new $itemclass();
+            $itemnr = $itemobj->print_analysed($item, $itemnr, $mygroupid);
+            echo '</table>';
+        }
+    }else {
+        print_heading_with_help(get_string('insufficient_responses_for_this_group', 'feedback'), 'insufficient_responses', 'feedback');
+    }
+    echo '</td></tr></table></div>';
+    // print_simple_box_end();
+    print_box_end();
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/analysis_course.php b/mod/feedback/analysis_course.php
new file mode 100644 (file)
index 0000000..ed7d2cc
--- /dev/null
@@ -0,0 +1,187 @@
+<?php // $Id$
+/**
+* shows an analysed view of a feedback on the mainsite
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    
+    // $SESSION->feedback->current_tab = 'analysis';
+    $current_tab = 'analysis';
+    $id = required_param('id', PARAM_INT);  //the POST dominated the GET
+    $coursefilter = optional_param('coursefilter', '0', PARAM_INT);
+    $courseitemfilter = optional_param('courseitemfilter', '0', PARAM_INT);
+    $courseitemfiltertyp = optional_param('courseitemfiltertyp', '0', PARAM_ALPHANUM);
+    // $searchcourse = optional_param('searchcourse', '', PARAM_ALPHAEXT);
+    $searchcourse = optional_param('searchcourse', '', PARAM_RAW);
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    
+    if(($searchcourse OR $courseitemfilter OR $coursefilter) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if( !( (intval($feedback->publish_stats) == 1) || $capabilities->viewreports)) {
+        error(get_string('error'));
+    }
+    
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// print the tabs
+    include('tabs.php');
+
+    //print the analysed items
+    // print_simple_box_start("center", '80%');
+    print_box_start('generalbox boxaligncenter boxwidthwide');
+
+    if( $capabilities->viewreports ) {
+        //button "export to excel"
+        echo '<div align="center">';
+        $export_button_link = 'analysis_to_excel.php';
+        $export_button_options = array('sesskey'=>$USER->sesskey, 'id'=>$id);
+        $export_button_label = get_string('export_to_excel', 'feedback');
+        print_single_button($export_button_link, $export_button_options, $export_button_label, 'post');
+        echo '</div>';
+    }
+    
+    //get the groupid
+    //lstgroupid is the choosen id
+    $mygroupid = false;
+    //get completed feedbacks
+    $completedscount = feedback_get_completeds_group_count($feedback, $mygroupid, $coursefilter);
+    
+    //show the count
+    echo '<b>'.get_string('completed_feedbacks', 'feedback').': '.$completedscount. '</b><br />';
+    
+    // get the items of the feedback
+    $items = get_records_select('feedback_item', 'feedback = '. $feedback->id . ' AND hasvalue = 1', 'position');
+    //show the count
+    if(is_array($items)){
+       echo '<b>'.get_string('questions', 'feedback').': ' .sizeof($items). ' </b><hr />';
+        echo '<a href="analysis_course.php?id=' . $id . '&courseid='.$courseid.'">'.get_string('show_all', 'feedback').'</a>';
+    } else {
+        $items=array();
+    }
+
+    echo '<form name="report" method="post">';
+    echo '<div align="center"><table width="80%" cellpadding="10">';
+    if ($courseitemfilter > 0) {
+        $avgvalue = 'avg(value)';
+        if ($CFG->dbtype == 'postgres7') {
+             $avgvalue = 'avg(cast (value as integer))';
+        }
+        if ($courses = get_records_sql ('select fv.course_id, c.shortname, '.$avgvalue.' as avgvalue '.
+                                                  'from '.$CFG->prefix.'feedback_value fv, '.$CFG->prefix.'course c, '.
+                                                  $CFG->prefix.'feedback_item fi '.
+                                                  'where fv.course_id = c.id '.
+                                                  'and fi.id = fv.item and fi.typ = \''.$courseitemfiltertyp.'\' and fv.item = \''.
+                                                  $courseitemfilter.'\' '.
+                                                  'group by course_id, shortname order by avgvalue desc')) {
+             $item = get_record('feedback_item', 'id', $courseitemfilter);
+             echo '<tr><th colspan="2">'.$item->name.'</th></tr>';
+             echo '<tr><td><table align="left">';
+             echo '<tr><th>Course</th><th>Average</th></tr>';
+             $sep_dec = get_string('separator_decimal', 'feedback');
+             $sep_thous = get_string('separator_thousand', 'feedback');
+
+             foreach ($courses as $c) {
+                  echo '<tr><td>'.$c->shortname.'</td><td align="right">'.number_format(($c->avgvalue), 2, $sep_dec, $sep_thous).'</td></tr>';
+             }
+             echo '</table></td></tr>';
+        } else {
+             echo '<tr><td>'.get_string('noresults').'</td></tr>';
+        }
+    } else {
+
+        echo get_string('search_course', 'feedback') . ': ';
+        echo '<input type="text" name="searchcourse" value="'.s($searchcourse).'"/> <input type="submit" value="'.get_string('search').'"/>';
+        echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+        echo '<input type="hidden" name="id" value="'.$id.'" />';
+        echo '<input type="hidden" name="courseitemfilter" value="'.$courseitemfilter.'" />';
+        echo '<input type="hidden" name="courseitemfiltertyp" value="'.$courseitemfiltertyp.'" />';
+        echo '<input type="hidden" name="courseid" value="'.$courseid.'" />';
+        echo '<script language="javascript" type="text/javascript">
+                <!--
+                function setcourseitemfilter(item, item_typ) {
+                    document.report.courseitemfilter.value = item;
+                    document.report.courseitemfiltertyp.value = item_typ;
+                    document.report.submit();
+                }
+                -->
+                </script>';
+
+
+        $sql = 'select c.id, c.shortname from '.$CFG->prefix.'course c, '.
+                                              $CFG->prefix.'feedback_value fv, '.$CFG->prefix.'feedback_item fi '.
+                                              'where c.id = fv.course_id and fv.item = fi.id '.
+                                              'and fi.feedback = '.$feedback->id.' '.
+                                              'and 
+                                              (c.shortname '.sql_ilike().' \'%'.$searchcourse.'%\'
+                                              OR c.fullname '.sql_ilike().' \'%'.$searchcourse.'%\')';
+        
+        if ($courses = get_records_sql_menu($sql)) {
+
+             echo ' ' . get_string('filter_by_course', 'feedback') . ': ';
+             choose_from_menu ($courses, 'coursefilter', $coursefilter, 'choose', 'this.form.submit()');
+        }
+        echo '<hr />';
+        $itemnr = 0;
+        //print the items in an analysed form
+        echo '<tr><td>';
+        foreach($items as $item) {
+            if($item->hasvalue == 0) continue;
+            echo '<table width="100%" class="generalbox">';    
+            //get the class from item-typ
+            $itemclass = 'feedback_item_'.$item->typ;
+            //get the instance of the item-class
+            $itemobj = new $itemclass();
+            $itemnr = $itemobj->print_analysed($item, $itemnr, $mygroupid, $coursefilter);
+            if (eregi('rated$', $item->typ)) {
+                 echo '<tr><td colspan="2"><a href="#" onclick="setcourseitemfilter('.$item->id.',\''.$item->typ.'\'); return false;">'.
+                    get_string('sort_by_course', 'feedback').'</a></td></tr>'; 
+            }
+            echo '</table>';
+        }
+        echo '</td></tr>';
+    }
+    echo '</table></div>';
+    echo '</form>';
+    print_box_end();
+    
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/analysis_to_excel.php b/mod/feedback/analysis_to_excel.php
new file mode 100644 (file)
index 0000000..8bcf9d5
--- /dev/null
@@ -0,0 +1,256 @@
+<?php // $Id$
+/**
+* prints an analysed excel-spreadsheet of the feedback
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once('easy_excel.php');
+    $id = required_param('id', PARAM_INT);  //the POST dominated the GET
+    
+    $formdata = data_submitted('nomatch');
+    
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->viewreports){
+        error(get_string('error'));
+    }
+
+    //buffering any output
+    //this prevents some output before the excel-header will be send
+    ob_start();
+    $fstring = new object();
+    $fstring->bold = get_string('bold', 'feedback');
+    $fstring->page = get_string('page', 'feedback');
+    $fstring->of = get_string('of', 'feedback');
+    $fstring->modulenameplural = get_string('modulenameplural', 'feedback');
+    $fstring->questions = get_string('questions', 'feedback');
+    $fstring->question = get_string('question', 'feedback');
+    $fstring->responses = get_string('responses', 'feedback');
+    $fstring->idnumber = get_string('idnumber');
+    $fstring->username = get_string('username');
+    $fstring->fullname = get_string('fullname');
+    $fstring->courseid = get_string('courseid', 'feedback');
+    $fstring->course = get_string('course');
+    $fstring->anonymous_user = get_string('anonymous_user','feedback');
+    ob_end_clean();
+
+    $filename = "feedback.xls";
+    
+    //get the groupid for this module
+    //get the groupid
+    $mygroupid = $SESSION->feedback->lstgroupid;
+
+    // Creating a workbook
+    $workbook = new EasyWorkbook("-");
+    $workbook->setTempDir('/srv/www/moodledata');
+    $workbook->send($filename);
+    $workbook->setVersion(8);
+    // Creating the worksheets
+    $sheetname = clean_param($feedback->name, PARAM_ALPHANUM);
+    error_reporting(0);
+    $worksheet1 =& $workbook->addWorksheet(substr($sheetname, 0, 31));
+    $worksheet1->set_workbook($workbook);
+    $worksheet2 =& $workbook->addWorksheet('detailed');
+    $worksheet2->set_workbook($workbook);
+    error_reporting($CFG->debug);
+    $worksheet1->setPortrait();
+    $worksheet1->setPaper(9);
+    $worksheet1->centerHorizontally();
+    $worksheet1->hideGridlines();
+    $worksheet1->setHeader("&\"Arial," . $fstring->bold . "\"&14".$feedback->name);
+    $worksheet1->setFooter($fstring->page." &P " . $fstring->of . " &N");
+    $worksheet1->setColumn(0, 0, 30);
+    $worksheet1->setColumn(1, 20, 15);
+    $worksheet1->setMargins_LR(0.10);
+
+    $worksheet2->setLandscape();
+    $worksheet2->setPaper(9);
+    $worksheet2->centerHorizontally();
+
+    //writing the table header
+    $rowOffset1 = 0;
+    $worksheet1->setFormat("<f>",12,false);
+    $worksheet1->write_string($rowOffset1, 0, UserDate(time()));
+
+    ////////////////////////////////////////////////////////////////////////
+    //print the analysed sheet
+    ////////////////////////////////////////////////////////////////////////
+    //get the completeds
+    $completedscount = feedback_get_completeds_group_count($feedback, $mygroupid);
+    if($completedscount > 0){
+        //write the count of completeds
+        $rowOffset1++;
+        $worksheet1->write_string($rowOffset1, 0, $fstring->modulenameplural.': '.strval($completedscount));
+    }
+
+    //get the questions (item-names)
+    $items = get_records_select('feedback_item', 'feedback = '. $feedback->id . ' AND hasvalue = 1', 'position');
+    if(is_array($items)){
+        $rowOffset1++;
+        $worksheet1->write_string($rowOffset1, 0, $fstring->questions.': '. strval(sizeof($items)));
+    }
+    
+    $rowOffset1 += 2;
+    $worksheet1->write_string($rowOffset1, 0, $fstring->question);
+    $worksheet1->write_string($rowOffset1, 1, $fstring->responses);
+    $rowOffset1++ ;
+
+    if (empty($items)) {
+         $items=array();
+    }
+    foreach($items as $item) {
+        //get the class of item-typ
+        $itemclass = 'feedback_item_'.$item->typ;
+        //get the instance of the item-class
+        $itemobj = new $itemclass();
+        $rowOffset1 = $itemobj->excelprint_item($worksheet1, $rowOffset1, $item, $mygroupid);
+    }
+
+    ////////////////////////////////////////////////////////////////////////
+    //print the detailed sheet
+    ////////////////////////////////////////////////////////////////////////
+    //get the completeds
+    
+    $completeds = feedback_get_completeds_group($feedback, $mygroupid);
+    //important: for each completed you have to print each item, even if it is not filled out!!!
+    //therefor for each completed we have to iterate over all items of the feedback
+    //this is done by feedback_excelprint_detailed_items
+    
+    $rowOffset2 = 0;
+    //first we print the table-header
+    $rowOffset2 = feedback_excelprint_detailed_head($worksheet2, $items, $rowOffset2);
+    
+    
+    if(is_array($completeds)){
+        foreach($completeds as $completed) {
+            $rowOffset2 = feedback_excelprint_detailed_items($worksheet2, $completed, $items, $rowOffset2);
+        }
+    }
+    
+    
+    $workbook->close();
+    exit;
+////////////////////////////////////////////////////////////////////////////////    
+////////////////////////////////////////////////////////////////////////////////    
+//functions
+////////////////////////////////////////////////////////////////////////////////    
+
+    
+    function feedback_excelprint_detailed_head(&$worksheet, $items, $rowOffset) {
+        global $fstring, $feedback;
+        
+        if(!$items) return;
+        $colOffset = 0;
+        
+        $worksheet->setFormat('<l><f><ru2>');
+
+        $worksheet->write_string($rowOffset, $colOffset, $fstring->idnumber);
+        $colOffset++;
+
+        $worksheet->write_string($rowOffset, $colOffset, $fstring->username);
+        $colOffset++;
+
+        $worksheet->write_string($rowOffset, $colOffset, $fstring->fullname);
+        $colOffset++;
+        
+        foreach($items as $item) {
+            $worksheet->setFormat('<l><f><ru2>');
+            $worksheet->write_string($rowOffset, $colOffset, stripslashes_safe($item->name));
+            $colOffset++;
+        }
+
+        $worksheet->setFormat('<l><f><ru2>');
+        $worksheet->write_string($rowOffset, $colOffset, $fstring->courseid);
+        $colOffset++;
+
+        $worksheet->setFormat('<l><f><ru2>');
+        $worksheet->write_string($rowOffset, $colOffset, $fstring->course);
+        $colOffset++;
+
+        return $rowOffset + 1;
+    }
+    
+    function feedback_excelprint_detailed_items(&$worksheet, $completed, $items, $rowOffset) {
+        global $fstring;
+        
+        if(!$items) return;
+        $colOffset = 0;
+        $courseid = 0;
+        
+        $feedback = get_record('feedback', 'id', $completed->feedback);
+        //get the username
+        //anonymous users are separated automatically because the userid in the completed is "0"
+        $worksheet->setFormat('<l><f><ru2>');
+        if($user = get_record('user', 'id', $completed->userid)) {
+            if ($completed->anonymous_response == FEEDBACK_ANONYMOUS_NO) {
+                $worksheet->write_string($rowOffset, $colOffset, $user->idnumber);
+                $colOffset++;
+                $userfullname = fullname($user);
+                $worksheet->write_string($rowOffset, $colOffset, $user->username);
+                $colOffset++;
+            } else {
+                $userfullname = $fstring->anonymous_user;
+                $worksheet->write_string($rowOffset, $colOffset, '-');
+                $colOffset++;
+                $worksheet->write_string($rowOffset, $colOffset, '-');
+                $colOffset++;
+            }
+        }else {
+            $userfullname = $fstring->anonymous_user;
+            $worksheet->write_string($rowOffset, $colOffset, '-');
+            $colOffset++;
+            $worksheet->write_string($rowOffset, $colOffset, '-');
+            $colOffset++;
+        }
+        
+        $worksheet->write_string($rowOffset, $colOffset, $userfullname);
+        
+        $colOffset++;
+        foreach($items as $item) {
+            $value = get_record('feedback_value', 'item', $item->id, 'completed', $completed->id);
+            
+            $itemclass = 'feedback_item_'.$item->typ;
+            $itemobj = new $itemclass();
+            $printval = $itemobj->get_printval($item, $value);
+
+            $worksheet->setFormat('<l><vo>');
+            if(is_numeric($printval)) {
+                $worksheet->write_number($rowOffset, $colOffset, trim($printval));
+            } else {
+                $worksheet->write_string($rowOffset, $colOffset, trim($printval));
+            }
+            $printval = '';
+            $colOffset++;
+            $courseid = isset($value->course_id) ? $value->course_id : 0;
+            if($courseid == 0) $courseid = $feedback->course;
+        }
+        $worksheet->write_number($rowOffset, $colOffset, $courseid);
+        $colOffset++;
+        if(isset($courseid) AND $course = get_record('course', 'id', $courseid)){
+            $worksheet->write_string($rowOffset, $colOffset, $course->shortname);
+        }
+        return $rowOffset + 1;
+    }
+?>
diff --git a/mod/feedback/backuplib.php b/mod/feedback/backuplib.php
new file mode 100644 (file)
index 0000000..f66ace3
--- /dev/null
@@ -0,0 +1,270 @@
+<?php // $Id$
+    //This php script contains all the stuff to backup/restore
+    //feedback mods
+
+    //This is the "graphical" structure of the feedback mod:
+    //
+    //                     feedback---------------------------------feedback_tracking
+    //                    (CL,pk->id)                            (UL, pk->id, fk->feedback,completed)
+    //                        |                                           |
+    //                        |                                           |
+    //                        |                                           |
+    //                 feedback_template                            feedback_completed
+    //                   (CL,pk->id)                           (UL, pk->id, fk->feedback)
+    //                        |                                           |
+    //                        |                                           |
+    //                        |                                           |
+    //                 feedback_item---------------------------------feedback_value
+    //        (ML,pk->id, fk->feedback, fk->template)       (UL, pk->id, fk->item, fk->completed)
+    //
+    // Meaning: pk->primary key field of the table
+    //          fk->foreign key to link with parent
+    //          CL->course level info
+    //          ML->modul level info
+    //          UL->userid level info
+    //          message->text of each feedback_posting
+    //
+    //-----------------------------------------------------------
+
+    //This function executes all the backup procedure about this mod
+   function feedback_backup_mods($bf,$preferences) {
+      global $CFG;
+
+      $status = true;
+
+      //Iterate over feedback table
+      $feedbacks = get_records ("feedback","course",$preferences->backup_course,"id");
+      if ($feedbacks) {
+         foreach ($feedbacks as $feedback) {
+            if (backup_mod_selected($preferences,'feedback',$feedback->id)) {
+               $status = feedback_backup_one_mod($bf,$preferences,$feedback);
+            }
+         }
+      }
+      return $status;  
+   }
+
+   function feedback_backup_one_mod($bf,$preferences,$feedback) {
+      global $CFG;
+    
+      if (is_numeric($feedback)) {
+         $feedback = get_record('feedback','id',$feedback);
+      }
+      
+      $status = true;
+      fwrite ($bf,start_tag("MOD",3,true));
+      //Print feedback data
+      fwrite ($bf,full_tag("ID",4,false,$feedback->id));
+      fwrite ($bf,full_tag("MODTYPE",4,false,"feedback"));
+      fwrite ($bf,full_tag("VERSION",4,false,1)); //version 1 steht fuer die neue Version
+      fwrite ($bf,full_tag("NAME",4,false,$feedback->name));
+      fwrite ($bf,full_tag("SUMMARY",4,false,$feedback->summary));
+      fwrite ($bf,full_tag("ANONYMOUS",4,false,$feedback->anonymous));
+      fwrite ($bf,full_tag("EMAILNOTIFICATION",4,false,$feedback->email_notification));
+      fwrite ($bf,full_tag("MULTIPLESUBMIT",4,false,$feedback->multiple_submit));
+      fwrite ($bf,full_tag("PAGEAFTERSUB",4,false,$feedback->page_after_submit));
+      fwrite ($bf,full_tag("PUBLISHSTATS",4,false,$feedback->publish_stats));
+      fwrite ($bf,full_tag("TIMEOPEN",4,false,$feedback->timeopen));
+      fwrite ($bf,full_tag("TIMECLOSE",4,false,$feedback->timeclose));
+      fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$feedback->timemodified));
+       
+      //backup the items of each feedback
+      feedback_backup_data($bf, $preferences, $feedback->id);
+       
+      //End mod
+      $status =fwrite ($bf,end_tag("MOD",3,true));
+      return $status;
+   }
+   
+   function feedback_backup_data($bf, $preferences, $feedbackid) {
+      global $CFG;
+      $status = true;
+      $feedbackitems = get_records('feedback_item', 'feedback', $feedbackid);
+      if(function_exists('backup_userdata_selected')) { //compatibility-hack for moodle 1.5.x
+         $backup_userdata = backup_userdata_selected($preferences,'feedback',$feedbackid);
+      }else {
+         $backup_userdata = $preferences->mods["feedback"]->userinfo;
+      }
+
+      if ($feedbackitems) {
+         $status =fwrite ($bf,start_tag("ITEMS",4,true));
+         foreach ($feedbackitems as $feedbackitem) {
+            //Start item
+            fwrite ($bf,start_tag("ITEM",5,true));
+            //Print item data
+            fwrite ($bf,full_tag("ID",6,false,$feedbackitem->id));
+            fwrite ($bf,full_tag("NAME",6,false,$feedbackitem->name));
+            fwrite ($bf,full_tag("PRESENTATION",6,false,$feedbackitem->presentation));
+            fwrite ($bf,full_tag("TYP",6,false,$feedbackitem->typ));
+            fwrite ($bf,full_tag("HASVALUE",6,false,$feedbackitem->hasvalue));
+            fwrite ($bf,full_tag("POSITION",6,false,$feedbackitem->position));
+            fwrite ($bf,full_tag("REQUIRED",6,false,$feedbackitem->required));
+            
+            if ($backup_userdata) {
+               //backup the values of items
+               $feedbackvalues = get_records('feedback_value', 'item', $feedbackitem->id);
+               if($feedbackvalues) {
+                  $status =fwrite ($bf,start_tag("FBVALUES",6,true));
+                  foreach($feedbackvalues as $feedbackvalue) {
+                     //start value
+                     fwrite ($bf,start_tag("FBVALUE",7,true));
+                     //print value data
+                     fwrite ($bf,full_tag("ID",8,false,$feedbackvalue->id));
+                     fwrite ($bf,full_tag("ITEM",8,false,$feedbackvalue->item));
+                     fwrite ($bf,full_tag("COMPLETED",8,false,$feedbackvalue->completed));
+                     fwrite ($bf,full_tag("VAL",8,false,$feedbackvalue->value));
+                     fwrite ($bf,full_tag("COURSE_ID",8,false,$feedbackvalue->course_id));
+                     //End value
+                     $status =fwrite ($bf,end_tag("FBVALUE",7,true));
+                  }
+                  $status =fwrite ($bf,end_tag("FBVALUES",6,true));
+               }
+            }
+            //End item
+            $status =fwrite ($bf,end_tag("ITEM",5,true));
+         }
+         $status =fwrite ($bf,end_tag("ITEMS",4,true));
+      }
+      
+      if($backup_userdata) {
+         //backup of feedback-completeds
+         $feedbackcompleteds = get_records('feedback_completed', 'feedback', $feedbackid);
+         if($feedbackcompleteds) {
+            fwrite ($bf,start_tag("COMPLETEDS",4,true));
+            foreach ($feedbackcompleteds as $feedbackcompleted) {
+               //Start completed
+               fwrite ($bf,start_tag("COMPLETED",5,true));
+               //Print completed data
+               fwrite ($bf,full_tag("ID",6,false,$feedbackcompleted->id));
+               fwrite ($bf,full_tag("FEEDBACK",6,false,$feedbackcompleted->feedback));
+               fwrite ($bf,full_tag("USERID",6,false,$feedbackcompleted->userid));
+               fwrite ($bf,full_tag("TIMEMODIFIED",6,false,$feedbackcompleted->timemodified));
+               fwrite ($bf,full_tag("RANDOMRESPONSE",6,false,$feedbackcompleted->random_response));
+               fwrite ($bf,full_tag("ANONYMOUSRESPONSE",6,false,$feedbackcompleted->anonymous_response));
+               
+               //End completed
+               $status =fwrite ($bf,end_tag("COMPLETED",5,true));
+            }
+            $status =fwrite ($bf,end_tag("COMPLETEDS",4,true));
+         }
+         
+         //backup of tracking-data
+         $feedbacktrackings = get_records('feedback_tracking', 'feedback', $feedbackid);
+         if($feedbacktrackings) {
+            fwrite ($bf,start_tag("TRACKINGS",4,true));
+            foreach ($feedbacktrackings as $feedbacktracking) {
+               //Start tracking
+               fwrite ($bf,start_tag("TRACKING",5,true));
+               //Print tracking data
+               fwrite ($bf,full_tag("ID",6,false,$feedbacktracking->id));
+               fwrite ($bf,full_tag("USERID",6,false,$feedbacktracking->userid));
+               fwrite ($bf,full_tag("FEEDBACK",6,false,$feedbacktracking->feedback));
+               fwrite ($bf,full_tag("COMPLETED",6,false,$feedbacktracking->completed));
+               fwrite ($bf,full_tag("COUNT",6,false,$feedbacktracking->count));
+               
+               //End completed
+               $status =fwrite ($bf,end_tag("TRACKING",5,true));
+            }
+            $status =fwrite ($bf,end_tag("TRACKINGS",4,true));
+         }
+         
+      }
+
+   }
+
+
+   function feedback_backup_template_data($bf, $templateid, $userinfo) {
+      global $CFG;
+      $status = true;
+      $templateitems = get_records('feedback_item', 'template', $templateid);
+
+      if ($templateitems) {
+         $status =fwrite ($bf,start_tag("ITEMS",5,true));
+         foreach ($templateitems as $templateitem) {
+            //Start item
+            fwrite ($bf,start_tag("ITEM",6,true));
+            //Print item data
+            fwrite ($bf,full_tag("ID",7,false,$templateitem->id));
+            fwrite ($bf,full_tag("NAME",7,false,$templateitem->name));
+            fwrite ($bf,full_tag("PRESENTATION",7,false,$templateitem->presentation));
+            fwrite ($bf,full_tag("TYP",7,false,$templateitem->typ));
+            fwrite ($bf,full_tag("HASVALUE",7,false,$templateitem->hasvalue));
+            fwrite ($bf,full_tag("POSITION",7,false,$templateitem->position));
+            fwrite ($bf,full_tag("REQUIRED",7,false,$templateitem->required));
+            
+            //End item
+            $status =fwrite ($bf,end_tag("ITEM",6,true));
+         }
+         $status =fwrite ($bf,end_tag("ITEMS",5,true));
+      }
+   }
+
+
+
+
+   //Return an array of info (name,value)
+   function feedback_check_backup_mods($course,$user_data=false,$backup_unique_code, $instances=null) {
+      if (!empty($instances) && is_array($instances) && count($instances)) {
+         $info = array();
+         foreach ($instances as $id => $instance) {
+            $info += feedback_check_backup_mods_instances($instance,$backup_unique_code);
+         }
+         return $info;
+      }
+      //First the course data
+      $info[0][0] = get_string("modulenameplural","feedback");
+      $info[0][1] = feedback_count($course);
+      
+      //Now, if requested, the user_data
+      
+      if ($user_data) {
+         $info[1][0] = get_string('ready_feedbacks','feedback');
+         $info[1][1] = feedback_completed_count($course);
+      }
+      
+      return $info;
+   }
+
+   ////Return an array of info (name,value)
+   function feedback_check_backup_mods_instances($instance,$backup_unique_code) {
+      //First the course data
+      $info[$instance->id.'0'][0] = '<b>'.$instance->name.'</b>';
+      $info[$instance->id.'0'][1] = '';
+
+      //Now, if requested, the user_data
+      if (!empty($instance->userdata)) {
+         $info[$instance->id.'1'][0] = get_string("responses","feedback");
+         if ($responses_count = count_records ('feedback_completed', 'feedback', $instance->id)) {
+               $info[$instance->id.'1'][1] = $responses_count;
+         } else {
+               $info[$instance->id.'1'][1] = 0;
+         }
+      }
+      return $info;
+   }
+
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+//// INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+   //Returns an array of feedbacks ids 
+   function feedback_count ($course) {
+      global $CFG;
+      return count_records('feedback', 'course', $course);
+   }
+   
+   function feedback_completed_count($course) {
+      global $CFG;
+      $count = 0;
+      //get all feedbacks
+      $feedbacks = get_records('feedback', 'course', $course);
+      if($feedbacks) {
+         foreach($feedbacks as $feedback) {
+            $count += count_records('feedback_completed', 'feedback', $feedback->id);
+         }
+      }
+      return $count;
+   }
+   
+?>
diff --git a/mod/feedback/choose_group_form.php b/mod/feedback/choose_group_form.php
new file mode 100644 (file)
index 0000000..c4a6482
--- /dev/null
@@ -0,0 +1,63 @@
+<?php // $Id$
+/**
+* prints the form to choose the group you want to analyse
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once $CFG->libdir.'/formslib.php';
+
+class feedback_choose_group_form extends moodleform {
+    var $feedbackdata;
+    
+    function definition() {
+        $this->feedbackdata = new object();
+        //this function can not be called, because not all data are available at this time
+        //I use set_form_elements instead
+    }
+    
+    //this function set the data used in set_form_elements()
+    //in this form the only value have to set is course
+    //eg: array('course' => $course)
+    function set_feedbackdata($data) {
+        if(is_array($data)) {
+            foreach($data as $key => $val) {
+                $this->feedbackdata->{$key} = $val;
+            }
+        }
+    }
+    
+    //here the elements will be set
+    //this function have to be called manually
+    //the advantage is that the data are already set
+    function set_form_elements(){
+        $mform =& $this->_form;
+        
+        $elementgroup = array();
+        //headline
+        // $mform->addElement('header', 'general', get_string('choose_group', 'feedback'));
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'do_show');
+        
+        // visible elements
+        $groups_options = array();
+        if(isset($this->feedbackdata->groups)){
+            $groups_options['-1'] = get_string('allgroups');
+            foreach($this->feedbackdata->groups as $group) {
+                $groups_options[$group->id] = $group->name;
+            }
+        }
+        $attributes = 'onChange="this.form.submit()"';
+        $elementgroup[] =& $mform->createElement('select', 'lstgroupid', '', $groups_options, $attributes);
+        // buttons
+        $elementgroup[] =& $mform->createElement('submit', 'switch_group', get_string('switch_group', 'feedback'));
+        $mform->addGroup($elementgroup, 'elementgroup', '', array(' '), false);
+        
+//-------------------------------------------------------------------------------
+    }
+}
+?>
diff --git a/mod/feedback/complete.php b/mod/feedback/complete.php
new file mode 100644 (file)
index 0000000..0207f64
--- /dev/null
@@ -0,0 +1,405 @@
+<?php // $Id$
+/**
+* prints the form so the user can fill out the feedback
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    $id = required_param('id', PARAM_INT);
+    $completedid = optional_param('completedid', false, PARAM_INT);
+    $preservevalues  = optional_param('preservevalues', 0,  PARAM_INT);
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    $gopage = optional_param('gopage', -1, PARAM_INT);
+    $lastpage = optional_param('lastpage', false, PARAM_INT);
+    $startitempos = optional_param('startitempos', 0, PARAM_INT);
+    $lastitempos = optional_param('lastitempos', 0, PARAM_INT);
+    $anonymous_response = optional_param('anonymous_response', 0, PARAM_INT); //arb
+
+    $highlightrequired = false;
+
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+
+    //if the use hit enter into a textfield so the form should not submit
+    if(isset($formdata->sesskey) AND !isset($formdata->savevalues) AND !isset($formdata->gonextpage) AND !isset($formdata->gopreviouspage)) {
+        $gopage = $formdata->lastpage;
+    }
+
+    if(isset($formdata->savevalues)) {
+        $savevalues = true;
+    }else {
+        $savevalues = false;
+    }
+    
+    if($gopage < 0 AND !$savevalues) {
+        if(isset($formdata->gonextpage)){
+            $gopage = $lastpage + 1;
+            $gonextpage = true;
+            $gopreviouspage = false;
+        }else if(isset($formdata->gopreviouspage)){
+            $gopage = $lastpage - 1;
+            $gonextpage = false;
+            $gopreviouspage = true;
+        }else {
+            error('parameter (gopage) required');
+        }
+    }else {
+        $gonextpage = $gopreviouspage = false;
+    }
+    
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+
+    $capabilities = feedback_load_capabilities($cm->id);
+    
+    if($feedback->anonymous == FEEDBACK_ANONYMOUS_YES) {
+        $capabilities->complete = true;
+    }
+    //check whether the feedback is located and! started from the mainsite
+    if($course->id == SITEID AND !$courseid) {
+        $courseid = SITEID;
+    }
+        
+    if($feedback->anonymous != FEEDBACK_ANONYMOUS_YES) {
+        require_login($course->id);
+    } else {
+        require_course_login($course);
+    }
+    
+    if($courseid AND $courseid != SITEID) {
+        $course2 = get_record('course', 'id', $courseid);
+        require_course_login($course2); //this overwrites the object $course :-(
+        $course = get_record("course", "id", $cm->course); // the workaround
+    }
+    
+    if(!$capabilities->complete) {
+        error(get_string('error'));
+    }
+    
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    //ishidden check.
+    if ((empty($cm->visible) and !$capabilities->viewhiddenactivities) AND $course->id != SITEID) {
+        notice(get_string("activityiscurrentlyhidden"));
+    }
+
+    feedback_print_errors();
+  
+    //check, if the feedback is open (timeopen, timeclose)
+    $checktime = time();
+    if(($feedback->timeopen > $checktime) OR ($feedback->timeclose < $checktime AND $feedback->timeclose > 0)) {
+        // print_simple_box_start('center');
+        print_box_start('generalbox boxaligncenter');
+            echo '<h2><font color="red">'.get_string('feedback_is_not_open', 'feedback').'</font></h2>';
+            print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+        // print_simple_box_end();
+        print_box_end();
+        print_footer($course);
+        exit;
+    }
+    
+    //additional check for multiple-submit (prevent browsers back-button). the main-check is in view.php
+    $feedback_can_submit = true;
+    if($feedback->multiple_submit == 0 ) {
+        if(feedback_is_already_submitted($feedback->id, $courseid)) {
+            $feedback_can_submit = false;
+        }
+    }
+    if($feedback_can_submit) {
+        //preserving the items
+        if($preservevalues == 1){
+            if(!$SESSION->feedback->is_started == true)error('error', $CFG->wwwroot.'/course/view.php?id='.$course->id);
+            //checken, ob alle required items einen wert haben
+            if(feedback_check_values($_POST, $startitempos, $lastitempos)) {
+                    $userid = $USER->id; //arb
+                if($completedid = feedback_save_values($_POST, $USER->id, true)){
+                    if($userid > 0) {
+                        add_to_log($course->id, "feedback", "startcomplete", "view.php?id=$cm->id", "$feedback->name", $cm->id, $userid);
+                    }
+                    if(!$gonextpage AND !$gopreviouspage) $preservevalues = false;//es kann gespeichert werden
+                    
+                }else {
+                    $savereturn = 'failed';
+                    if(isset($lastpage)) {
+                        $gopage = $lastpage;
+                    }else {
+                        error('parameter failed');
+                    }
+                }
+            }else {
+                $savereturn = 'missing';
+                $highlightrequired = true;
+                if(isset($lastpage)) {
+                    $gopage = $lastpage;
+                }else {
+                    error('parameter failed');
+                }
+            
+            }
+        }
+        
+        //saving the items
+        if($savevalues AND !$preservevalues){
+            //exists there any pagebreak, so there are values in the feedback_valuetmp
+            $userid = $USER->id; //arb
+
+            if($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) {
+                $feedbackcompleted = feedback_get_current_completed($feedback->id, false, $courseid);
+            }else{
+                $feedbackcompleted = false;
+            }
+            $feedbackcompletedtmp = get_record('feedback_completedtmp', 'id', $completedid);
+            //fake saving for switchrole
+            $is_switchrole = feedback_check_is_switchrole();
+            if($is_switchrole) {
+                $savereturn = 'saved';
+                feedback_delete_completedtmp($completedid);
+            }else if($new_completed_id = feedback_save_tmp_values($feedbackcompletedtmp, $feedbackcompleted, $userid)) {
+                $savereturn = 'saved';
+                if($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) {
+                    add_to_log($course->id, "feedback", "submit", "view.php?id=$cm->id", "$feedback->name", $cm->id, $userid);
+                    feedback_email_teachers($cm, $feedback, $course, $userid);
+                }else {
+                    feedback_email_teachers_anonym($cm, $feedback, $course, $userid);
+                }
+                //tracking the submit
+                $multiple_count = null;
+                $multiple_count->userid = $USER->id;
+                $multiple_count->feedback = $feedback->id;
+                $multiple_count->completed = $new_completed_id;
+                $multiple_count->count = 1;
+                insert_record('feedback_tracking', $multiple_count);
+                unset($SESSION->feedback->is_started);
+                
+            }else {
+                $savereturn = 'failed';
+            }
+           
+        }
+
+
+        if($allbreaks = feedback_get_all_break_positions($feedback->id)){
+            if($gopage <= 0) {
+                $startposition = 0;
+            }else {
+                $startposition = $allbreaks[$gopage - 1];
+            }
+            $ispagebreak = true;
+        }else {
+            $startposition = 0;
+            $newpage = 0;
+            $ispagebreak = false;
+        }
+        
+        //get the feedbackitems after the last shown pagebreak
+        $feedbackitems = get_records_select('feedback_item', 'feedback = '.$feedback->id.' AND position > '.$startposition, 'position');
+        
+        //get the first pagebreak
+        if($pagebreaks = get_records_select('feedback_item', "feedback = ".$feedback->id." AND typ = 'pagebreak'", 'position')) {
+            $pagebreaks = array_values($pagebreaks);
+            $firstpagebreak = $pagebreaks[0];
+        }else {
+            $firstpagebreak = false;
+        }
+        $maxitemcount = count_records('feedback_item', 'feedback', $feedback->id);
+        
+        //get the values of completeds before done. Anonymous user can not get these values.
+        if((!isset($SESSION->feedback->is_started)) AND (!isset($savereturn)) AND ($feedback->anonymous == FEEDBACK_ANONYMOUS_NO)) {
+            if(!$feedbackcompletedtmp = feedback_get_current_completed($feedback->id, true, $courseid)) {
+                if($feedbackcompleted = feedback_get_current_completed($feedback->id, false, $courseid)) {
+                    //copy the values to feedback_valuetmp create a completedtmp
+                    $feedbackcompletedtmp = feedback_set_tmp_values($feedbackcompleted);
+                }
+            }
+        }else {
+            $feedbackcompletedtmp = feedback_get_current_completed($feedback->id, true, $courseid);
+        }
+
+        /// Print the main part of the page
+        ///////////////////////////////////////////////////////////////////////////
+        ///////////////////////////////////////////////////////////////////////////
+        ///////////////////////////////////////////////////////////////////////////
+        print_heading(format_text($feedback->name));
+        
+        if(isset($savereturn) && $savereturn == 'saved') {
+            if($feedback->page_after_submit) {
+                // print_simple_box_start('center', '75%');
+                print_box_start('generalbox boxaligncenter boxwidthwide');
+                echo format_text(stripslashes_safe($feedback->page_after_submit));
+                // print_simple_box_end();
+                print_box_end();
+            } else {
+                echo '<p align="center"><b><font color="green">'.get_string('entries_saved','feedback').'</font></b></p>';
+                if( intval($feedback->publish_stats) == 1) {
+                    echo '<p align="center"><a href="analysis.php?id=' . $id . '&courseid='.$courseid.'">';
+                    echo get_string('completed_feedbacks', 'feedback').'</a>';
+                    echo '</p>';
+                }
+            }
+            if($courseid) {
+                print_continue($CFG->wwwroot.'/course/view.php?id='.$courseid);
+            }else {
+                if($course->id == SITEID) {
+                    print_continue($CFG->wwwroot);
+                } else {
+                    print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+                }
+            }
+        }else {
+            if(isset($savereturn) && $savereturn == 'failed') {
+                echo '<p align="center"><b><font color="red">'.get_string('saving_failed','feedback').'</font></b></p>';
+            }
+    
+            if(isset($savereturn) && $savereturn == 'missing') {
+                echo '<p align="center"><b><font color="red">'.get_string('saving_failed_because_missing_or_false_values','feedback').'</font></b></p>';
+            }
+    
+            //print the items
+            if(is_array($feedbackitems)){
+                // print_simple_box_start('center', '75%');
+                print_box_start('generalbox boxaligncenter boxwidthwide');
+                echo '<div align="center"><form name="frm" action="'.$ME.'" method="post" onsubmit=" ">';
+                echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+                echo '<table>';
+                switch ($feedback->anonymous) {
+                    case FEEDBACK_ANONYMOUS_YES:
+                        echo '<tr><th colspan="3" align="center"><input type="hidden" name="anonymous" value="1" /><input type="hidden" name="anonymous_response" value="'.FEEDBACK_ANONYMOUS_YES.'" />'.get_string('mode', 'feedback').': '.get_string('anonymous', 'feedback').'</th></tr>'; //arb
+                        break;
+                    case FEEDBACK_ANONYMOUS_NO:
+                        echo '<tr><th colspan="3" align="center"><input type="hidden" name="anonymous" value="0" /><input type="hidden" name="anonymous_response" value="'.FEEDBACK_ANONYMOUS_NO.'" />'.get_string('mode', 'feedback').': '.get_string('non_anonymous', 'feedback').'&nbsp;</td></tr>'; //arb
+                        break;
+                }
+                //check, if there exists required-elements
+                $countreq = count_records('feedback_item', 'feedback', $feedback->id, 'required', 1);
+                if($countreq > 0) {
+                    echo '<tr><td colspan="3"><font color="red">(*)' . get_string('items_are_required', 'feedback') . '</font></td></tr>';
+                }
+                
+                unset($startitem);
+                $itemnr = count_records_select('feedback_item', 'feedback = '. $feedback->id . ' AND hasvalue = 1 AND position < '.$startposition);
+                foreach($feedbackitems as $feedbackitem){
+                    if(!isset($startitem)) {
+                        //avoid showing double pagebreaks
+                        if($feedbackitem->typ == 'pagebreak') continue;
+                        $startitem = $feedbackitem;
+                    }
+                    $value = '';
+                    //get the value
+                    $frmvaluename = $feedbackitem->typ . '_'. $feedbackitem->id;
+                    if(isset($savereturn)) {
+                        $value =  isset($formdata->{$frmvaluename})?$formdata->{$frmvaluename}:NULL;
+                    }else {
+                        if(isset($feedbackcompletedtmp->id)) {
+                            $value = feedback_get_item_value($feedbackcompletedtmp->id, $feedbackitem->id, true);
+                        }
+                    }
+                    echo '<tr>';
+                    if($feedbackitem->hasvalue == 1) {
+                        $itemnr++;
+                        echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+                    } else {
+                        echo '<td>&nbsp;</td>';
+                    }
+                    if($feedbackitem->typ != 'pagebreak') {
+                        feedback_print_item($feedbackitem, $value, false, false, $highlightrequired);
+                    }
+                    echo '</tr>';
+                    echo '<tr><td>&nbsp;</td></tr>';
+                    
+                    $lastbreakposition = $feedbackitem->position; //last item-pos (item or pagebreak)
+                    if($feedbackitem->typ == 'pagebreak'){
+                        break;
+                    }else {
+                        $lastitem = $feedbackitem;
+                    }
+                }
+                echo '</table>';
+                echo '<input type="hidden" name="id" value="'.$id.'" />';
+                echo '<input type="hidden" name="feedbackid" value="'.$feedback->id.'" />';
+                echo '<input type="hidden" name="lastpage" value="'.$gopage.'" />';
+                echo '<input type="hidden" name="completedid" value="'.(isset($feedbackcompletedtmp->id)?$feedbackcompletedtmp->id:'').'" />';
+                echo '<input type="hidden" name="courseid" value="'. $courseid . '" />';
+                echo '<input type="hidden" name="preservevalues" value="1" />';
+                if(isset($startitem)) {
+                    echo '<input type="hidden" name="startitempos" value="'. $startitem->position . '" />';
+                    echo '<input type="hidden" name="lastitempos" value="'. $lastitem->position . '" />';
+                }
+                
+                if( $ispagebreak AND $lastbreakposition > $firstpagebreak->position) {
+                    echo '<input name="gopreviouspage" type="submit" value="'.get_string('previous_page','feedback').'" />';
+                }
+                if($lastbreakposition < $maxitemcount){
+                    echo '<input name="gonextpage" type="submit" value="'.get_string('next_page','feedback').'" />';
+                }
+                if($lastbreakposition >= $maxitemcount) { //last page
+                    echo '<input name="savevalues" type="submit" value="'.get_string('save_entries','feedback').'" />';
+                }
+                
+                echo '</form>';
+                
+                    if($courseid) {
+                        echo '<form name="frm" action="'.$CFG->wwwroot.'/course/view.php?id='.$courseid.'" method="post" onsubmit=" ">';
+                    }else{
+                        if($course->id == SITEID) {
+                            echo '<form name="frm" action="'.$CFG->wwwroot.'" method="post" onsubmit=" ">';
+                        } else {
+                            echo '<form name="frm" action="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'" method="post" onsubmit=" ">';
+                        }
+                    }
+                echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+                echo '<input type="hidden" name="courseid" value="'. $courseid . '" />';
+                echo '<button type="submit">'.get_string('cancel').'</button>';
+                echo '</form>';
+                echo '</div>';
+                $SESSION->feedback->is_started = true;
+                // print_simple_box_end();
+                print_box_end();
+            }
+        }
+    }else {
+        // print_simple_box_start('center');
+        print_box_start('generalbox boxaligncenter');
+            echo '<h2><font color="red">'.get_string('this_feedback_is_already_submitted', 'feedback').'</font></h2>';
+            print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+        // print_simple_box_end();
+        print_box_end();
+    }
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/complete_guest.php b/mod/feedback/complete_guest.php
new file mode 100644 (file)
index 0000000..a69a7ce
--- /dev/null
@@ -0,0 +1,379 @@
+<?php // $Id$
+/**
+* prints the form so an anonymous user can fill out the feedback on the mainsite
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    $id = required_param('id', PARAM_INT);
+    $completedid = optional_param('completedid', false, PARAM_INT);
+    $preservevalues  = optional_param('preservevalues', 0,  PARAM_INT);
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    $gopage = optional_param('gopage', -1, PARAM_INT);
+    $lastpage = optional_param('lastpage', false, PARAM_INT);
+    $startitempos = optional_param('startitempos', 0, PARAM_INT);
+    $lastitempos = optional_param('lastitempos', 0, PARAM_INT);
+
+    $highlightrequired = false;
+
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    //if the use hit enter into a textfield so the form should not submit
+    if(isset($formdata->sesskey) AND !isset($formdata->savevalues) AND !isset($formdata->gonextpage) AND !isset($formdata->gopreviouspage)) {
+        $gopage = $formdata->lastpage;
+    }
+    if(isset($formdata->savevalues)) {
+        $savevalues = true;
+    }else {
+        $savevalues = false;
+    }
+    
+    if($gopage < 0 AND !$savevalues) {
+        if(isset($formdata->gonextpage)){
+            $gopage = $lastpage + 1;
+            $gonextpage = true;
+            $gopreviouspage = false;
+        }else if(isset($formdata->gopreviouspage)){
+            $gopage = $lastpage - 1;
+            $gonextpage = false;
+            $gopreviouspage = true;
+        }else {
+            error('parameter (gopage) required');
+        }
+    }else {
+        $gonextpage = $gopreviouspage = false;
+    }
+    
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+
+    $capabilities = feedback_load_capabilities($cm->id);
+    
+    //check whether the feedback is anonymous
+    if($feedback->anonymous == FEEDBACK_ANONYMOUS_YES) {
+        $capabilities->complete = true;
+    }else {
+        error(get_string('feedback_is_not_for_anonymous'));
+    }
+    
+    //check whether the user has a session
+    if(!isset($USER->sesskey) OR !$USER->sesskey) {
+        error('error');
+    }
+    
+    //check whether the feedback is located and! started from the mainsite
+    if($course->id == SITEID AND !$courseid) {
+        $courseid = SITEID;
+    }
+    
+    require_course_login($course);
+    
+    if($courseid AND $courseid != SITEID) {
+        $course2 = get_record('course', 'id', $courseid);
+        require_course_login($course2); //this overwrites the object $course :-(
+        $course = get_record("course", "id", $cm->course); // the workaround
+    }
+    
+    if(!$capabilities->complete) {
+        error(get_string('error'));
+    }
+
+    
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    //ishidden check. hidden feedbacks except feedbacks on mainsite are only accessible with related capabilities
+    if ((empty($cm->visible) and !$capabilities->viewhiddenactivities) AND $course->id != SITEID) {
+        notice(get_string("activityiscurrentlyhidden"));
+    }
+
+    feedback_print_errors();
+  
+    //check, if the feedback is open (timeopen, timeclose)
+    $checktime = time();
+    if(($feedback->timeopen > $checktime) OR ($feedback->timeclose < $checktime AND $feedback->timeclose > 0)) {
+        // print_simple_box_start('center');
+        print_box_start('generalbox boxaligncenter');
+            echo '<h2><font color="red">'.get_string('feedback_is_not_open', 'feedback').'</font></h2>';
+            print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+        // print_simple_box_end();
+        print_box_end();
+        print_footer($course);
+        exit;
+    }
+    
+    //additional check for multiple-submit (prevent browsers back-button). the main-check is in view.php
+    $feedback_can_submit = true;
+    if($feedback->multiple_submit == 0 ) {
+        // if($multiple_count = get_record('feedback_tracking', 'userid', $USER->id, 'feedback', $feedback->id)) {
+        if(feedback_is_already_submitted($feedback->id, $courseid)) {
+            $feedback_can_submit = false;
+        }
+    }
+    if($feedback_can_submit) {
+        //preserving the items
+        if($preservevalues == 1){
+            if(!$SESSION->feedback->is_started == true)error('error', $CFG->wwwroot.'/course/view.php?id='.$course->id);
+            //check, if all required items have a value
+            if(feedback_check_values($_POST, $startitempos, $lastitempos)) {
+                $userid = $USER->id; //arb
+                if($completedid = feedback_save_guest_values($_POST, $USER->sesskey)){
+                    add_to_log($course->id, "feedback", "startcomplete", "view.php?id=$cm->id", "$feedback->name"); //arb: log even guest submissions or at least the startcomplete since the other add log event is elsewhere
+                    
+                    if(!$gonextpage AND !$gopreviouspage) $preservevalues = false;//es kann gespeichert werden
+                    
+                }else {
+                    $savereturn = 'failed';
+                    if(isset($lastpage)) {
+                        $gopage = $lastpage;
+                    }else {
+                        error('parameter failed');
+                    }
+                }
+            }else {
+                $savereturn = 'missing';
+                $highlightrequired = true;
+                if(isset($lastpage)) {
+                    $gopage = $lastpage;
+                }else {
+                    error('parameter failed');
+                }
+            }
+        }
+        
+        //saving the items
+        if($savevalues AND !$preservevalues){
+            //exists there any pagebreak, so there are values in the feedback_valuetmp
+            $userid = $USER->id; //arb changed from 0 to $USER->id - no strict anonymous feedbacks - if it is a guest taking it then I want to know that it was a guest (at least in the data saved in the feedback tables)
+
+            $feedbackcompletedtmp = get_record('feedback_completedtmp', 'id', $completedid);
+            
+            //fake saving for switchrole
+            $is_switchrole = feedback_check_is_switchrole();
+            if($is_switchrole) {
+                $savereturn = 'saved';
+                feedback_delete_completedtmp($completedid);
+            }else if($new_completed_id = feedback_save_tmp_values($feedbackcompletedtmp, false, $userid)) {
+                $savereturn = 'saved';
+                feedback_email_teachers_anonym($cm, $feedback, $course, $userid);
+                unset($SESSION->feedback->is_started);
+                
+            }else {
+                $savereturn = 'failed';
+            }
+        }
+
+
+        if($allbreaks = feedback_get_all_break_positions($feedback->id)){
+            if($gopage <= 0) {
+                $startposition = 0;
+            }else {
+                $startposition = $allbreaks[$gopage - 1];
+            }
+            $ispagebreak = true;
+        }else {
+            $startposition = 0;
+            $newpage = 0;
+            $ispagebreak = false;
+        }
+        
+        //get the feedbackitems after the last shown pagebreak
+        $feedbackitems = get_records_select('feedback_item', 'feedback = '.$feedback->id.' AND position > '.$startposition, 'position');
+        //get the first pagebreak
+        if($pagebreaks = get_records_select('feedback_item', "feedback = ".$feedback->id." AND typ = 'pagebreak'", 'position')) {
+            $pagebreaks = array_values($pagebreaks);
+            $firstpagebreak = $pagebreaks[0];
+        }else {
+            $firstpagebreak = false;
+        }
+        $maxitemcount = count_records('feedback_item', 'feedback', $feedback->id);
+        $feedbackcompletedtmp = feedback_get_current_completed($feedback->id, true, $courseid, $USER->sesskey);
+
+        /// Print the main part of the page
+        ///////////////////////////////////////////////////////////////////////////
+        ///////////////////////////////////////////////////////////////////////////
+        ///////////////////////////////////////////////////////////////////////////
+        print_heading(format_text($feedback->name));
+        
+        if(isset($savereturn) && $savereturn == 'saved') {
+            if($feedback->page_after_submit) {
+                // print_simple_box_start('center', '75%');
+                print_box_start('generalbox boxaligncenter boxwidthwide');
+                echo format_text(stripslashes_safe($feedback->page_after_submit));
+                // print_simple_box_end();
+                print_box_end();
+            } else {
+                echo '<p align="center"><b><font color="green">'.get_string('entries_saved','feedback').'</font></b></p>';
+                if( intval($feedback->publish_stats) == 1) {
+                    echo '<p align="center"><a href="analysis.php?id=' . $id . '&courseid='.$courseid.'">';
+                    echo get_string('completed_feedbacks', 'feedback').'</a>';
+                    echo '</p>';
+                }
+            }
+            if($courseid) {
+                if($courseid == SITEID) {
+                    print_continue($CFG->wwwroot);
+                }else {
+                    print_continue($CFG->wwwroot.'/course/view.php?id='.$courseid);
+                }
+            }else {
+                if($course->id == SITEID) {
+                    print_continue($CFG->wwwroot);
+                } else {
+                    print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+                }
+            }
+        }else {
+            if(isset($savereturn) && $savereturn == 'failed') {
+                echo '<p align="center"><b><font color="red">'.get_string('saving_failed','feedback').'</font></b></p>';
+            }
+    
+            if(isset($savereturn) && $savereturn == 'missing') {
+                echo '<p align="center"><b><font color="red">'.get_string('saving_failed_because_missing_or_false_values','feedback').'</font></b></p>';
+            }
+    
+            //print the items
+            if(is_array($feedbackitems)){
+                // print_simple_box_start('center', '75%');
+                print_box_start('generalbox boxaligncenter boxwidthwide');
+                echo '<div align="center"><form name="frm" action="'.$ME.'" method="post" onsubmit=" ">';
+                echo '<table>';
+                echo '<tr><td colspan="3" align="center">
+                        <input type="hidden" name="anonymous" value="0" />
+                        <input type="hidden" name="anonymous_response" value="'.FEEDBACK_ANONYMOUS_YES.'" />
+                        &nbsp;
+                      </td></tr>';
+                //check, if there exists required-elements
+                $countreq = count_records('feedback_item', 'feedback', $feedback->id, 'required', 1);
+                if($countreq > 0) {
+                    echo '<tr><td colspan="3"><font color="red">(*)' . get_string('items_are_required', 'feedback') . '</font></td></tr>';
+                }
+                
+                unset($startitem);
+                $itemnr = count_records_select('feedback_item', 'feedback = '. $feedback->id . ' AND hasvalue = 1 AND position < '.$startposition);
+                foreach($feedbackitems as $feedbackitem){
+                    if(!isset($startitem)) {
+                        //avoid showing double pagebreaks
+                        if($feedbackitem->typ == 'pagebreak') continue;
+                        $startitem = $feedbackitem;
+                    }
+                    $value = '';
+                    //get the value
+                    $frmvaluename = $feedbackitem->typ . '_'. $feedbackitem->id;
+                    if(isset($savereturn)) {
+                        $value =  isset($formdata->{$frmvaluename})?$formdata->{$frmvaluename}:NULL;
+                    }else {
+                        if(isset($feedbackcompletedtmp->id)) {
+                            $value = feedback_get_item_value($feedbackcompletedtmp->id, $feedbackitem->id, $USER->sesskey);
+                        }
+                    }
+                    echo '<tr>';
+                    if($feedbackitem->hasvalue == 1) {
+                        $itemnr++;
+                        echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+                    } else {
+                        echo '<td>&nbsp;</td>';
+                    }
+                    if($feedbackitem->typ != 'pagebreak') {
+                        feedback_print_item($feedbackitem, $value, false, false, $highlightrequired);
+                    }
+                    echo '</tr>';
+                    echo '<tr><td>&nbsp;</td></tr>';
+                    
+                    $lastbreakposition = $feedbackitem->position; //last item-pos (item or pagebreak)
+                    if($feedbackitem->typ == 'pagebreak'){
+                        break;
+                    }else {
+                        $lastitem = $feedbackitem;
+                    }
+                }
+                echo '</table>';
+                echo '<input type="hidden" name="id" value="'.$id.'" />';
+                echo '<input type="hidden" name="feedbackid" value="'.$feedback->id.'" />';
+                echo '<input type="hidden" name="lastpage" value="'.$gopage.'" />';
+                echo '<input type="hidden" name="completedid" value="'.(isset($feedbackcompletedtmp->id)?$feedbackcompletedtmp->id:'').'" />';
+                echo '<input type="hidden" name="courseid" value="'. $courseid . '" />';
+                echo '<input type="hidden" name="preservevalues" value="1" />';
+                if(isset($startitem)) {
+                    echo '<input type="hidden" name="startitempos" value="'. $startitem->position . '" />';
+                    echo '<input type="hidden" name="lastitempos" value="'. $lastitem->position . '" />';
+                }
+                
+                if($ispagebreak AND $lastbreakposition > $firstpagebreak->position) {
+                    echo '<input name="gopreviouspage" type="submit" value="'.get_string('previous_page','feedback').'" />';
+                }
+                if($lastbreakposition < $maxitemcount){
+                    echo '<input name="gonextpage" type="submit" value="'.get_string('next_page','feedback').'" />';
+                }
+                if($lastbreakposition >= $maxitemcount) { //last page
+                    echo '<input name="savevalues" type="submit" value="'.get_string('save_entries','feedback').'" />';
+                }
+                
+                echo '</form>';
+                
+                if($courseid) {
+                    echo '<form name="frm" action="'.$CFG->wwwroot.'/course/view.php?id='.$courseid.'" method="post" onsubmit=" ">';
+                }else{
+                    if($course->id == SITEID) {
+                        echo '<form name="frm" action="'.$CFG->wwwroot.'" method="post" onsubmit=" ">';
+                    } else {
+                        echo '<form name="frm" action="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'" method="post" onsubmit=" ">';
+                    }
+                }
+                echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+                echo '<input type="hidden" name="courseid" value="'. $courseid . '" />';
+                echo '<button type="submit">'.get_string('cancel').'</button>';
+                echo '</form>';
+                echo '</div>';
+                $SESSION->feedback->is_started = true;
+                // print_simple_box_end();
+                print_box_end();
+            }
+        }
+    }else {
+        // print_simple_box_start('center');
+        print_box_start('generalbox boxaligncenter');
+            echo '<h2><font color="red">'.get_string('this_feedback_is_already_submitted', 'feedback').'</font></h2>';
+            print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+        // print_simple_box_end();
+        print_box_end();
+    }
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/db/access.php b/mod/feedback/db/access.php
new file mode 100644 (file)
index 0000000..ec726d2
--- /dev/null
@@ -0,0 +1,144 @@
+<?php
+//
+// Capability definitions for the feedback module.
+//
+// The capabilities are loaded into the database table when the module is
+// installed or updated. Whenever the capability definitions are updated,
+// the module version number should be bumped up.
+//
+// The system has four possible values for a capability:
+// CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT, and inherit (not set).
+//
+//
+// CAPABILITY NAMING CONVENTION
+//
+// It is important that capability names are unique. The naming convention
+// for capabilities that are specific to modules and blocks is as follows:
+//   [mod/block]/<component_name>:<capabilityname>
+//
+// component_name should be the same as the directory name of the mod or block.
+//
+// Core moodle capabilities are defined thus:
+//    moodle/<capabilityclass>:<capabilityname>
+//
+// Examples: mod/forum:viewpost
+//           block/recent_activity:view
+//           moodle/site:deleteuser
+//
+// The variable name for the capability definitions array follows the format
+//   $<componenttype>_<component_name>_capabilities
+//
+// For the core capabilities, the variable is $moodle_capabilities.
+
+
+$mod_feedback_capabilities = array(
+
+    'mod/feedback:view' => array(
+
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'guest' => CAP_ALLOW,
+            'user' => CAP_ALLOW,
+            'student' => CAP_ALLOW,
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+    
+    'mod/feedback:complete' => array(
+
+        'riskbitmask' => RISK_SPAM | RISK_XSS,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'user' => CAP_ALLOW,
+            'student' => CAP_ALLOW,
+            'editingteacher' => CAP_PREVENT,
+            'admin' => CAP_PREVENT
+        )
+    ),
+    
+    'mod/feedback:deletesubmissions' => array(
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+    'mod/feedback:mapcourse' => array(
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+    'mod/feedback:edititems' => array(
+
+        'riskbitmask' => RISK_SPAM | RISK_XSS,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+    'mod/feedback:createprivatetemplate' => array(
+
+        'riskbitmask' => RISK_SPAM,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+    'mod/feedback:createpublictemplate' => array(
+
+        'riskbitmask' => RISK_SPAM,
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+    'mod/feedback:deletetemplate' => array(
+
+        'captype' => 'write',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+    'mod/feedback:viewreports' => array(
+    
+        'riskbitmask' => RISK_PERSONAL,
+
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_MODULE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        )
+    ),
+
+);
+
+?>
diff --git a/mod/feedback/db/install.xml b/mod/feedback/db/install.xml
new file mode 100644 (file)
index 0000000..c9e9837
--- /dev/null
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<XMLDB PATH="mod/feedback/db" VERSION="20070101" COMMENT="XMLDB file for Moodle mod/feedback">
+  <TABLES>
+    <TABLE NAME="feedback" COMMENT="all feedbacks" NEXT="feedback_template">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course"/>
+        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="summary"/>
+        <FIELD NAME="summary" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="anonymous"/>
+        <FIELD NAME="anonymous" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="summary" NEXT="email_notification"/>
+        <FIELD NAME="email_notification" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="anonymous" NEXT="multiple_submit"/>
+        <FIELD NAME="multiple_submit" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="email_notification" NEXT="page_after_submit"/>
+        <FIELD NAME="page_after_submit" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="multiple_submit" NEXT="publish_stats"/>
+        <FIELD NAME="publish_stats" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="page_after_submit" NEXT="timeopen"/>
+        <FIELD NAME="timeopen" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="publish_stats" NEXT="timeclose"/>
+        <FIELD NAME="timeclose" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timeopen" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timeclose"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_template" COMMENT="templates of feedbackstructures" PREVIOUS="feedback" NEXT="feedback_item">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course"/>
+        <FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="ispublic"/>
+        <FIELD NAME="ispublic" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="ispublic"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_template"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_item" COMMENT="feedback_items" PREVIOUS="feedback_template" NEXT="feedback_completed">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="feedback"/>
+        <FIELD NAME="feedback" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="template"/>
+        <FIELD NAME="template" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="feedback" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="template" NEXT="presentation"/>
+        <FIELD NAME="presentation" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="typ"/>
+        <FIELD NAME="typ" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="presentation" NEXT="hasvalue"/>
+        <FIELD NAME="hasvalue" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="typ" NEXT="position"/>
+        <FIELD NAME="position" TYPE="int" LENGTH="3" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="hasvalue" NEXT="required"/>
+        <FIELD NAME="required" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="position"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_item" NEXT="feedback"/>
+        <KEY NAME="feedback" TYPE="foreign" FIELDS="feedback" REFTABLE="feedback" REFFIELDS="id" PREVIOUS="primary" NEXT="template"/>
+        <KEY NAME="template" TYPE="foreign" FIELDS="template" REFTABLE="feedback_template" REFFIELDS="id" PREVIOUS="feedback"/>
+      </KEYS>
+    </TABLE>
+    <TABLE NAME="feedback_completed" COMMENT="filled out feedback" PREVIOUS="feedback_item" NEXT="feedback_completedtmp">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="feedback"/>
+        <FIELD NAME="feedback" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="feedback" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="random_response"/>
+        <FIELD NAME="random_response" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timemodified" NEXT="anonymous_response"/>
+        <FIELD NAME="anonymous_response" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="random_response"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_completed" NEXT="feedback"/>
+        <KEY NAME="feedback" TYPE="foreign" FIELDS="feedback" REFTABLE="feedback" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_completedtmp" COMMENT="filled out feedback" PREVIOUS="feedback_completed" NEXT="feedback_value">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="feedback"/>
+        <FIELD NAME="feedback" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="feedback" NEXT="guestid"/>
+        <FIELD NAME="guestid" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="guestid" NEXT="random_response"/>
+        <FIELD NAME="random_response" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="timemodified" NEXT="anonymous_response"/>
+        <FIELD NAME="anonymous_response" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="random_response"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_completedtmp" NEXT="feedback"/>
+        <KEY NAME="feedback" TYPE="foreign" FIELDS="feedback" REFTABLE="feedback" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_value" COMMENT="values of the completeds" PREVIOUS="feedback_completedtmp" NEXT="feedback_valuetmp">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course_id"/>
+        <FIELD NAME="course_id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="item"/>
+        <FIELD NAME="item" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="course_id" NEXT="completed"/>
+        <FIELD NAME="completed" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="item" NEXT="tmp_completed"/>
+        <FIELD NAME="tmp_completed" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="completed" NEXT="value"/>
+        <FIELD NAME="value" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="tmp_completed"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_value" NEXT="item"/>
+        <KEY NAME="item" TYPE="foreign" FIELDS="item" REFTABLE="feedback_item" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="course_id" UNIQUE="false" FIELDS="course_id"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_valuetmp" COMMENT="values of the completedstmp" PREVIOUS="feedback_value" NEXT="feedback_tracking">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course_id"/>
+        <FIELD NAME="course_id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="item"/>
+        <FIELD NAME="item" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="course_id" NEXT="completed"/>
+        <FIELD NAME="completed" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="item" NEXT="tmp_completed"/>
+        <FIELD NAME="tmp_completed" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="completed" NEXT="value"/>
+        <FIELD NAME="value" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="tmp_completed"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_valuetmp" NEXT="item"/>
+        <KEY NAME="item" TYPE="foreign" FIELDS="item" REFTABLE="feedback_item" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="course_id" UNIQUE="false" FIELDS="course_id"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_tracking" COMMENT="feedback trackingdata" PREVIOUS="feedback_valuetmp" NEXT="feedback_sitecourse_map">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="feedback"/>
+        <FIELD NAME="feedback" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="completed"/>
+        <FIELD NAME="completed" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="feedback" NEXT="tmp_completed"/>
+        <FIELD NAME="tmp_completed" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="completed" NEXT="count"/>
+        <FIELD NAME="count" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="tmp_completed"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_tracking" NEXT="feedback"/>
+        <KEY NAME="feedback" TYPE="foreign" FIELDS="feedback" REFTABLE="feedback" REFFIELDS="id" PREVIOUS="primary" NEXT="completed"/>
+        <KEY NAME="completed" TYPE="foreign" FIELDS="completed" REFTABLE="feedback_completed" REFFIELDS="id" PREVIOUS="feedback"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="feedback_sitecourse_map" COMMENT="feedback sitecourse map" PREVIOUS="feedback_tracking">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="feedbackid"/>
+        <FIELD NAME="feedbackid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="feedbackid"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for feedback_tracking" NEXT="feedbackid"/>
+        <KEY NAME="feedbackid" TYPE="foreign" FIELDS="feedbackid" REFTABLE="feedback" REFFIELDS="id" PREVIOUS="primary"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="courseid" UNIQUE="false" FIELDS="courseid"/>
+      </INDEXES>
+    </TABLE>
+  </TABLES>
+</XMLDB>
diff --git a/mod/feedback/db/upgrade.php b/mod/feedback/db/upgrade.php
new file mode 100644 (file)
index 0000000..e8c2c8b
--- /dev/null
@@ -0,0 +1,157 @@
+<?php  //$Id$
+
+// This file keeps track of upgrades to 
+// the feedback module
+//
+// Sometimes, changes between versions involve
+// alterations to database structures and other
+// major things that may break installations.
+//
+// The upgrade function in this file will attempt
+// to perform all the necessary actions to upgrade
+// your older installtion to the current version.
+//
+// If there's something it cannot do itself, it
+// will tell you what you need to do.
+//
+// The commands in here will all be database-neutral,
+// using the functions defined in lib/ddllib.php
+
+function xmldb_feedback_upgrade($oldversion=0) {
+
+    global $CFG, $THEME, $db;
+
+    $result = true;
+
+    if ($result && $oldversion < 2007012310) {
+
+        //create a new table feedback_completedtmp and the field-definition
+        $table = new XMLDBTable('feedback_completedtmp');
+
+        $field = new XMLDBField('id');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, true, null, null, null, null);
+        $table->addField($field);
+        
+        $field = new XMLDBField('feedback');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+        
+        $field = new XMLDBField('userid');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+
+        $field = new XMLDBField('guestid');
+        $field->setAttributes(XMLDB_TYPE_CHAR, '255', null, null, false, null, null, '', null);
+        $table->addField($field);
+
+        $field = new XMLDBField('timemodified');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+        
+        $key = new XMLDBKey('PRIMARY');
+        $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
+        $table->addKey($key);
+        
+        $key = new XMLDBKey('feedback');
+        $key->setAttributes(XMLDB_KEY_FOREIGN, array('feedback'), 'feedback', 'id');
+        $table->addKey($key);
+
+        $result = $result && create_table($table);
+        ////////////////////////////////////////////////////////////
+        ////////////////////////////////////////////////////////////
+        //create a new table feedback_valuetmp and the field-definition
+        $table = new XMLDBTable('feedback_valuetmp');
+
+        $field = new XMLDBField('id');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, true, null, null, null, null);
+        $table->addField($field);
+        
+        $field = new XMLDBField('course_id');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+        
+        $field = new XMLDBField('item');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+        
+        $field = new XMLDBField('completed');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+        
+        $field = new XMLDBField('tmp_completed');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        $table->addField($field);
+
+        $field = new XMLDBField('value');
+        $field->setAttributes(XMLDB_TYPE_TEXT, null, null, null, false, null, null, '', null);
+        $table->addField($field);
+        
+        $key = new XMLDBKey('PRIMARY');
+        $key->setAttributes(XMLDB_KEY_PRIMARY, array('id'));
+        $table->addKey($key);
+        
+        $key = new XMLDBKey('feedback');
+        $key->setAttributes(XMLDB_KEY_FOREIGN, array('item'), 'feedback_item', 'id');
+        $table->addKey($key);
+
+        $result = $result && create_table($table);
+        ////////////////////////////////////////////////////////////
+    }
+
+    if ($result && $oldversion < 2007050504) {
+
+        /// Define field random_response to be added to feedback_completed
+        $table = new XMLDBTable('feedback_completed');
+        $field = new XMLDBField('random_response');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        /// Launch add field1
+        $result = $result && add_field($table, $field);
+
+        /// Define field anonymous_response to be added to feedback_completed
+        $table = new XMLDBTable('feedback_completed');
+        $field = new XMLDBField('anonymous_response');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '1', null);
+        /// Launch add field2
+        $result = $result && add_field($table, $field);
+
+        /// Define field random_response to be added to feedback_completed
+        $table = new XMLDBTable('feedback_completedtmp');
+        $field = new XMLDBField('random_response');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '0', null);
+        /// Launch add field1
+        $result = $result && add_field($table, $field);
+
+        /// Define field anonymous_response to be added to feedback_completed
+        $table = new XMLDBTable('feedback_completedtmp');
+        $field = new XMLDBField('anonymous_response');
+        $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, false, null, null, '1', null);
+        /// Launch add field2
+        $result = $result && add_field($table, $field);
+
+        ////////////////////////////////////////////////////////////
+    }
+
+    if ($result && $oldversion < 2007102600) {
+        // public is a reserved word on Oracle
+
+        $table = new XMLDBTable('feedback_template');
+        $field = new XMLDBField('ispublic');
+        if (!field_exists($table, $field)) {
+            $result = $result && table_column('feedback_template', 'public', 'ispublic', 'integer', 1);
+        }
+    }
+
+
+/// And upgrade begins here. For each one, you'll need one 
+/// block of code similar to the next one. Please, delete 
+/// this comment lines once this file start handling proper
+/// upgrade code.
+
+/// if ($result && $oldversion < YYYYMMDD00) { //New version in version.php
+///      $result = result of "/lib/ddllib.php" function calls
+/// }
+
+    return $result;
+}
+
+?>
diff --git a/mod/feedback/delete_completed.php b/mod/feedback/delete_completed.php
new file mode 100644 (file)
index 0000000..79ebcc0
--- /dev/null
@@ -0,0 +1,92 @@
+<?php // $Id$
+/**
+* prints the form to confirm the deleting of a completed
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once('delete_completed_form.php');
+
+    $id = required_param('id', PARAM_INT);
+    $completedid = optional_param('completedid', 0, PARAM_INT);
+
+    if($completedid == 0){
+        error(get_string('no_complete_to_delete', 'feedback'), 'show_entries.php?id='.$id.'&do_show=showentries');
+    }
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->deletesubmissions){
+        error(get_string('error'));
+    }
+    
+    $mform = new mod_feedback_delete_completed_form();
+    $newformdata = array('id'=>$id,
+                        'completedid'=>$completedid,
+                        'confirmdelete'=>'1',
+                        'do_show'=>'edit');
+    $mform->set_data($newformdata);
+    $formdata = $mform->get_data();
+    
+    if ($mform->is_cancelled()) {
+        redirect('show_entries.php?id='.$id.'&do_show=showentries');
+    }
+    
+    if(isset($formdata->confirmdelete) AND $formdata->confirmdelete == 1){
+        if($completed = get_record('feedback_completed', 'id', $completedid)) {
+            feedback_delete_completed($completedid);
+            add_to_log($course->id, "feedback", "delete", "view.php?id=$cm->id", "$feedback->name",$cm->id);
+            redirect('show_entries.php?id='.$id.'&do_show=showentries');
+        }
+    }
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(format_text($feedback->name));
+    // print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox");
+    print_box_start('generalbox errorboxcontent boxaligncenter boxwidthnormal');
+    print_heading(get_string('confirmdeleteentry', 'feedback'));
+    $mform->display();
+    // print_simple_box_end();
+    print_box_end();
+        
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/delete_completed_form.php b/mod/feedback/delete_completed_form.php
new file mode 100644 (file)
index 0000000..c79397e
--- /dev/null
@@ -0,0 +1,32 @@
+<?php // $Id$
+/**
+* prints the form to confirm delete a completed
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once $CFG->libdir.'/formslib.php';
+
+class mod_feedback_delete_completed_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        //headline
+        //$mform->addElement('header', 'general', '');
+        
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'completedid');
+        $mform->addElement('hidden', 'do_show');
+        $mform->addElement('hidden', 'confirmdelete');
+
+        //-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons(true, get_string('yes'));
+
+    }
+}
+?>
diff --git a/mod/feedback/delete_item.php b/mod/feedback/delete_item.php
new file mode 100644 (file)
index 0000000..586829f
--- /dev/null
@@ -0,0 +1,85 @@
+<?php // $Id$
+/**
+* deletes an item of the feedback
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+    
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once('delete_item_form.php');
+
+    $id = required_param('id', PARAM_INT);
+    $deleteitem = required_param('deleteitem', PARAM_INT);
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error(get_string('error'));
+    }
+                
+    $mform = new mod_feedback_delete_item_form();
+    $newformdata = array('id'=>$id,
+                        'deleteitem'=>$deleteitem,
+                        'confirmdelete'=>'1');
+    $mform->set_data($newformdata);
+    $formdata = $mform->get_data();
+    
+    if ($mform->is_cancelled()) {
+        redirect('edit.php?id='.$id);
+    }
+    
+    if(isset($formdata->confirmdelete) AND $formdata->confirmdelete == 1){
+        feedback_delete_item($formdata->deleteitem);
+        redirect('edit.php?id=' . $id);
+    }
+
+    
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(format_text($feedback->name));
+    // print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox");
+    print_box_start('generalbox errorboxcontent boxaligncenter boxwidthnormal');
+    print_heading(get_string('confirmdeleteitem', 'feedback'));
+    print_string('relateditemsdeleted','feedback');
+    $mform->display();
+    // print_simple_box_end();
+    print_box_end();
+        
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/delete_item_form.php b/mod/feedback/delete_item_form.php
new file mode 100644 (file)
index 0000000..b4eaab5
--- /dev/null
@@ -0,0 +1,31 @@
+<?php // $Id$
+/**
+* prints the form to confirm delete a completed
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once $CFG->libdir.'/formslib.php';
+
+class mod_feedback_delete_item_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        //headline
+        //$mform->addElement('header', 'general', '');
+        
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'deleteitem');
+        $mform->addElement('hidden', 'confirmdelete');
+
+        //-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons(true, get_string('yes'));
+
+    }
+}
+?>
diff --git a/mod/feedback/delete_template.php b/mod/feedback/delete_template.php
new file mode 100644 (file)
index 0000000..c49f1dc
--- /dev/null
@@ -0,0 +1,132 @@
+<?php // $Id$
+/**
+* deletes a template
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once('delete_template_form.php');
+    
+    $SESSION->feedback->current_tab = 'templates';
+
+    $id = required_param('id', PARAM_INT);
+    $canceldelete = optional_param('canceldelete', false, PARAM_INT);
+    $shoulddelete = optional_param('shoulddelete', false, PARAM_INT);
+    $deletetempl = optional_param('deletetempl', false, PARAM_INT);
+    // $formdata = data_submitted('nomatch');
+    
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    if($canceldelete == 1){
+        redirect(htmlspecialchars('edit.php?id='.$id.'&do_show=templates'));
+    }
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->deletetemplate){
+        error(get_string('error'));
+    }
+    
+    $mform = new mod_feedback_delete_template_form();
+    $newformdata = array('id'=>$id,
+                        'deletetempl'=>$deletetempl,
+                        'confirmdelete'=>'1');
+    
+    $mform->set_data($newformdata);
+    $formdata = $mform->get_data();
+    
+    if ($mform->is_cancelled()) {
+        redirect(htmlspecialchars('delete_template.php?id='.$id));
+    }
+    
+    if(isset($formdata->confirmdelete) AND $formdata->confirmdelete == 1){
+        feedback_delete_template($formdata->deletetempl);
+        redirect(htmlspecialchars('delete_template.php?id=' . $id));
+    }
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(get_string('delete_template','feedback'));
+    if($shoulddelete == 1) {
+    
+        // print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox");
+        print_box_start('generalbox errorboxcontent boxaligncenter boxwidthnormal');
+        print_heading(get_string('confirmdeletetemplate', 'feedback'));
+        $mform->display();
+        // print_simple_box_end();
+        print_box_end();
+    }else {
+        $templates = feedback_get_template_list($course, true);
+        echo '<div align="center">';
+        if(!is_array($templates)) {
+            // print_simple_box(get_string('no_templates_available_yet', 'feedback'), "center");
+            print_box(get_string('no_templates_available_yet', 'feedback'), 'generalbox boxaligncenter');
+        }else {
+            echo '<table width="30%">';
+            echo '<tr><th>'.get_string('templates', 'feedback').'</th><th>&nbsp;</th></tr>';
+            foreach($templates as $template) {
+                echo '<tr><td align="center">'.$template->name.'</td>';
+                echo '<td align="center">';
+                echo '<form action="'.$ME.'" method="post">';
+                echo '<input title="'.get_string('delete_template','feedback').'" type="image" src="'.$CFG->pixpath .'/t/delete.gif" hspace="1" height="11" width="11" border="0" />';
+                echo '<input type="hidden" name="deletetempl" value="'.$template->id.'" />';
+                echo '<input type="hidden" name="shoulddelete" value="1" />';
+                echo '<input type="hidden" name="id" value="'.$id.'" />';
+                echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+                echo '</form>';
+                echo '</td></tr>';
+            }
+            echo '</table>';
+        }
+?>
+        <form name="frm" action="<?php echo $ME;?>" method="post">
+            <input type="hidden" name="sesskey" value="<?php echo $USER->sesskey;?>" />
+            <input type="hidden" name="id" value="<?php echo $id;?>" />
+            <input type="hidden" name="canceldelete" value="0" />
+            <button type="button" onclick="this.form.canceldelete.value=1;this.form.submit();"><?php print_string('cancel');?></button>
+        </form>
+        </div>
+<?php
+    }
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/delete_template_form.php b/mod/feedback/delete_template_form.php
new file mode 100644 (file)
index 0000000..f37fe84
--- /dev/null
@@ -0,0 +1,31 @@
+<?php // $Id$
+/**
+* prints the form to confirm delete a completed
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once $CFG->libdir.'/formslib.php';
+
+class mod_feedback_delete_template_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        //headline
+        //$mform->addElement('header', 'general', '');
+        
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'deletetempl');
+        $mform->addElement('hidden', 'confirmdelete');
+
+        //-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons(true, get_string('yes'));
+
+    }
+}
+?>
diff --git a/mod/feedback/easy_excel.php b/mod/feedback/easy_excel.php
new file mode 100644 (file)
index 0000000..17472a4
--- /dev/null
@@ -0,0 +1,261 @@
+<?php // $Id$
+/**
+* makes it easier to use the spreadsheet-functions from pear
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once("../../config.php");
+require_once("lib.php");
+
+ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
+require_once 'Spreadsheet/Excel/Writer.php';
+
+class EasyWorkbook extends Spreadsheet_Excel_Writer {
+    function &addWorksheet($name = ''){
+        global $CFG;
+        
+        $index      = count($this->_worksheets);
+        $sheetname = $this->_sheetname;
+
+        if ($name == '') {
+            $name = $sheetname.($index+1);
+        }
+
+        // Check that sheetname is <= 31 chars (Excel limit before BIFF8).
+        if ($this->_BIFF_version != 0x0600)
+        {
+            if (strlen($name) > 31) {
+                return $this->raiseError("Sheetname $name must be <= 31 chars");
+            }
+        }
+
+        // Check that the worksheet name doesn't already exist: a fatal Excel error.
+        $total_worksheets = count($this->_worksheets);
+        for ($i = 0; $i < $total_worksheets; $i++) {
+            if ($this->_worksheets[$i]->getName() == $name) {
+                 return $this->raiseError("Worksheet '$name' already exists");
+            }
+        }
+
+        $worksheet =& new EasyWorksheet($this->_BIFF_version,
+                                          $name, $index,
+                                          $this->_activesheet, $this->_firstsheet,
+                                          $this->_str_total, $this->_str_unique,
+                                          $this->_str_table, $this->_url_format,
+                                          $this->_parser);
+
+        $this->_worksheets[$index] = &$worksheet;     // Store ref for iterator
+        $this->_sheetnames[$index] = $name;             // Store EXTERNSHEET names
+        $this->_parser->setExtSheet($name, $index);  // Register worksheet name with parser
+
+        if(!isset($CFG->latinexcelexport) || !$CFG->latinexcelexport) {
+            $worksheet->setInputEncoding('UTF-16LE');
+            // $worksheet->setInputEncoding('utf-8');
+        }
+        return $worksheet;
+    }
+}
+
+
+class EasyWorksheet extends Spreadsheet_Excel_Writer_Worksheet {
+    var $m_format;
+    var $m_formatbox = array();
+    var $m_workbook;
+
+    function set_workbook(&$workbook) {
+        $this->m_workbook =& $workbook;
+    }
+    
+    function write($row, $col, $token)
+    {
+        parent::write($row, $col, $token, $this->m_format);
+    }
+
+    function write_number($row, $col, $num)
+    {
+        parent::writeNumber($row, $col, $num, $this->m_format);
+    }
+
+    function write_string($row, $col, $str)
+    {
+        parent::writeString($row, $col, feedback_convert_to_win($str), $this->m_format);
+    }
+
+    function write_formula($row, $col, $formula)
+    {
+        parent::writeFormula($row, $col, $formula, $this->m_format);
+    }
+
+    function write_url($row, $col, $url, $string = '')
+    {
+        parent::writeUrl($row, $col, $url, $string, $this->m_format);
+    }
+
+    /** 
+     *  Setz das aktuelle Format, dass zum Schreiben verwendet wird
+     *  Der Formatstring setzt sich aus den folgenden Buchstaben mit folgender Bedeutung zusammen.
+     *  <f> = Fett
+     *  <k> = kursiv
+     *  <z> = zentriert
+     *  <l> = linksbündig
+     *  <r> = rechtsbündig
+     *  <vo> = vertikal oben
+     *  <vz> = vertikal zentriert
+     *  <vu> = vertikal unten
+     *  <uX> = unterstrichen X=1-einfach, X=2-doppelt
+     *  <w> = währungsformat
+     *  <pr> = prozentformat
+     *  <ruX> = Rahmen unten X=Stärke
+     *  <roX> = rahmen oben X=Stärke
+     *  <rrX> = rahmen rechts X=Stärke
+     *  <rlX> = rahmen links X=Stärke
+     *  <c:XXX> = Schriftfarbe, XXX kann einen der folgenden Farbwerte enthalten:
+     *      aqua,cyan,black,blue,brown,magenta,fuchsia,gray,
+     *      grey,green,lime,navy,orange,purple,red,silver,white,yellow
+     *      Wichtig: alle Werte müssen klein geschrieben werden.
+     *  @param string $formatString
+     *  @param int $size the size of font in pt
+     *  @param boolean $textWrap
+     *  @return void
+     */
+    function setFormat($formatString,$size = 10,$textWrap = true)
+    {
+        //looking for an existing format-signature at the $m_formatbox
+        //this prevents the overflow of formats
+        $signature = $formatString.'_'.$size.'_'.$textWrap;
+        if((count($this->m_formatbox) > 0) AND array_key_exists($signature, $this->m_formatbox)) {
+            $this->m_format = $this->m_formatbox[$signature];
+        }else {
+        
+            $this->m_format = &$this->m_workbook->addFormat();
+            if($textWrap)
+            {
+                $this->m_format->setTextWrap();
+            }
+
+            if(preg_match("/<f>/i",$formatString) > 0)
+            {
+                $this->m_format->setBold();
+            }
+
+            if(preg_match("/<k>/i",$formatString) > 0)
+            {
+                $this->m_format->setItalic();
+            }
+
+            if(preg_match("/<z>/i",$formatString) > 0)
+            {
+                $this->m_format->setAlign("center");
+            }
+
+            if(preg_match("/<l>/i",$formatString) > 0)
+            {
+                $this->m_format->setAlign("left");
+            }
+
+            if(preg_match("/<r>/i",$formatString) > 0)
+            {
+                $this->m_format->setAlign("right");
+            }
+
+            if(preg_match("/<vo>/i",$formatString) > 0)
+            {
+                $this->m_format->setAlign("top");
+            }
+
+            if(preg_match("/<vz>/i",$formatString) > 0)
+            {
+                $this->m_format->setAlign("vcenter");
+            }
+
+            if(preg_match("/<vu>/i",$formatString) > 0)
+            {
+                $this->m_format->setAlign("bottom");
+            }
+
+            if(preg_match("/<u\d>/i",$formatString,$treffer) > 0)
+            {
+                $this->m_format->setUnderline(substr($treffer[0],2,1));
+            }
+
+            if(preg_match("/<w>/i",$formatString) > 0)
+            {
+                $this->m_format->setNumFormat("#,##0.00_)\80;[Red]-#,##0.00_)\80");
+            }
+
+            if(preg_match("/<pr>/i",$formatString) > 0)
+            {
+                $this->m_format->setNumFormat("#,##0.00%");
+            }
+
+            if(preg_match("/<ru\d>/i",$formatString,$treffer) > 0)
+            {
+                $this->m_format->setBottom(substr($treffer[0],3,1));
+            }
+
+            if(preg_match("/<ro\d>/i",$formatString,$treffer) > 0)
+            {
+                $this->m_format->setTop(substr($treffer[0],3,1));
+            }
+
+            if(preg_match("/<rr\d>/i",$formatString,$treffer) > 0)
+            {
+                $this->m_format->setRight(substr($treffer[0],3,1));
+            }
+
+            if(preg_match("/<rl\d>/i",$formatString,$treffer) > 0)
+            {
+                $this->m_format->setLeft(substr($treffer[0],3,1));
+            }
+
+            if(preg_match("/<c\:[^>]+>/",$formatString,$treffer) > 0)
+            {
+                $len = strlen($treffer[0]) - 4; //abzueglich der Zeichen <c:>
+                $this->m_format->setColor(substr($treffer[0],3,$len));
+            }
+
+            $this->m_format->setSize($size);
+            
+            //save the format with its signature
+            $this->m_formatbox[$signature] = $this->m_format;
+        }
+    }
+}
+
+function feedback_convert_to_win($text) {
+    global $CFG;
+    static $textlib;
+    static $newwincharset;
+    static $oldcharset;
+    
+    if(!isset($textlib)) {
+        $textlib = textlib_get_instance();
+    }
+    
+    if(!isset($newwincharset)) {
+        if(!isset($CFG->latinexcelexport) || !$CFG->latinexcelexport) {
+            $newwincharset = get_string('UTF-16LE');
+        }else {
+            $newwincharset = get_string('localewincharset');
+            if($newwincharset == '') {
+                $newwincharset = 'windows-1252';
+            }
+        }
+    }
+    
+    if(!isset($oldcharset)) {
+        $oldcharset = get_string('thischarset');
+    }
+    
+    //converting <br /> into newline
+    $newtext = str_ireplace('<br />', "\n", $text);
+    $newtext = str_ireplace('<br>', "\n", $newtext);
+    
+    return $textlib->convert($newtext, $oldcharset, $newwincharset);
+}
+
+?>
diff --git a/mod/feedback/edit.php b/mod/feedback/edit.php
new file mode 100644 (file)
index 0000000..6e737a6
--- /dev/null
@@ -0,0 +1,419 @@
+<?php // $Id$
+/**
+* prints the form to edit the feedback items such moving, deleting and so on
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once('edit_form.php');
+
+    $id = required_param('id', PARAM_INT);
+
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    $do_show = optional_param('do_show', 'edit', PARAM_ALPHA);
+    $moveupitem = optional_param('moveupitem', false, PARAM_INT);
+    $movedownitem = optional_param('movedownitem', false, PARAM_INT);
+    $moveitem = optional_param('moveitem', false, PARAM_INT);
+    $movehere = optional_param('movehere', false, PARAM_INT);
+    $switchitemrequired = optional_param('switchitemrequired', false, PARAM_INT);
+    
+    // $SESSION->feedback->current_tab = $do_show;
+    $current_tab = $do_show;
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error(get_string('error'));
+    }
+
+    //move up/down items
+    if($moveupitem){
+        $item = get_record('feedback_item', 'id', $moveupitem);
+        feedback_moveup_item($item);
+    }
+    if($movedownitem){
+        $item = get_record('feedback_item', 'id', $movedownitem);
+        feedback_movedown_item($item);
+    }
+    
+    //moving of items
+    if($movehere && isset($SESSION->feedback->moving->movingitem)){
+        $item = get_record('feedback_item', 'id', intval($SESSION->feedback->moving->movingitem));
+        feedback_move_item($item, intval($movehere));
+    }
+    if($moveitem){
+        $item = get_record('feedback_item', 'id', $moveitem);
+        $SESSION->feedback->moving->shouldmoving = 1;
+        $SESSION->feedback->moving->movingitem = $moveitem;
+    } else {
+        unset($SESSION->feedback->moving);
+    }
+    
+    if($switchitemrequired) {
+        $item = get_record('feedback_item', 'id', $switchitemrequired);
+        @feedback_switch_item_required($item);
+        redirect($ME.'?'.feedback_edit_get_default_query($id, $do_show));
+        exit;
+    }
+    
+    //the create_template-form
+    $create_template_form = new feedback_edit_create_template_form();
+    $create_template_form->set_feedbackdata(array('capabilities' => $capabilities));
+    $create_template_form->set_form_elements();
+    $create_template_form->set_data(array('id'=>$id, 'do_show'=>'templates'));
+    $create_template_formdata = $create_template_form->get_data();
+    if(isset($create_template_formdata->savetemplate) && $create_template_formdata->savetemplate == 1) {
+        //check the capabilities to create templates
+        if(!$capabilities->createprivatetemplate AND !$capabilities->createpublictemplate) {
+            error('saving templates is not allowed');
+        }
+        if(trim($create_template_formdata->templatename) == '')
+        {
+            $savereturn = 'notsaved_name';
+        }else {
+            if($capabilities->createpublictemplate) {
+                $create_template_formdata->ispublic = isset($create_template_formdata->ispublic) ? 1 : 0;
+            }else {
+                $create_template_formdata->ispublic = 0;
+            }
+            if(!feedback_save_as_template($feedback, $create_template_formdata->templatename, $create_template_formdata->ispublic))
+            {
+                $savereturn = 'failed';
+            }else {
+                $savereturn = 'saved';
+            }
+        }
+    }
+
+    //get the feedbackitems
+    $lastposition = 0;
+    $feedbackitems = get_records('feedback_item', 'feedback', $feedback->id, 'position');
+    if(is_array($feedbackitems)){
+        $feedbackitems = array_values($feedbackitems);
+        $lastitem = $feedbackitems[count($feedbackitems)-1];
+        $lastposition = $lastitem->position;
+    }
+    $lastposition++;
+    
+    
+    //the add_item-form
+    $add_item_form = new feedback_edit_add_question_form('edit_item.php');
+    $add_item_form->set_data(array('id'=>$id, 'position'=>$lastposition));
+
+    //the use_template-form
+    $use_template_form = new feedback_edit_use_template_form('use_templ.php');
+    $use_template_form->set_feedbackdata(array('course' => $course));
+    $use_template_form->set_form_elements();
+    $use_template_form->set_data(array('id'=>$id));
+
+    //the create_template-form
+    //$create_template_form = new feedback_edit_create_template_form('use_templ.php');
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// print the tabs
+    include('tabs.php');
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+       
+    $savereturn=isset($savereturn)?$savereturn:'';
+         
+    //print the messages
+    if($savereturn == 'notsaved_name') {
+        echo '<p align="center"><b><font color="red">'.get_string('name_required','feedback').'</font></b></p>';
+    }
+
+    if($savereturn == 'saved') {
+        echo '<p align="center"><b><font color="green">'.get_string('template_saved','feedback').'</font></b></p>';
+    }
+    
+    if($savereturn == 'failed') {
+        echo '<p align="center"><b><font color="red">'.get_string('saving_failed','feedback').'</font></b></p>';
+    }
+
+    feedback_print_errors();
+    
+    ///////////////////////////////////////////////////////////////////////////
+    ///print the template-section
+    ///////////////////////////////////////////////////////////////////////////
+    if($do_show == 'templates') {
+        // print_simple_box_start("center", '80%');
+        print_box_start('generalbox boxaligncenter boxwidthwide');
+        $use_template_form->display();
+        
+        if($capabilities->createprivatetemplate OR $capabilities->createpublictemplate) {
+            $create_template_form->display();
+            echo '<p><a href="'.htmlspecialchars('delete_template.php?id='.$id).'">'.get_string('delete_templates', 'feedback').'</a></p>';
+        }else {
+            echo '&nbsp;';
+        }
+
+        if($capabilities->edititems) {
+            echo '<p>
+                <a href="'.htmlspecialchars('export.php?action=exportfile&id='.$id).'">'.get_string('export_questions', 'feedback').'</a>/
+                <a href="'.htmlspecialchars('import.php?id='.$id).'">'.get_string('import_questions', 'feedback').'</a>
+            </p>';
+        }
+        // print_simple_box_end();
+        print_box_end();
+    }
+    ///////////////////////////////////////////////////////////////////////////
+    ///print the Item-Edit-section
+    ///////////////////////////////////////////////////////////////////////////
+    if($do_show == 'edit') {
+        
+        $add_item_form->display();
+
+        if(is_array($feedbackitems)){
+            $itemnr = 0;
+            
+            $helpbutton = helpbutton('preview', get_string('preview','feedback'), 'feedback',true,false,'',true);
+            
+            print_heading($helpbutton . get_string('preview', 'feedback'));
+            if(isset($SESSION->feedback->moving) AND $SESSION->feedback->moving->shouldmoving == 1) {
+                print_heading('<a href="'.htmlspecialchars($ME.'?id='.$id).'">'.get_string('cancel_moving', 'feedback').'</a>');
+            }
+            // print_simple_box_start('center', '80%');
+            print_box_start('generalbox boxaligncenter boxwidthwide');
+            
+            //check, if there exists required-elements
+            $countreq = count_records('feedback_item', 'feedback', $feedback->id, 'required', 1);
+            if($countreq > 0) {
+                // echo '<font color="red">(*)' . get_string('items_are_required', 'feedback') . '</font>';
+                echo '<span class="feedback_required_mark">(*)' . get_string('items_are_required', 'feedback') . '</span>';
+            }
+            
+            echo '<table>';
+            if(isset($SESSION->feedback->moving) AND $SESSION->feedback->moving->shouldmoving == 1) {
+                $moveposition = 1;
+                echo '<tr>'; //only shown if shouldmoving = 1
+                    echo '<td>';
+                    $buttonlink = $ME.'?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&movehere='.$moveposition);
+                    echo '<a title="'.get_string('move_here','feedback').'" href="'.$buttonlink.'">
+                            <img class="movetarget" alt="'.get_string('move_here','feedback').'" src="'.$CFG->pixpath .'/movehere.gif" />
+                          </a>';
+
+                        // echo '<form action="'.$ME.'" method="post"><fieldset>';
+                        // echo '<input title="'.get_string('move_here','feedback').'" type="image" src="'.$CFG->pixpath .'/movehere.gif" hspace="1" height="16" width="80" border="0" />';
+                        // echo '<input type="hidden" name="movehere" value="'.$moveposition.'" />';
+                        // feedback_edit_print_default_form_values($id, $do_show);
+                        // echo '</fieldset></form>';
+                    echo '</td>';
+                echo '</tr>';
+            }
+            //print the inserted items
+            $itempos = 0;
+            foreach($feedbackitems as $feedbackitem){
+                $itempos++;
+                if(isset($SESSION->feedback->moving) AND $SESSION->feedback->moving->movingitem == $feedbackitem->id){ //hiding the item to move
+                    continue;
+                }
+                echo '<tr>';
+                //items without value only are labels
+                if($feedbackitem->hasvalue == 1) {
+                    $itemnr++;
+                    echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+                } else {
+                    echo '<td>&nbsp;</td>';
+                }
+                if($feedbackitem->typ != 'pagebreak') {
+                    feedback_print_item($feedbackitem, false, false, true);
+                }else {
+                    echo '<td class="feedback_pagebreak"><b>'.get_string('pagebreak', 'feedback').'</b></td><td><hr width="100%" size="8px" noshade="noshade" /></td>';
+                }
+                echo '<td>('.get_string('position', 'feedback').':'.$itempos .')</td>';
+                echo '<td>';
+                if($feedbackitem->position > 1){
+                    $buttonlink = $ME.'?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&moveupitem='.$feedbackitem->id);
+                    echo '<a class="icon up" title="'.get_string('moveup_item','feedback').'" href="'.$buttonlink.'">
+                            <img alt="'.get_string('moveup_item','feedback').'" src="'.$CFG->pixpath .'/t/up.gif" />
+                          </a>';
+                    //print the button to move-up the item
+                    // echo '<form action="'.$ME.'" method="post"><fieldset>';
+                    // ///////echo '<input title="'.get_string('moveup_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/up.gif" hspace="1" height="11" width="11" border="0" />';
+                    // echo '<input class="feedback_moveup_button" title="'.get_string('moveup_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/up.gif" />';
+                    // echo '<input type="hidden" name="moveupitem" value="'.$feedbackitem->id.'" />';
+                    // feedback_edit_print_default_form_values($id, $do_show);
+                    // echo '</fieldset></form>';
+                }else{
+                    echo '&nbsp;';
+                }
+                echo '</td>';
+                echo '<td>';
+                if($feedbackitem->position < $lastposition - 1){
+                    $buttonlink = $ME.'?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&movedownitem='.$feedbackitem->id);
+                    echo '<a class="icon down" title="'.get_string('movedown_item','feedback').'" href="'.$buttonlink.'">
+                            <img alt="'.get_string('movedown_item','feedback').'" src="'.$CFG->pixpath .'/t/down.gif" />
+                          </a>';
+                    //print the button to move-down the item
+                    // echo '<form action="'.$ME.'" method="post"><fieldset>';
+                    // echo '<input title="'.get_string('movedown_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/down.gif" hspace="1" height="11" width="11" border="0" />';
+                    // echo '<input class="feedback_movedown_button" title="'.get_string('movedown_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/down.gif" />';
+                    // echo '<input type="hidden" name="movedownitem" value="'.$feedbackitem->id.'" />';
+                    // feedback_edit_print_default_form_values($id, $do_show);
+                    // echo '</fieldset></form>';
+                }else{
+                    echo '&nbsp;';
+                }
+                echo '</td>';
+                echo '<td>';
+                    $buttonlink = $ME.'?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&moveitem='.$feedbackitem->id);
+                    echo '<a class="editing_move" title="'.get_string('move_item','feedback').'" href="'.$buttonlink.'">
+                            <img alt="'.get_string('move_item','feedback').'" src="'.$CFG->pixpath .'/t/move.gif" />
+                          </a>';
+                    // echo '<form action="'.$ME.'" method="post"><fieldset>';
+                    // echo '<input title="'.get_string('move_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/move.gif" hspace="1" height="11" width="11" border="0" />';
+                    // echo '<input class="feedback_move_button" title="'.get_string('move_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/move.gif" />';
+                    // echo '<input type="hidden" name="moveitem" value="'.$feedbackitem->id.'" />';
+                    // feedback_edit_print_default_form_values($id, $do_show);
+                    // echo '</fieldset></form>';
+                echo '</td>';
+                echo '<td>';
+                //print the button to edit the item
+                if($feedbackitem->typ != 'pagebreak') {
+                    $buttonlink = 'edit_item.php?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&itemid='.$feedbackitem->id.'&typ='.$feedbackitem->typ);
+                    echo '<a class="editing_update" title="'.get_string('edit_item','feedback').'" href="'.$buttonlink.'">
+                            <img alt="'.get_string('edit_item','feedback').'" src="'.$CFG->pixpath .'/t/edit.gif" />
+                          </a>';
+                    // echo '<form action="edit_item.php" method="post"><fieldset>';
+                    // echo '<input title="'.get_string('edit_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/edit.gif" hspace="1" height="11" width="11" border="0" />';
+                    // echo '<input class="feedback_edit_button" title="'.get_string('edit_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/edit.gif" />';
+                    // echo '<input type="hidden" name="itemid" value="'.$feedbackitem->id.'" />';
+                    // echo '<input type="hidden" name="typ" value="'.$feedbackitem->typ.'" />';
+                    // feedback_edit_print_default_form_values($id, $do_show);
+                    // echo '</fieldset></form>';
+                }else {
+                    echo '&nbsp;';
+                }
+                echo '</td>';
+                echo '<td>';
+                
+                //print the toggle-button to switch required yes/no
+                if($feedbackitem->hasvalue == 1) {
+                    // echo '<form action="'.$ME.'" method="post"><fieldset>';
+                    if($feedbackitem->required == 1) {
+                        // echo '<input title="'.get_string('switch_item_to_not_required','feedback').'" type="image" src="pics/required.gif" hspace="1" height="11" width="11" border="0" />';
+                        // echo '<input class="feedback_required_button" title="'.get_string('switch_item_to_not_required','feedback').'" type="image" src="pics/required.gif" />';
+                        $buttontitle = get_string('switch_item_to_not_required','feedback');
+                        $buttonimg = 'pics/required.gif';
+                    } else {
+                        // echo '<input title="'.get_string('switch_item_to_required','feedback').'" type="image" src="pics/notrequired.gif" hspace="1" height="11" width="11" border="0" />';
+                        // echo '<input class="feedback_required_button" title="'.get_string('switch_item_to_required','feedback').'" type="image" src="pics/notrequired.gif" />';
+                        $buttontitle = get_string('switch_item_to_required','feedback');
+                        $buttonimg = 'pics/notrequired.gif';
+                    }
+                    $buttonlink = $ME.'?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&switchitemrequired='.$feedbackitem->id);
+                    echo '<a class="icon feedback_switchrequired" title="'.$buttontitle.'" href="'.$buttonlink.'">
+                            <img alt="'.$buttontitle.'" src="'.$buttonimg.'" />
+                          </a>';
+                    // echo '<input type="hidden" name="switchitemrequired" value="'.$feedbackitem->id.'" />';
+                    // feedback_edit_print_default_form_values($id, $do_show);
+                    // echo '</fieldset></form>';
+                }else {
+                    echo '&nbsp;';
+                }
+                echo '</td>';
+                echo '<td>';
+                    $buttonlink = 'delete_item.php?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&deleteitem='.$feedbackitem->id);
+                    echo '<a class="icon delete" title="'.get_string('delete_item','feedback').'" href="'.$buttonlink.'">
+                            <img alt="'.get_string('delete_item','feedback').'" src="'.$CFG->pixpath .'/t/delete.gif" />
+                          </a>';
+                //print the button to drop the item
+                // echo '<form action="delete_item.php" method="post"><fieldset>';
+                // echo '<input class="feedback_delete_button" title="'.get_string('delete_item','feedback').'" type="image" src="'.$CFG->pixpath .'/t/delete.gif" />';
+                // echo '<input type="hidden" name="deleteitem" value="'.$feedbackitem->id.'" />';
+                // feedback_edit_print_default_form_values($id, $do_show);
+                // echo '</fieldset></form>';
+                echo '</td>';
+                echo '</tr>';
+                if(isset($SESSION->feedback->moving) AND $SESSION->feedback->moving->shouldmoving == 1) {
+                    $moveposition++;
+                    echo '<tr>'; //only shown if shouldmoving = 1
+                        echo '<td>';
+                            $buttonlink = $ME.'?'.htmlspecialchars(feedback_edit_get_default_query($id, $do_show).'&movehere='.$moveposition);
+                            echo '<a title="'.get_string('move_here','feedback').'" href="'.$buttonlink.'">
+                                    <img class="movetarget" alt="'.get_string('move_here','feedback').'" src="'.$CFG->pixpath .'/movehere.gif" />
+                                  </a>';
+                            // echo '<form action="'.$ME.'" method="post"><fieldset>';
+                            // echo '<input class="feedback_movehere_button" title="'.get_string('move_here','feedback').'" type="image" src="'.$CFG->pixpath .'/movehere.gif" />';
+                            // echo '<input type="hidden" name="movehere" value="'.$moveposition.'" />';
+                            // feedback_edit_print_default_form_values($id, $do_show);
+                            // echo '</fieldset></form>';
+                        echo '</td>';
+                    echo '</tr>';
+                }else {
+                    echo '<tr><td>&nbsp;</td></tr>';
+                }
+                
+            }
+            echo '</table>';
+            // print_simple_box_end();
+            print_box_end();
+        }else{
+            // print_simple_box(get_string('no_items_available_yet','feedback'),"center");
+            print_box(get_string('no_items_available_yet','feedback'),'generalbox boxaligncenter');
+        }
+    }
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+    function feedback_edit_get_default_query($id, $tab) {
+        global $USER;
+        
+        $query = 'id='.$id;
+        $query .= '&do_show='.$tab;
+        //$query .= '&sesskey='.$USER->sesskey;
+        
+        return $query;
+    }
+
+    function feedback_edit_print_default_form_values($id, $tab) {
+        global $USER;
+        
+        echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+        echo '<input type="hidden" name="id" value="'.$id.'" />';
+        echo '<input type="hidden" name="do_show" value="'.$tab.'" />';
+    }
+?>
diff --git a/mod/feedback/edit_form.php b/mod/feedback/edit_form.php
new file mode 100644 (file)
index 0000000..1521534
--- /dev/null
@@ -0,0 +1,140 @@
+<?php // $Id$
+/**
+* prints the forms to choose an item-typ to create items and to choose a template to use
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once $CFG->libdir.'/formslib.php';
+
+class feedback_edit_add_question_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        //headline
+        $mform->addElement('header', 'general', get_string('add_items', 'feedback'));
+        // visible elements
+        // $feedback_names = feedback_load_feedback_items('mod/feedback/item');
+        // $feedback_names_options = array();
+        // $feedback_names_options[' '] = get_string('select');
+        // foreach($feedback_names as $fn) {
+            // $feedback_names_options[$fn] = get_string($fn,'feedback');
+        // }
+        $feedback_names_options = feedback_load_feedback_items_options();
+        
+        $attributes = 'onChange="this.form.submit()"';
+        $mform->addElement('select', 'typ', '', $feedback_names_options, $attributes);
+
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'position');
+//-------------------------------------------------------------------------------
+        // buttons
+        $mform->addElement('submit', 'add_item', get_string('add_item', 'feedback'));
+    }
+}
+
+class feedback_edit_use_template_form extends moodleform {
+    var $feedbackdata;
+    
+    function definition() {
+        $this->feedbackdata = new object();
+        //this function can not be called, because not all data are available at this time
+        //I use set_form_elements instead
+    }
+    
+    //this function set the data used in set_form_elements()
+    //in this form the only value have to set is course
+    //eg: array('course' => $course)
+    function set_feedbackdata($data) {
+        if(is_array($data)) {
+            foreach($data as $key => $val) {
+                $this->feedbackdata->{$key} = $val;
+            }
+        }
+    }
+    
+    //here the elements will be set
+    //this function have to be called manually
+    //the advantage is that the data are already set
+    function set_form_elements(){
+        $mform =& $this->_form;
+        
+        $elementgroup = array();
+        //headline
+        $mform->addElement('header', '', get_string('using_templates', 'feedback'));
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        
+        // visible elements
+        $templates_options = array();
+        if($templates = feedback_get_template_list($this->feedbackdata->course)){//get the templates
+            $templates_options[' '] = get_string('select');
+            foreach($templates as $template) {
+                $templates_options[$template->id] = $template->name;
+            }
+            $attributes = 'onChange="this.form.submit()"';
+            $elementgroup[] =& $mform->createElement('select', 'templateid', '', $templates_options, $attributes);
+            // buttons
+            $elementgroup[] =& $mform->createElement('submit', 'use_template', get_string('use_this_template', 'feedback'));
+        }else {
+            $mform->addElement('static', 'info', get_string('no_templates_available_yet', 'feedback'));
+        }
+        $mform->addGroup($elementgroup, 'elementgroup', '', array(' '), false);
+        
+    //-------------------------------------------------------------------------------
+    }
+}
+
+class feedback_edit_create_template_form extends moodleform {
+    var $feedbackdata;
+    
+    function definition() {
+    }
+    
+    function data_preprocessing(&$default_values){
+        $default_values['templatename'] = '';
+    }
+    
+    function set_feedbackdata($data) {
+        if(is_array($data)) {
+            foreach($data as $key => $val) {
+                $this->feedbackdata->{$key} = $val;
+            }
+        }
+    }
+    
+    function set_form_elements(){
+        $mform =& $this->_form;
+        $capabilities = $this->feedbackdata->capabilities;
+
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'do_show');
+        $mform->addElement('hidden', 'savetemplate', 1);
+
+        //headline
+        $mform->addElement('header', '', get_string('creating_templates', 'feedback'));
+        
+        // visible elements
+        $elementgroup = array();
+        
+        $elementgroup[] =& $mform->createElement('static', 'templatenamelabel', get_string('name', 'feedback'));
+        $elementgroup[] =& $mform->createElement('text', 'templatename', get_string('name', 'feedback'), array('size'=>'40', 'maxlength'=>'200'));
+        if($capabilities->createpublictemplate) {
+            $elementgroup[] =& $mform->createElement('checkbox', 'ispublic', get_string('public', 'feedback'), get_string('public', 'feedback'));
+        }
+        
+        // buttons
+        $elementgroup[] =& $mform->createElement('submit', 'create_template', get_string('save_as_new_template', 'feedback'));
+        $mform->addGroup($elementgroup, 'elementgroup', get_string('name', 'feedback'), array(' '), false);
+        
+        $mform->setType('templatename', PARAM_TEXT);
+        
+//-------------------------------------------------------------------------------
+    }
+}
+?>
diff --git a/mod/feedback/edit_item.php b/mod/feedback/edit_item.php
new file mode 100644 (file)
index 0000000..70f3c47
--- /dev/null
@@ -0,0 +1,192 @@
+<?php // $Id$
+/**
+* prints the form to edit a dedicated item
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    $id = optional_param('id', NULL, PARAM_INT);
+    $typ = optional_param('typ', false, PARAM_ALPHA);
+    $itemid = optional_param('itemid', false, PARAM_INT);
+    
+    if(!$typ)redirect(htmlspecialchars('edit.php?id=' . $id));
+
+    // set up some general variables
+    $usehtmleditor = can_use_html_editor(); 
+
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+        
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+        
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error(get_string('error'));
+    }
+
+    //if the typ is pagebreak so the item will be saved directly
+    if($typ == 'pagebreak') {
+        feedback_create_pagebreak($feedback->id);
+        redirect(htmlspecialchars('edit.php?id='.$id));
+        exit;
+    }
+    
+    //get the existing item or create it
+    // $formdata->itemid = isset($formdata->itemid) ? $formdata->itemid : NULL;
+    if($itemid and $item = get_record('feedback_item', 'id', $itemid)){
+        $typ = $item->typ;
+        $position = $item->position;
+    }else {
+        $position = -1;
+        $item = new stdClass();
+        if ($position == '')$position = 0;
+        if(!$typ)error('missing value "typ"', htmlspecialchars('edit.php?id='.$id));
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////////////
+    if(isset($formdata->cancel)){
+        redirect(htmlspecialchars('edit.php?id=' . $id));
+    }
+    
+    // if(isset($formdata->editcancel) AND $formdata->editcancel == 1){
+        // redirect(htmlspecialchars('edit.php?id=' . $id));
+    // }
+    
+    if(isset($formdata->saveitem) AND $formdata->saveitem == 1){
+        $newposition = $formdata->position;
+        $formdata->position = $newposition + 1;
+
+        if (!$newitemid = feedback_create_item($formdata)) {
+            $SESSION->feedback->errors[] = get_string('item_creation_failed', 'feedback');
+        }else {
+            $newitem = get_record('feedback_item', 'id', $newitemid);
+            if (!feedback_move_item($newitem, $newposition)){
+                $SESSION->feedback->errors[] = get_string('item_creation_failed', 'feedback');
+            }else {
+                redirect(htmlspecialchars('edit.php?id='.$id));
+            }            
+        }
+    }
+    
+    if(isset($formdata->updateitem) AND $formdata->updateitem == 1){
+        //update the item and go back
+        if (!feedback_update_item($item, $formdata)) {
+            $SESSION->feedback->errors[] = get_string('item_update_failed', 'feedback');
+        } else {
+            if (!feedback_move_item($item, $formdata->position)){
+                $SESSION->feedback->errors[] = get_string('item_update_failed', 'feedback');
+            }else {
+                redirect(htmlspecialchars('edit.php?id='.$id));
+            } 
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(format_text($feedback->name));
+  
+          
+    //print errormsg
+    if(isset($error)){echo $error;}
+
+    feedback_print_errors();
+            
+    // print_simple_box_start('center');
+    print_box_start('generalbox boxwidthwide boxaligncenter');
+    echo '<form action="'.$ME.'" method="post">';
+    echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+    
+    //this div makes the buttons stand side by side
+    echo '<div>';
+    $itemclass = 'feedback_item_'.$typ;
+    $itemobj = new $itemclass();
+    $itemobj->show_edit($item, $usehtmleditor);
+    echo '</div>';        
+    echo '<input type="hidden" name="id" value="'.$id.'" />';
+    echo '<input type="hidden" name="itemid" value="'.(isset($item->id)?$item->id:'').'" />';
+    echo '<input type="hidden" name="typ" value="'.$typ.'" />';
+    echo '<input type="hidden" name="feedbackid" value="'.$feedback->id.'" />';
+    
+    //choose the position
+    $lastposition = count_records('feedback_item', 'feedback', $feedback->id);
+    echo get_string('position', 'feedback').'&nbsp;';
+    echo '<select name="position">';
+        //Dropdown-Items for choosing the position
+        if($position == -1){
+            feedback_print_numeric_option_list(1, $lastposition + 1, $lastposition + 1);
+        }else {
+            feedback_print_numeric_option_list(1, $lastposition, $item->position);
+        }
+    echo '</select><hr />';
+    
+    //////////////////////////////////////////////////////////////////////////////////////        
+    //////////////////////////////////////////////////////////////////////////////////////        
+    if(!empty($item->id)){
+        echo '<input type="hidden" id="updateitem" name="updateitem" value="1" />';
+        echo '<input type="submit" value ="'.get_string('update_item', 'feedback').'" />';
+    }else{
+        echo '<input type="hidden" id="saveitem" name="saveitem" value="1" />';
+        echo '<input type="submit" value="'.get_string('save_item', 'feedback').'" />';
+    }
+    echo '<input type="submit" name="cancel" value="'.get_string('cancel').'" />';
+    echo '</form>';
+    //////////////////////////////////////////////////////////////////////////////////////        
+    //////////////////////////////////////////////////////////////////////////////////////
+
+    // print_simple_box_end();
+    print_box_end();
+  
+    if ($typ!='label') {
+        echo '<script language="javascript">';
+        echo 'document.getElementById("itemname").focus()';
+        echo '</script>';
+    } 
+
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/export.php b/mod/feedback/export.php
new file mode 100644 (file)
index 0000000..3a4b78d
--- /dev/null
@@ -0,0 +1,104 @@
+<?php // $Id$
+/**
+* prints the form to export the items as xml-file
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    // get parameters
+    $id = required_param('id', PARAM_INT); 
+    $action = optional_param('action', false, PARAM_ALPHA);
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error('this action is not allowed');
+    }
+    
+    if ($action == 'exportfile') {
+        if(!$exportdata = feedback_get_xml_data($feedback->id)) {
+            error('no data');
+        }
+        @feedback_send_xml_data($exportdata, 'feedback_'.$feedback->id.'.xml');
+        exit;
+    }
+
+    redirect('view.php?id='.$id);
+    exit;
+  
+    function feedback_get_xml_data($feedbackid) {
+        $space = '     ';
+        //get all items of the feedback
+        if(!$items = get_records('feedback_item', 'feedback', $feedbackid, 'position')) {
+            return false;
+        }
+        
+        //writing the header of the xml file including the charset of the currrent used language
+        $data = '<?xml version="1.0" encoding="UTF-8" ?>'."\n";
+        $data .= '<FEEDBACK VERSION="200701" COMMENT="XML-Importfile for mod/feedback">'."\n";
+        $data .= $space.'<ITEMS>'."\n";
+        
+        //writing all the items
+        foreach($items as $item) {
+            //start of item
+            $data .= $space.$space.'<ITEM TYPE="'.$item->typ.'" REQUIRED="'.$item->required.'">'."\n";
+            
+            //start of itemtext
+            $data .= $space.$space.$space.'<ITEMTEXT>'."\n";
+            //start of CDATA
+            $data .= $space.$space.$space.$space.'<![CDATA[';
+            $data .= $item->name;
+            //end of CDATA
+            $data .= ']]>'."\n";
+            //end of itemtext
+            $data .= $space.$space.$space.'</ITEMTEXT>'."\n";
+            
+            //start of presentation
+            $data .= $space.$space.$space.'<PRESENTATION>'."\n";
+            //start of CDATA
+            $data .= $space.$space.$space.$space.'<![CDATA[';
+            $data .= $item->presentation;
+            //end of CDATA
+            $data .= ']]>'."\n";
+            //end of presentation
+            $data .= $space.$space.$space.'</PRESENTATION>'."\n";
+            
+            //end of item
+            $data .= $space.$space.'</ITEM>'."\n";
+        }
+        
+        //writing the footer of the xml file
+        $data .= $space.'</ITEMS>'."\n";
+        $data .= '</FEEDBACK>'."\n";
+        
+        return $data;
+    }
+    
+    function feedback_send_xml_data($data, $filename) {
+        $charset = get_string('thischarset');
+        @header('Content-Type: application/xml; charset=UTF-8');
+        @header('Content-Disposition: attachment; filename='.$filename);
+        print($data);
+    }
+?>
diff --git a/mod/feedback/icon.gif b/mod/feedback/icon.gif
new file mode 100644 (file)
index 0000000..2ad2534
Binary files /dev/null and b/mod/feedback/icon.gif differ
diff --git a/mod/feedback/import.php b/mod/feedback/import.php
new file mode 100644 (file)
index 0000000..42a1a6a
--- /dev/null
@@ -0,0 +1,232 @@
+<?php // $Id$
+/**
+* prints the form to import items from xml-file
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    
+    // get parameters
+    $id = required_param('id', PARAM_INT);
+    $choosefile = optional_param('choosefile', false, PARAM_PATH);
+    $action = optional_param('action', false, PARAM_ALPHA);
+
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error('this action is not allowed');
+    }
+    
+    unset($filename);
+    if ($action == 'choosefile' AND confirm_sesskey() ) { 
+
+        // file checks out ok
+        $fileisgood = false;
+
+        // work out if this is an uploaded file 
+        // or one from the filesarea.
+        if ($choosefile) {
+            $filename = "{$CFG->dataroot}/{$course->id}/{$choosefile}";
+        }
+    }
+    
+    // process if we are happy file is ok
+    if (isset($filename)) { 
+        if(!is_file($filename) OR !is_readable($filename)) {
+            error('file not found or not readable');
+        }
+        if(!$xmldata = feedback_load_xml_data($filename)) {
+            error('failed to loading xml', 'edit.php?id='.$id);
+        }
+        
+        $importerror = feedback_import_loaded_data($xmldata, $feedback->id);
+        if($importerror->stat == true) {
+            redirect('edit.php?id='.$id.'&do_show=templates', get_string('import_successfully', 'feedback'), 3);
+            exit;
+        }
+    }
+
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(get_string('import_questions','feedback'));
+    
+    if(isset($importerror->msg) AND is_array($importerror->msg)) {
+        // print_simple_box_start('center', '', '#FFAAAA', 5, 'notifyproblem');
+        print_box_start('generalbox errorboxcontent boxaligncenter');
+        foreach($importerror->msg as $msg) {
+            echo $msg.'<br />';
+        }
+        // print_simple_box_end();
+        print_box_end();
+    }
+    
+    ?>
+
+     <form name="form" method="post" action="import.php">
+          <input type="hidden" name="sesskey" value="<?php echo sesskey(); ?>" />
+          <input type="hidden" name="action" value="choosefile" />
+          <input type="hidden" name="id" value="<?php p($id);?>" />
+          <input type="hidden" name="do_show" value="templates" />
+          <?php print_box_start('generalbox boxaligncenter boxwidthwide'); ?>
+          <input type="radio" name="deleteolditems" value="1" checked="checked" /> <?php echo get_string('delete_old_items', 'feedback').' ('.get_string('oldvalueswillbedeleted','feedback').')';?><br />
+          <input type="radio" name="deleteolditems" value="0" /> <?php echo get_string('append_new_items', 'feedback').' ('.get_string('oldvaluespreserved','feedback').')';?><br />
+          <table cellpadding="5">
+                <tr>
+                     <td align="right"><?php print_string('file', 'feedback'); ?>:</td>
+                     <td><input type="text" name="choosefile" size="50" /></td>
+                </tr>
+
+                <tr>
+                     <td>&nbsp;</td>
+                     <td><?php  button_to_popup_window ("/files/index.php?id={$course->id}&amp;choose=form.choosefile", 
+                          "coursefiles", get_string('choosefile', 'feedback'), 500, 750, get_string('choosefile', 'feedback')); ?>
+                          <input type="submit" name="save" value="<?php print_string('importfromthisfile', 'feedback'); ?>" />
+                    </td>
+                </tr>
+          </table>
+          <?php 
+          print_box_end(); ?>
+     </form>
+
+     <?php
+
+    echo '<div align="center">';
+    print_single_button('edit.php', array('id'=>$id, 'do_show'=>'templates'), get_string('cancel'));
+    echo '</div>';
+    print_footer($course);
+  
+    function feedback_load_xml_data($filename) {
+        global $CFG;
+        require_once($CFG->dirroot.'/lib/xmlize.php');
+    
+        $datei =  file_get_contents($filename);
+        
+        if(!$datei = feedback_check_xml_utf8($datei)) return false;
+        
+        $data = xmlize($datei, 1, 'UTF-8');
+        
+        if(intval($data['FEEDBACK']['@']['VERSION']) != 200701) {
+            return false;
+        }
+        $data = $data['FEEDBACK']['#']['ITEMS'][0]['#']['ITEM'];
+        return $data;
+    }
+    
+    function feedback_import_loaded_data(&$data, $feedbackid){
+        global $CFG;
+        
+        $deleteolditems = optional_param('deleteolditems', 0, PARAM_INT);
+        
+        $error = new object();
+        $error->stat = true;
+        $error->msg = array();
+        
+        if(!is_array($data)) {
+            $error->msg[] = get_string('data_is_not_an_array', 'feedback');
+            $error->stat = false;
+            return $error;
+        }
+        
+        if($deleteolditems) {
+            feedback_delete_all_items($feedbackid);
+            $position = 0;
+        } else {
+            //items will be add to the end of the existing items
+            $position = count_records('feedback_item', 'feedback', $feedbackid);
+        }
+        
+        foreach($data as $item) {
+            $position++;
+            //check the typ
+            $typ = $item['@']['TYPE'];
+            $itemclass = 'feedback_item_'.$typ;
+            if($typ != 'pagebreak' AND !class_exists($itemclass)) {
+                $error->stat = false;
+                $error->msg[] = 'type ('.$typ.') not found';
+                continue;
+            }
+            $itemobj = new $itemclass();
+            
+            $newitem = new object();
+            $newitem->feedback = $feedbackid;
+            $newitem->template = 0;
+            $newitem->typ = $typ;
+            $newitem->name = trim($item['#']['ITEMTEXT'][0]['#']);
+            $newitem->presentation = trim($item['#']['PRESENTATION'][0]['#']);
+            if($typ != 'pagebreak') {
+                $newitem->hasvalue = $itemobj->get_hasvalue();
+            }else {
+                $newitem->hasvalue = 0;
+            }
+            $newitem->required = intval($item['@']['REQUIRED']);
+            $newitem->position = $position;
+            if(!insert_record('feedback_item', $newitem)) {
+                $error->stat = false;
+                $error->msg[] = 'item ('.$newitem->name.') not imported';
+            }
+        }
+        return $error;
+    }
+
+    function feedback_check_xml_utf8($text) {
+        //find the encoding
+        $searchpattern = '/^\<\?xml.+(encoding=\"([a-z0-9-]*)\").+\?\>/is';
+        
+        if(!preg_match($searchpattern, $text, $match)) return false; //no xml-file
+        
+        //$match[0] = \<\? xml ... \?\> (without \)
+        //$match[1] = encoding="...."
+        //$match[2] = ISO-8859-1 or so on
+        if(isset($match[0]) AND !isset($match[1])){ //no encoding given. we assume utf-8
+            return $text;
+        }
+        
+        if(isset($match[0]) AND isset($match[1]) AND isset($match[2])) { //encoding is given in $match[2]
+            $enc = $match[2];
+            $textlib = textlib_get_instance();
+            return $textlib->convert($text, $enc);
+        }
+    }
+?>
diff --git a/mod/feedback/index.php b/mod/feedback/index.php
new file mode 100644 (file)
index 0000000..dbf34e6
--- /dev/null
@@ -0,0 +1,116 @@
+<?php // $Id$
+/**
+* prints the overview of all feedbacks included into the current course
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    $id = required_param('id', PARAM_INT);
+
+    if (! $course = get_record("course", "id", $id)) {
+        error("Course ID is incorrect");
+    }
+    $capabilities = feedback_load_course_capabilities($course->id);
+
+    require_login($course->id);
+
+    add_to_log($course->id, "feedback", "view all", htmlspecialchars('index.php?id='.$course->id), "");
+
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "", 'type' => 'activity');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(get_string('modulename', 'feedback').' '.get_string('activities'), "",
+                 $navigation, "", "", true, null, navmenu($course));
+
+    /// Get all the appropriate data
+
+    if (! $feedbacks = get_all_instances_in_course("feedback", $course)) {
+        notice("There are no feedbacks", htmlspecialchars('../../course/view.php?id='.$course->id));
+        die;
+    }
+
+    /// Print the list of instances (your module will probably extend this)
+
+    $timenow = time();
+    $strname  = get_string("name");
+    $strweek  = get_string("week");
+    $strtopic  = get_string("topic");
+    $strresponses = get_string('responses', 'feedback');
+
+    if ($course->format == "weeks") {
+        if($capabilities->viewreports) {
+            $table->head  = array ($strweek, $strname, $strresponses);
+            $table->align = array ("center", "left", 'center');
+        }else{
+            $table->head  = array ($strweek, $strname);
+            $table->align = array ("center", "left");
+        }
+    } else if ($course->format == "topics") {
+        if($capabilities->viewreports) {
+            $table->head  = array ($strtopic, $strname, $strresponses);
+            $table->align = array ("center", "left", "center");
+        }else{
+            $table->head  = array ($strtopic, $strname);
+            $table->align = array ("center", "left");
+        }
+    } else {
+        if($capabilities->viewreports) {
+            $table->head  = array ($strname, $strresponses);
+            $table->align = array ("left", "center");
+        }else{
+            $table->head  = array ($strname);
+            $table->align = array ("left");
+        }
+    }
+
+    
+    foreach ($feedbacks as $feedback) {
+        //get the responses of each feedback
+
+        if($capabilities->viewreports) {
+            $completedFeedbackCount = intval(feedback_get_completeds_group_count($feedback));
+        }
+        
+        if (!$feedback->visible) {
+            //Show dimmed if the mod is hidden
+            $link = '<a class="dimmed" href="'.htmlspecialchars('view.php?id='.$feedback->coursemodule).'">'.$feedback->name.'</a>';
+        } else {
+            //Show normal if the mod is visible
+            $link = '<a href="'.htmlspecialchars('view.php?id='.$feedback->coursemodule).'">'.$feedback->name.'</a>';
+        }
+
+        if ($course->format == "weeks" or $course->format == "topics") {
+            $tabledata = array ($feedback->section, $link);
+        } else {
+            $tabledata = array ($link);
+        }
+        if($capabilities->viewreports) {
+            $tabledata[] = $completedFeedbackCount;
+        }
+        
+        $table->data[] = $tabledata;
+        
+    }
+
+    echo "<br />";
+
+    print_table($table);
+
+    /// Finish the page
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/item/captcha/default.ttf b/mod/feedback/item/captcha/default.ttf
new file mode 100644 (file)
index 0000000..754a9b7
Binary files /dev/null and b/mod/feedback/item/captcha/default.ttf differ
diff --git a/mod/feedback/item/captcha/lib.php b/mod/feedback/item/captcha/lib.php
new file mode 100644 (file)
index 0000000..0aec717
--- /dev/null
@@ -0,0 +1,149 @@
+<?PHP  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+class feedback_item_captcha extends feedback_item_base {
+    var $type = "captcha";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation=empty($item->presentation)? 3 : $item->presentation;
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('numeric', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php 
+                $item->required = isset($item->required) ? $item->required : 1;
+                echo ($item->required == 1?'checked="checked"':'');
+                ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td><?php print_string('count_of_nums', 'feedback');?></td>
+                <td>
+                    <select name="count_of_nums">
+                    <?php
+                        feedback_print_numeric_option_list(3, 10, $item->presentation);
+                    ?>
+                    </select>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert eine Struktur ->name, ->data = array(mit Antworten)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        return null;
+    }
+
+    function get_printval($item, $value) {
+        return '';
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        global $SESSION, $CFG;
+        
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        $presentation = $item->presentation;
+        $SESSION->feedback->item->captcha->charcount = $presentation;
+        
+        $cmid = 0;
+        if(!$readonly) {
+            $feedbackid = $item->feedback;
+            if($feedbackid > 0) {
+                $feedback = get_record('feedback', 'id', $feedbackid);
+                if($cm = get_coursemodule_from_instance("feedback", $feedback->id, $feedback->course)) {
+                    $cmid = $cm->id;
+                }
+            }
+        }
+        
+        if(isset($SESSION->feedback->item->captcha->checked)) {
+            $checked = $SESSION->feedback->item->captcha->checked == true;
+            unset($SESSION->feedback->item->captcha->checked);
+        }else {
+            $checked = false;
+        }
+        
+        //check if an false value even the value is not required
+        if(!$readonly AND !$item->required AND $value != '' AND $SESSION->feedback->item->captcha->checkchar != $value) {
+            $falsevalue = true;
+        }else {
+            $falsevalue = false;
+        }
+        
+        if(($highlightrequire AND $item->required AND !$checked) OR $falsevalue) {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark = ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>">
+            <?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?>
+            <img alt="<?php echo $this->type;?>" src="<?php echo $CFG->wwwroot.htmlspecialchars('/mod/feedback/item/captcha/print_captcha.php?id='.$cmid);?>" />
+        </td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        if($readonly){
+            // print_simple_box_start($align);
+            print_box_start('generalbox boxalign'.$align);
+            echo $value?$value:'&nbsp;';
+            // print_simple_box_end();
+            print_box_end();
+        }else {
+    ?>
+            <input type="text" name="<?php echo $item->typ . '_' . $item->id;?>"
+                                    size="<?php echo $presentation;?>"
+                                    maxlength="<?php echo $presentation;?>"
+                                    value="" />
+    <?php
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        global $SESSION;
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '') AND $item->required != 1) return true;
+        if($SESSION->feedback->item->captcha->checkchar == $value) {
+            $SESSION->feedback->item->captcha->checked = true;
+            return true;
+        }
+        return false;
+    }
+
+    function create_value($data) {
+        $data = addslashes(clean_text($data));
+        return $data;
+    }
+
+    function get_presentation($data) {
+        return $data->count_of_nums;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/captcha/print_captcha.php b/mod/feedback/item/captcha/print_captcha.php
new file mode 100644 (file)
index 0000000..2723286
--- /dev/null
@@ -0,0 +1,113 @@
+<?php
+    require_once('../../../../config.php');
+    
+    $id = required_param('id', PARAM_INT);
+    
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    
+    if(!isset($SESSION->feedback->item->captcha)) {
+        error('not allowed');
+    }
+
+    $height = 40;
+    $charcount = $SESSION->feedback->item->captcha->charcount;
+    $fontfile = $CFG->dirroot.'/mod/feedback/item/captcha/default.ttf';
+
+    $ttfbox = imagettfbbox ( 30, 0, $fontfile, 'H' );//the text to measure
+    $charwidth = $ttfbox[2];
+
+    $width = $charcount * $charwidth;
+
+    $scale = 0.3;
+    $elipsesize = intval((($width + $height)/2) / 5);
+    $factorX = intval($width * $scale);
+    $factorY = intval($height * $scale);
+
+    //I split the colors in three ranges
+    //given are the max-min-values
+    //$colors = array(80, 155, 255);
+    $colors = array(array(0,40),array(50,200),array(210,255));
+    //shuffle($colors);
+    list($col_text1, $col_el, $col_text2) = $colors;
+
+    //if the text is in color_1 so the elipses can be in color_2 or color_3
+    //if the text is in color_2 so the elipses can be in color_1 or color_3
+    //and so on.
+    $textcolnum = rand(1, 3);
+
+    //create the numbers to print out
+    $nums = array();
+    for($i = 0; $i < $charcount; $i++) {
+        $nums[] = rand(0,9); //Ziffern von 0-
+    }
+    // $nums = range(0, 9);
+    // shuffle($nums);
+
+
+    //to draw enough elipses so I draw 0.2 * width and 0.2 * height
+    //we need th colors for that
+    $properties = array();
+    for($x = 0; $x < $factorX; $x++) {
+        for($y = 0; $y < $factorY; $y++) {
+            $propobj = null;
+            $propobj->x = intval($x / $scale);
+            $propobj->y = intval($y / $scale);
+            $propobj->red = get_random_color($col_el[0], $col_el[1]);
+            $propobj->green = get_random_color($col_el[0], $col_el[1]);
+            $propobj->blue = get_random_color($col_el[0], $col_el[1]);
+            $properties[] = $propobj;
+        }
+    }
+    shuffle($properties);
+
+    // create a blank image
+    $image = imagecreatetruecolor($width, $height);
+    $bg = imagecolorallocate($image, 0, 0, 0);
+    for($i = 0; $i < ($factorX * $factorY); $i++) {
+        $propobj = $properties[$i];
+        // choose a color for the ellipse
+        $col_ellipse = imagecolorallocate($image, $propobj->red, $propobj->green, $propobj->blue);
+        // draw the white ellipse
+        imagefilledellipse($image, $propobj->x, $propobj->y, $elipsesize, $elipsesize, $col_ellipse);
+    }
+
+    $checkchar = '';
+    for($i = 0; $i < $charcount; $i++) {
+        $colnum = rand(1,2);
+        $textcol->red = get_random_color(${'col_text'.$colnum}[0], ${'col_text'.$colnum}[1]);
+        $textcol->green = get_random_color(${'col_text'.$colnum}[0], ${'col_text'.$colnum}[1]);
+        $textcol->blue = get_random_color(${'col_text'.$colnum}[0], ${'col_text'.$colnum}[1]);
+        $color_text = imagecolorallocate($image, $textcol->red, $textcol->green, $textcol->blue);
+        $angle_text = rand(-20, 20);
+        $left_text = $i * $charwidth;
+        $text = $nums[$i];
+        $checkchar .= $text;
+        ImageTTFText ($image, 30, $angle_text, $left_text, 35, $color_text, $fontfile, $text);
+    }
+    
+    $SESSION->feedback->item->captcha->checkchar = $checkchar;
+    
+    // output the picture
+    header("Content-type: image/png");
+    imagepng($image);
+
+    function get_random_color($val1 = 0, $val2 = 255) {
+        $min = $val1 < $val2 ? $val1 : $val2;
+        $max = $val1 > $val2 ? $val1 : $val2;
+        
+        return rand($min, $max);
+    }
+
+?> 
diff --git a/mod/feedback/item/check/lib.php b/mod/feedback/item/check/lib.php
new file mode 100644 (file)
index 0000000..65b7f78
--- /dev/null
@@ -0,0 +1,314 @@
+<?PHP  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+define('FEEDBACK_CHECK_LINE_SEP', '|');
+define('FEEDBACK_CHECK_ADJUST_SEP', '<<<<<');
+class feedback_item_check extends feedback_item_base {
+    var $type = "check";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation = empty($item->presentation) ? '' : $item->presentation;
+       
+        //check, whether the buttons are vertical or horizontal
+        $presentation = $horizontal = '';
+        @list($presentation, $horizontal) = explode(FEEDBACK_CHECK_ADJUST_SEP, $item->presentation);
+        if(isset($horizontal) AND $horizontal == 1) {
+            $horizontal = true;
+        }else {
+            $horizontal = false;
+        }
+        
+    ?>
+        <table>
+            <tr><th colspan="2">
+                <?php print_string('check', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php 
+                    $item->required=isset($item->required) ? $item->required : 0;
+                    echo ($item->required == 1?'checked="checked"':'');
+                    ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <?php print_string('adjustment', 'feedback');?>:
+                    &nbsp;<?php print_string('vertical', 'feedback');?><input type="radio" name="horizontal" value="0" <?php echo $horizontal ? '' : 'checked="checked"';?> />
+                    &nbsp;<?php print_string('horizontal', 'feedback');?><input type="radio" name="horizontal" value="1" <?php echo $horizontal ? 'checked="checked"' : '';?> />
+                </td>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td>
+                    <?php print_string('check_values', 'feedback');?>
+                    <?php print_string('use_one_line_for_each_value', 'feedback');?>
+                </td>
+                <td>
+        <?php
+                    $itemvalues = str_replace(FEEDBACK_CHECK_LINE_SEP, "\n", stripslashes_safe($presentation));
+        ?>
+                    <textarea name="itemvalues" cols="30" rows="5"><?php echo $itemvalues;?></textarea>
+                </td>
+            </tr>
+        </table>
+        <?php
+    }
+
+    //liefert ein Array mit drei Werten(typ, name, XXX)
+    //XXX ist ein Array (anzahl der Antworten bei Typ checkbox) Jedes Element ist eine Struktur (answertext, answercount)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        $analysedItem = array();
+        $analysedItem[] = $item->typ;
+        $analysedItem[] = $item->name;
+        //die moeglichen Antworten extrahieren
+        $answers = null;
+        $presentation = '';
+        @list($presentation) = explode(FEEDBACK_CHECK_ADJUST_SEP, $item->presentation); //remove the adjustment-info
+       
+        $answers = explode (FEEDBACK_CHECK_LINE_SEP, stripslashes_safe($presentation));
+        if(!is_array($answers)) return null;
+
+        //die Werte holen
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if(!$values) return null;
+        //schleife ueber den Werten und ueber die Antwortmoeglichkeiten
+       
+        $analysedAnswer = array();
+
+        for($i = 1; $i <= sizeof($answers); $i++) {
+            $ans = null;
+            $ans->answertext = $answers[$i-1];
+            $ans->answercount = 0;
+            foreach($values as $value) {
+                //ist die Antwort gleich dem index der Antworten + 1?
+                $vallist = explode(FEEDBACK_CHECK_LINE_SEP, $value->value);
+                foreach($vallist as $val) {
+                    if ($val == $i) {
+                       $ans->answercount++;
+                    }
+                }
+            }
+            $ans->quotient = $ans->answercount / sizeof($values);
+            $analysedAnswer[] = $ans;
+        }
+        $analysedItem[] = $analysedAnswer;
+        return $analysedItem;
+    }
+
+    function get_printval($item, $value) {
+        $printval = '';
+        
+        if(!isset($value->value)) return $printval;
+
+        @list($presentation) = explode(FEEDBACK_CHECK_ADJUST_SEP, $item->presentation); //remove the adjustment-info
+
+        $presentation = array_values(explode (FEEDBACK_CHECK_LINE_SEP, stripslashes_safe($presentation)));
+        $vallist = array_values(explode (FEEDBACK_CHECK_LINE_SEP, $value->value));
+        for($i = 0; $i < sizeof($vallist); $i++) {
+            for($k = 0; $k < sizeof($presentation); $k++) {
+                if($vallist[$i] == ($k + 1)) {//Die Werte beginnen bei 1, das Array aber mit 0
+                    $printval .= trim($presentation[$k]) . chr(10);
+                    break;
+                }
+            }
+        }
+        return $printval;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $sep_dec = get_string('separator_decimal', 'feedback');
+        if(substr($sep_dec, 0, 2) == '[['){
+            $sep_dec = FEEDBACK_DECIMAL;
+        }
+
+        $sep_thous = get_string('separator_thousand', 'feedback');
+        if(substr($sep_thous, 0, 2) == '[['){
+            $sep_thous = FEEDBACK_THOUSAND;
+        }
+       
+        $analysedItem = $this->get_analysed($item, $groupid, $courseid);
+        if($analysedItem) {
+            $itemnr++;
+            $itemname = stripslashes($analysedItem[1]);
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . $itemname .'</th></tr>';
+            $analysedVals = $analysedItem[2];
+            $pixnr = 0;
+            foreach($analysedVals as $val) {
+                if( function_exists("bcmod")) {
+                    $intvalue = bcmod($pixnr, 10);
+                }else {
+                    $intvalue = 0;
+                }
+                $pix = "pics/$intvalue.gif";
+                $pixnr++;
+                $pixwidth = intval($val->quotient * FEEDBACK_MAX_PIX_LENGTH);
+                $quotient = number_format(($val->quotient * 100), 2, $sep_dec, $sep_thous);
+                echo '<tr><td align="left" valign="top">-&nbsp;&nbsp;' . trim($val->answertext) . ':</td><td align="left" style="width: '.FEEDBACK_MAX_PIX_LENGTH.'"><img alt="'.$intvalue.'" src="'.$pix.'" height="5" width="'.$pixwidth.'" />&nbsp;' . $val->answercount . (($val->quotient > 0)?'&nbsp;('. $quotient . '&nbsp;%)':'').'</td></tr>';
+            }
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+
+        $data = $analysed_item[2];
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        //frage schreiben
+        $worksheet->write_string($rowOffset, 0, stripslashes($analysed_item[1]));
+        if(is_array($data)) {
+            for($i = 0; $i < sizeof($data); $i++) {
+                $aData = $data[$i];
+             
+                $worksheet->setFormat("<l><f><ro2><vo><c:blue>");
+                $worksheet->write_string($rowOffset, $i + 1, trim($aData->answertext));
+             
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_number($rowOffset + 1, $i + 1, $aData->answercount);
+                $worksheet->setFormat("<l><f><vo><pr>");
+                $worksheet->write_number($rowOffset + 2, $i + 1, $aData->quotient);
+            }
+        }
+        $rowOffset +=3 ;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+       
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        //extract the adjustment-info
+        $presentation = $horizontal = '';
+        @list($presentation, $horizontal) = explode(FEEDBACK_CHECK_ADJUST_SEP, $item->presentation);
+        if(isset($horizontal) AND $horizontal == 1) {
+            $horizontal = true;
+        }else {
+            $horizontal = false;
+        }
+       
+        $presentation = explode (FEEDBACK_CHECK_LINE_SEP, stripslashes_safe($presentation));
+        if (is_array($value)) {
+            $values = $value;
+        }else {
+            $values = explode(FEEDBACK_CHECK_LINE_SEP, $value);
+        }
+        if($highlightrequire AND $item->required AND $values[0] == '') {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+        
+        echo '<td '.$highlight.' valign="top" align="'.$align.'">'.format_text(stripslashes_safe($item->name).$requiredmark, true, false, false).'</td>';
+        echo '<td valign="top" align="'.$align.'">';
+
+        $index = 1;
+        $checked = '';
+        if($readonly){
+            // print_simple_box_start($align);
+            print_box_start('generalbox boxalign'.$align);
+            foreach($presentation as $check){
+                foreach($values as $val) {
+                    if($val == $index){
+                        echo text_to_html($check . '<br />', true, false, false);
+                        break;
+                    }
+                }
+                $index++;
+            }
+            // print_simple_box_end();
+            print_box_end();
+        } else {
+            if($horizontal) {
+                echo '<table><tr>';
+            }
+            foreach($presentation as $check){
+                foreach($values as $val) {
+                    if($val == $index){
+                        $checked = 'checked="checked"';
+                        break;
+                    }else{
+                        $checked = '';
+                    }
+                }
+                $inputname = $item->typ. '_' . $item->id;
+                $inputid = $item->typ. '_' . $item->id.'_'.$index;
+                if($horizontal) {
+    ?>
+                    <td valign="top" align="<?php echo $align;?>"><input type="checkbox"
+                        name="<?php echo $inputname;?>[]"
+                        id="<?php echo $inputid;?>"
+                        value="<?php echo $index;?>" <?php echo $checked;?> />
+                    </td><td align="<?php echo $align;?>"><label for="<?php echo $inputid;?>"><?php echo text_to_html($check, true, false, false);?>&nbsp;</label>
+                    </td>
+    <?php         
+                }else {
+    ?>
+                    <table><tr>
+                    <td valign="top" align="<?php echo $align;?>"><input type="checkbox"
+                        name="<?php echo $inputname;?>[]"
+                        id="<?php echo $inputid;?>"
+                        value="<?php echo $index;?>" <?php echo $checked;?> />
+                    </td><td align="<?php echo $align;?>"><label for="<?php echo $inputid;?>"><?php echo text_to_html($check, true, false, false);?>&nbsp;</label>
+                    </td></tr></table>
+    <?php
+                }
+                $index++;
+            }
+            if($horizontal) {
+                echo '</tr></table>';
+            }
+        }
+    ?>
+            <input type="hidden" name="<?php echo $item->typ. '_' . $item->id?>[]" value="" />
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+       //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR !is_array($value) OR $value[0] == '' OR $value[0] == 0) AND $item->required != 1) return true;
+        if($value[0] == "")return false;
+        return true;
+    }
+
+    function create_value($data) {
+        $vallist = $data;
+        return trim($this->item_arrayToString($vallist));
+    }
+
+    function get_presentation($data) {
+        $present = str_replace("\n", FEEDBACK_CHECK_LINE_SEP, trim($data->itemvalues));
+        if($data->horizontal == 1) {
+            $present .= FEEDBACK_CHECK_ADJUST_SEP.'1';
+        }
+        return $present;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+
+    function item_arrayToString($arr) {
+        if(!is_array($arr)) {
+            return '';
+        }
+        $retval = '';
+        $arrvals = array_values($arr);
+        $arrvals = clean_param($arrvals, PARAM_INT);  //prevent sql-injection
+        $retval = $arrvals[0];
+        for($i = 1; $i < sizeof($arrvals) - 1; $i++) {
+            $retval .= FEEDBACK_CHECK_LINE_SEP.$arrvals[$i];
+        }
+        return $retval;
+    }
+}
+?>
diff --git a/mod/feedback/item/dropdown/lib.php b/mod/feedback/item/dropdown/lib.php
new file mode 100644 (file)
index 0000000..c92b6ec
--- /dev/null
@@ -0,0 +1,233 @@
+<?PHP  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+class feedback_item_dropdown extends feedback_item_base {
+    var $type = "dropdown";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation=empty($item->presentation)?'':$item->presentation;
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('dropdown', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php 
+                $item->required=isset($item->required)?$item->required:0;
+                echo ($item->required == 1?'checked="checked"':'');
+                ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td>
+                    <?php print_string('dropdown_values', 'feedback');?>
+                    <?php print_string('use_one_line_for_each_value', 'feedback');?>
+                </td>
+                <td>
+    <?php
+                    $itemvalues = str_replace('|', "\n", stripslashes_safe($item->presentation));
+    ?>
+                    <textarea name="itemvalues" cols="30" rows="5"><?php echo $itemvalues;?></textarea>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert ein eindimensionales Array mit drei Werten(typ, name, XXX)
+    //XXX ist ein eindimensionales Array (anzahl der Antworten bei Typ DropDown) Jedes Element ist eine Struktur (answertext, answercount)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        $analysedItem = array();
+        $analysedItem[] = $item->typ;
+        $analysedItem[] = $item->name;
+        //die moeglichen Antworten extrahieren
+        $answers = null;
+        $answers = explode ("|", stripslashes_safe($item->presentation));
+        if(!is_array($answers)) return null;
+
+        //die Werte holen
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if(!$values) return null;
+        //schleife ueber den Werten und ueber die Antwortmoeglichkeiten
+        
+        $analysedAnswer = array();
+
+        for($i = 1; $i <= sizeof($answers); $i++) {
+            $ans = null;
+            $ans->answertext = $answers[$i-1];
+            $ans->answercount = 0;
+            foreach($values as $value) {
+                //ist die Antwort gleich dem index der Antworten + 1?
+                if ($value->value == $i) {
+                    $ans->answercount++;
+                }
+            }
+            $ans->quotient = $ans->answercount / sizeof($values);
+            $analysedAnswer[] = $ans;
+        }
+        $analysedItem[] = $analysedAnswer;
+        return $analysedItem;
+    }
+
+    function get_printval($item, $value) {
+        $printval = '';
+        
+        if(!isset($value->value)) return $printval;
+
+        $presentation = explode ("|", stripslashes_safe($item->presentation));
+        $index = 1;
+        foreach($presentation as $pres){
+            if($value->value == $index){
+                $printval = $pres;
+                break;
+            }
+            $index++;
+        }
+        return $printval;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $sep_dec = get_string('separator_decimal', 'feedback');
+        if(substr($sep_dec, 0, 2) == '[['){
+            $sep_dec = FEEDBACK_DECIMAL;
+        }
+        
+        $sep_thous = get_string('separator_thousand', 'feedback');
+        if(substr($sep_thous, 0, 2) == '[['){
+            $sep_thous = FEEDBACK_THOUSAND;
+        }
+        
+        $analysedItem = $this->get_analysed($item, $groupid, $courseid);
+        if($analysedItem) {
+            //echo '<table>';
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . stripslashes($analysedItem[1]) .'</th></tr>';
+            $analysedVals = $analysedItem[2];
+            $pixnr = 0;
+            foreach($analysedVals as $val) {
+                if( function_exists("bcmod")) {
+                    $intvalue = bcmod($pixnr, 10);
+                }else {
+                    $intvalue = 0;
+                }
+                $pix = "pics/$intvalue.gif";
+                $pixnr++;
+                $pixwidth = intval($val->quotient * FEEDBACK_MAX_PIX_LENGTH);
+                $quotient = number_format(($val->quotient * 100), 2, $sep_dec, $sep_thous);
+                echo '<tr><td valign="top" align="left">-&nbsp;&nbsp;' . trim($val->answertext) . ':</td><td align="left" style="width: '.FEEDBACK_MAX_PIX_LENGTH.'"><img alt="'.$intvalue.'" src="'.$pix.'" height="5" width="'.$pixwidth.'" />&nbsp;' . $val->answercount . (($val->quotient > 0)?'&nbsp;('. $quotient . '&nbsp;%)':'').'</td></tr>';
+            }
+            //echo '</table>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+
+        $data = $analysed_item[2];
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        //frage schreiben
+        $worksheet->write_string($rowOffset, 0, stripslashes($analysed_item[1]));
+        if(is_array($data)) {
+            for($i = 0; $i < sizeof($data); $i++) {
+                $aData = $data[$i];
+                
+                $worksheet->setFormat("<l><f><ro2><vo><c:blue>");
+                $worksheet->write_string($rowOffset, $i + 1, trim($aData->answertext));
+                
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_number($rowOffset + 1, $i + 1, $aData->answercount);
+                $worksheet->setFormat("<l><f><vo><pr>");
+                $worksheet->write_number($rowOffset + 2, $i + 1, $aData->quotient);
+            }
+        }
+        $rowOffset +=3 ;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        $presentation = explode ("|", stripslashes_safe($item->presentation));
+        if($highlightrequire AND $item->required AND intval($value) <= 0) {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>"><?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?></td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        $index = 1;
+        $selected = '';
+        if($readonly){
+            foreach($presentation as $dropdown){
+                if($value == $index){
+                    // print_simple_box_start($align);
+                    print_box_start('generalbox boxalign'.$align);
+                    echo text_to_html($dropdown, true, false, false);
+                    // print_simple_box_end();
+                    print_box_end();
+                    break;
+                }
+                $index++;
+            }
+        } else {
+    ?>
+            <select name="<?php echo $item->typ .'_' . $item->id;?>" size="1">
+                <option value="0">&nbsp;</option>
+    <?php
+            foreach($presentation as $dropdown){
+                if($value == $index){
+                    $selected = 'selected="selected"';
+                }else{
+                    $selected = '';
+                }
+    ?>
+                <option value="<?php echo $index;?>" <?php echo $selected;?>><?php echo text_to_html($dropdown, true, false, false);?></option>
+    <?php
+                $index++;
+            }
+    ?>
+            </select>
+    <?php
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '' OR $value == 0) AND $item->required != 1) return true;
+        if($value == 0)return false;
+        return true;
+    }
+
+    function create_value($data) {
+        $data = clean_param($data, PARAM_INT);
+        return $data;
+    }
+
+    function get_presentation($data) {
+        $present = str_replace("\n", '|', trim($data->itemvalues));
+        return $present;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/dropdownrated/lib.php b/mod/feedback/item/dropdownrated/lib.php
new file mode 100644 (file)
index 0000000..223a6d2
--- /dev/null
@@ -0,0 +1,303 @@
+<?PHP  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+define('FEEDBACK_DROPDOWNRATED_MAXCOUNT', 10); //count of possible items
+define('FEEDBACK_DROPDOWN_LINE_SEP', '|');
+define('FEEDBACK_DROPDOWN_VALUE_SEP', '####');
+
+
+class feedback_item_dropdownrated extends feedback_item_base {
+    var $type = "dropdownrated";
+    function init() {
+
+    }
+
+    function show_edit($item, $usehtmleditor = false) {
+
+         $item->presentation=empty($item->presentation)?'':$item->presentation;
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('dropdownrated', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php
+                         $item->required=isset($item->required)?$item->required:0;
+                         echo ($item->required == 1?'checked="checked"':'');
+                         ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td>
+                    <?php print_string('dropdown_values', 'feedback');?>
+                </td>
+                <td>
+    <?php
+                    //$itemvalues = str_replace('|', "\n", stripslashes_safe($item->presentation));
+                    if($itemvalues = explode(FEEDBACK_DROPDOWN_LINE_SEP, stripslashes_safe($item->presentation), FEEDBACK_DROPDOWNRATED_MAXCOUNT)){
+                        echo '<table>';
+                        echo '<tr>';
+                        echo '<td><b>'.get_string('line_values', 'feedback').'</b></td><td><b>'.get_string('line_labels', 'feedback').'</b></td>';
+                        echo '</tr>';
+                        for ($i = 0; $i < FEEDBACK_DROPDOWNRATED_MAXCOUNT; $i++) {
+                            if(count($itemvalues) > $i) { 
+                                $value = explode(FEEDBACK_DROPDOWN_VALUE_SEP, $itemvalues[$i]);
+                                if(count($value) <= 1) {
+                                    $value[0] = ''; $value[1] = '';
+                                }
+                            }else {
+                                $value[0] = ''; $value[1] = '';
+                            }
+                            echo '<tr>';
+                            echo '<td><input type="text" name="fr_val[]" size="4" maxlength="4" value="'.$value[0].'" /></td>';
+                            echo '<td><input type="text" name="fr_label[]" size="40" maxlength="255" value="'.$value[1].'" /></td>';
+                            echo '</tr>';
+                        }
+                        echo '</table>';
+                    }
+                    
+    ?>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert ein eindimensionales Array mit drei Werten(typ, name, XXX)
+    //XXX ist ein eindimensionales Array (Mittelwert der Werte der Antworten bei Typ dropdown_rated) Jedes Element ist eine Struktur (answertext, avg)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        $analysedItem = array();
+        $analysedItem[] = $item->typ;
+        $analysedItem[] = $item->name;
+        //die moeglichen Antworten extrahieren
+        $lines = null;
+        $lines = explode (FEEDBACK_DROPDOWN_LINE_SEP, stripslashes_safe($item->presentation));
+        if(!is_array($lines)) return null;
+
+        //die Werte holen
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if(!$values) return null;
+        //schleife ueber den Werten und ueber die Antwortmoeglichkeiten
+        
+        $analysedAnswer = array();
+
+        for($i = 1; $i <= sizeof($lines); $i++) {
+            $item_values = explode(FEEDBACK_DROPDOWN_VALUE_SEP, $lines[$i-1]);
+            $ans = null;
+            $ans->answertext = $item_values[1];
+            $avg = 0.0;
+            $anscount = 0;
+            foreach($values as $value) {
+                //ist die Antwort gleich dem index der Antworten + 1?
+                if ($value->value == $i) {
+                    $avg += $item_values[0]; //erst alle Werte aufsummieren
+                    $anscount++;
+                }
+            }
+            $ans->answercount = $anscount;
+            $ans->avg = doubleval($avg) / doubleval(sizeof($values));
+            $ans->value = $item_values[0];
+            $ans->quotient = $ans->answercount / sizeof($values);
+            $analysedAnswer[] = $ans;
+        }
+        $analysedItem[] = $analysedAnswer;
+        return $analysedItem;
+    }
+
+    function get_printval($item, $value) {
+        $printval = '';
+        
+        if(!isset($value->value)) return $printval;
+        
+        $presentation = explode (FEEDBACK_DROPDOWN_LINE_SEP, stripslashes_safe($item->presentation));
+        $index = 1;
+        foreach($presentation as $pres){
+            if($value->value == $index){
+                $dropdown_label = explode(FEEDBACK_DROPDOWN_VALUE_SEP, $pres);
+                $printval = $dropdown_label[1];
+                break;
+            }
+            $index++;
+        }
+        return $printval;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $sep_dec = get_string('separator_decimal', 'feedback');
+        if(substr($sep_dec, 0, 2) == '[['){
+            $sep_dec = FEEDBACK_DECIMAL;
+        }
+        
+        $sep_thous = get_string('separator_thousand', 'feedback');
+        if(substr($sep_thous, 0, 2) == '[['){
+            $sep_thous = FEEDBACK_THOUSAND;
+        }
+            
+        $analysedItem = $this->get_analysed($item, $groupid, $courseid);
+        if($analysedItem) {
+            //echo '<table>';
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . stripslashes($analysedItem[1]) .'</th></tr>';
+            $analysedVals = $analysedItem[2];
+            $pixnr = 0;
+            $avg = 0.0;
+            foreach($analysedVals as $val) {
+                if( function_exists("bcmod")) {
+                    $intvalue = bcmod($pixnr, 10);
+                }else {
+                    $intvalue = 0;
+                }
+                $pix = "pics/$intvalue.gif";
+                $pixnr++;
+                $pixwidth = intval($val->quotient * FEEDBACK_MAX_PIX_LENGTH);
+                
+                $avg += $val->avg;
+                $quotient = number_format(($val->quotient * 100), 2, $sep_dec, $sep_thous);
+                echo '<tr><td align="left" valign="top">-&nbsp;&nbsp;' . trim($val->answertext) . ' ('.$val->value.'):</td><td align="left" style="width: '.FEEDBACK_MAX_PIX_LENGTH.'"><img alt="'.$intvalue.'" src="'.$pix.'" height="5" width="'.$pixwidth.'" />' . $val->answercount. (($val->quotient > 0)?'&nbsp;('. $quotient . '&nbsp;%)':'') . '</td></tr>';
+            }
+            $avg = number_format(($avg), 2, $sep_dec, $sep_thous);
+            echo '<tr><td align="left" colspan="2"><b>'.get_string('average', 'feedback').': '.$avg.'</b></td></tr>';
+            //echo '</table>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+
+        $data = $analysed_item[2];
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        //frage schreiben
+        $worksheet->write_string($rowOffset, 0, stripslashes($analysed_item[1]));
+        if(is_array($data)) {
+            $avg = 0.0;
+            for($i = 0; $i < sizeof($data); $i++) {
+                $aData = $data[$i];
+                
+                $worksheet->setFormat("<l><f><ro2><vo><c:blue>");
+                $worksheet->write_string($rowOffset, $i + 1, trim($aData->answertext).' ('.$aData->value.')');
+                
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_number($rowOffset + 1, $i + 1, $aData->answercount);
+                //$worksheet->setFormat("<l><f><vo>");
+                //$worksheet->write_number($rowOffset + 2, $i + 1, $aData->avg);
+                $avg += $aData->avg;
+            }
+            //mittelwert anzeigen
+            $worksheet->setFormat("<l><f><ro2><vo><c:red>");
+            $worksheet->write_string($rowOffset, sizeof($data) + 1, get_string('average', 'feedback'));
+            
+            $worksheet->setFormat("<l><f><vo>");
+            $worksheet->write_number($rowOffset + 1, sizeof($data) + 1, $avg);
+        }
+        $rowOffset +=2 ;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        $lines = explode (FEEDBACK_DROPDOWN_LINE_SEP, stripslashes_safe($item->presentation));
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+        if($highlightrequire AND $item->required AND intval($value) <= 0) {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>"><?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?></td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        $index = 1;
+        $selected = '';
+        if($readonly){
+            foreach($lines as $line){
+                if($value == $index){
+                    $dropdown_value = explode(FEEDBACK_DROPDOWN_VALUE_SEP, $line);
+                    // print_simple_box_start($align);
+                    print_box_start('generalbox boxalign'.$align);
+                    echo text_to_html($dropdown_value[1], true, false, false);
+                    // print_simple_box_end();
+                    print_box_end();
+                    break;
+                }
+                $index++;
+            }
+        } else {
+            echo '<select name="'. $item->typ . '_' . $item->id . '">';
+            echo '<option value="0">&nbsp;</option>';
+            foreach($lines as $line){
+                if($value == $index){
+                    $selected = 'selected="selected"';
+                }else{
+                    $selected = '';
+                }
+                $dropdown_value = explode(FEEDBACK_DROPDOWN_VALUE_SEP, $line);
+                if($edit) {
+                    echo '<option value="'. $index.'" '. $selected.'>'. clean_text('('.$dropdown_value[0].') '.$dropdown_value[1]).'</option>';
+                }else {
+                    echo '<option value="'. $index.'" '. $selected.'>'. clean_text($dropdown_value[1]).'</option>';
+                }
+                $index++;
+            }
+            echo '</select>';
+            /*
+            if($item->required == 1) {
+                echo '<input type="hidden" name="'.$item->typ . '_' . $item->id.'" value="1" />';
+            }
+            */
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '' OR $value == 0) AND $item->required != 1) return true;
+        if(intval($value) > 0)return true;
+        return false;
+    }
+
+    function create_value($data) {
+        $data = clean_param($data, PARAM_INT);
+        return $data;
+    }
+
+    function get_presentation($data) {
+        $valuelines = $data->fr_val;
+        $labellines = $data->fr_label;
+        $present = '';
+        if(!is_array($valuelines) AND !is_array($labellines)) {
+            return $present;
+        }
+        
+        //if( trim($valuelines[0]) != ''){
+            $value = intval($valuelines[0]);
+            $label = $labellines[0];
+            $present .= $value.FEEDBACK_DROPDOWN_VALUE_SEP.$label;
+        //}
+        
+        for($i = 1; $i < FEEDBACK_DROPDOWNRATED_MAXCOUNT; $i++) {
+            if( (trim($valuelines[$i]) == '') AND (trim($labellines[$i]) == ''))continue;
+            
+            $value = intval($valuelines[$i]);
+            $label = $labellines[$i];
+            $present .= FEEDBACK_DROPDOWN_LINE_SEP.$value.FEEDBACK_DROPDOWN_VALUE_SEP.$label;
+        }
+        //$present = str_replace("\n", '|', trim($data->itemvalues));
+        return $present;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/feedback_item_class.php b/mod/feedback/item/feedback_item_class.php
new file mode 100644 (file)
index 0000000..1047fa7
--- /dev/null
@@ -0,0 +1,94 @@
+<?PHP  // $Id$
+
+class feedback_item_base {
+    var $type;
+    /**
+     * The class constructor
+     *
+     */
+    function feedback_item_base() {
+        $this->init();
+    }
+
+    /**
+     * Fake constructor to keep PHP5 happy
+     *
+     */
+    function __construct() {
+        $this->feedback_item_base();
+    }
+    
+    /**
+     * prints the item-related sequenz on the edit-item form
+     * 
+     * @param $item the db-object from feedback_item
+     * @param $usehtmleditor defines whether the editor should be shown or not
+     */
+    function show_edit($item, $usehtmleditor = false) {
+    }
+
+    /**
+     * returns an Array with three values(typ, name, XXX)
+     * XXX is also an Array (count of responses on type $this->type)
+     * each element is a structure (answertext, answercount)
+     * @param $item the db-object from feedback_item
+     * @param $groupid if given
+     * @param $courseid if given
+     * @return array
+    */
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        return array();
+    }
+
+    /**
+     * @param object $item the db-object from feedback_item
+     * @param string $value a item-related value from feedback_values
+     * @return string
+    */
+    function get_printval($item, $value) {
+      return '';
+    }
+
+    /**
+     * @param $item the db-object from feedback_item
+     * @param integer $itemnr
+     * @param integer $groupid
+     * @param integer $courseid
+     * @return integer the new itemnr
+    */
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+      return 0;
+    }
+
+    /**
+     * @param object $worksheet a reference to the pear_spreadsheet-object
+     * @param integer $rowOffset
+     * @param object $item the db-object from feedback_item
+     * @param integer $groupid
+     * @param integer $courseid
+     * @return integer the new rowOffset
+    */
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+      return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+    }
+
+    function check_value($value, $item) {
+        return true;
+    }
+
+    function create_value($data) {
+        return '';
+    }
+
+    function get_presentation($data) {
+      return '';
+   }
+
+    function get_hasvalue() {
+        return 0;
+    }
+}
+?>
diff --git a/mod/feedback/item/label/lib.php b/mod/feedback/item/label/lib.php
new file mode 100644 (file)
index 0000000..7a9d76b
--- /dev/null
@@ -0,0 +1,44 @@
+<?PHP  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+class feedback_item_label extends feedback_item_base {
+    var $type = "label";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+        $item->presentation=isset($item->presentation)?$item->presentation:'';
+        print_string('label', 'feedback');
+        echo '<br />';
+        print_textarea($usehtmleditor, 20, 0, 0, 0, "presentation", $item->presentation);
+        echo '<input type="hidden" id="itemname" name="itemname" value="label" />';
+
+        if ($usehtmleditor) {
+            use_html_editor();
+        }
+    }
+    function print_item($item){
+    ?>
+        <td colspan="2">
+            <?php echo format_text($item->presentation);?>
+        </td>
+    <?php
+    }
+
+    function create_value($data) {
+        return false;
+    }
+
+    //used by create_item and update_item functions,
+    //when provided $data submitted from feedback_show_edit
+    function get_presentation($data) {
+        return stripslashes($data->presentation);
+    }
+
+    function get_hasvalue() {
+        return 0;
+    }
+}
+?>
\ No newline at end of file
diff --git a/mod/feedback/item/numeric/lib.php b/mod/feedback/item/numeric/lib.php
new file mode 100644 (file)
index 0000000..6e65f6d
--- /dev/null
@@ -0,0 +1,238 @@
+<?php  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+class feedback_item_numeric extends feedback_item_base {
+    var $type = "numeric";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation=empty($item->presentation)?'':$item->presentation;
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('numeric', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php 
+                $item->required=isset($item->required)?$item->required:0;
+                echo ($item->required == 1?'checked="checked"':'');
+                ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <?php
+                        //Dropdown-Items fuer die Textfeldbreite
+                        $range_from_to = explode('|',$item->presentation);
+                        $range_from = isset($range_from_to[0]) ? intval($range_from_to[0]) : 0;
+                        $range_to = isset($range_from_to[1]) ? intval($range_from_to[1]) : 0;
+                ?>
+                <td><?php print_string('numeric_range_from', 'feedback');?></td>
+                <td>
+                    <input type="text" name="numericrangefrom" value="<?php echo $range_from;?>" />
+                </td>
+            </tr>
+            <tr>
+                <td><?php print_string('numeric_range_to', 'feedback');?></td>
+                <td>
+                    <input type="text" name="numericrangeto" value="<?php echo $range_to;?>" />
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert eine Struktur ->name, ->data = array(mit Antworten)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        $analysed = null;
+        $analysed->data = array();
+        $analysed->name = $item->name;
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        
+        $avg = 0.0;
+        $counter = 0;
+        if($values) {
+            $data = array();
+            foreach($values as $value) {
+                if(is_numeric($value->value)) {
+                    $data[] = $value->value;
+                    $avg += $value->value;
+                    $counter++;
+                }
+            }
+            $avg = $counter > 0 ? $avg / $counter : 0;
+            $analysed->data = $data;
+            $analysed->avg = $avg;
+        }
+        return $analysed;
+    }
+
+    function get_printval($item, $value) {
+        if(!isset($value->value)) return '';
+        
+        return $value->value;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $sep_dec = get_string('separator_decimal', 'feedback');
+        if(substr($sep_dec, 0, 2) == '[['){
+            $sep_dec = FEEDBACK_DECIMAL;
+        }
+        
+        $sep_thous = get_string('separator_thousand', 'feedback');
+        if(substr($sep_thous, 0, 2) == '[['){
+            $sep_thous = FEEDBACK_THOUSAND;
+        }
+        
+        // $values = feedback_get_group_values($item, $groupid, $courseid);
+        $values = $this->get_analysed($item, $groupid, $courseid);
+
+        if(isset($values->data) AND is_array($values->data)) {
+            //echo '<table>';2
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . stripslashes($item->name) .'</th></tr>';
+            foreach($values->data as $value) {
+                echo '<tr><td colspan="2" valign="top" align="left">-&nbsp;&nbsp;' . $value . '</td></tr>';
+            }
+            //echo '</table>';
+            $avg = number_format($values->avg, 2, $sep_dec, $sep_thous);
+            echo '<tr><td align="left" colspan="2"><b>'.get_string('average', 'feedback').': '.$avg.'</b></td></tr>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        $worksheet->write_string($rowOffset, 0, stripslashes($item->name));
+        $data = $analysed_item->data;
+        if(is_array($data)) {
+            // $worksheet->setFormat("<l><ro2><vo>");
+            // $worksheet->write_number($rowOffset, 1, $data[0]);
+            // $rowOffset++;
+            // for($i = 1; $i < sizeof($data); $i++) {
+                // $worksheet->setFormat("<l><vo>");
+                // $worksheet->write_number($rowOffset, 1, $data[$i]);
+                // $rowOffset++;
+            // }
+        
+            //mittelwert anzeigen
+            $worksheet->setFormat("<l><f><ro2><vo><c:red>");
+            $worksheet->write_string($rowOffset, 1, get_string('average', 'feedback'));
+            
+            $worksheet->setFormat("<l><f><vo>");
+            $worksheet->write_number($rowOffset + 1, 1, $analysed_item->avg);
+            $rowOffset++;
+        }
+        $rowOffset++;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        //get the range
+        $range_from_to = explode('|',$item->presentation);
+        //get the min-value
+        $range_from = isset($range_from_to[0]) ? intval($range_from_to[0]) : 0;
+        //get the max-value
+        $range_to = isset($range_from_to[1]) ? intval($range_from_to[1]) : 0;
+        if($highlightrequire AND (!$this->check_value($value, $item))) {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>">
+            <?php 
+                echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);
+                switch(true) {
+                    case ($range_from === 0 AND $range_to > 0):
+                        echo ' ('.get_string('maximal', 'feedback').': '.$range_to.')';
+                        break;
+                    case ($range_from > 0 AND $range_to === 0):
+                        echo ' ('.get_string('minimal', 'feedback').': '.$range_from.')';
+                        break;
+                    case ($range_from === 0 AND $range_to === 0):
+                        break;
+                    default:
+                        echo ' ('.$range_from.'-'.$range_to.')';
+                        break;
+                }
+            ?>
+        </td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        if($readonly){
+            // print_simple_box_start($align);
+            print_box_start('generalbox boxalign'.$align);
+            echo $value ? $value : '&nbsp;';
+            // print_simple_box_end();
+            print_box_end();
+        }else {
+    ?>
+            <input type="text" name="<?php echo $item->typ.'_'.$item->id; ?>"
+                                    size="10"
+                                    maxlength="10"
+                                    value="<?php echo $value ? $value : ''; ?>" />
+    <?php
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '') AND $item->required != 1) return true;
+        if(!is_numeric($value))return false;
+        
+        $range_from_to = explode('|',$item->presentation);
+        $range_from = isset($range_from_to[0]) ? intval($range_from_to[0]) : 0;
+        $range_to = isset($range_from_to[1]) ? intval($range_from_to[1]) : 0;
+        
+        switch(true) {
+            case ($range_from === 0 AND $range_to > 0):
+                if(intval($value) <= $range_to) return true;
+                break;
+            case ($range_from > 0 AND $range_to === 0):
+                if(intval($value) >= $range_from) return true;
+                break;
+            case ($range_from === 0 AND $range_to === 0):
+                return true;
+                break;
+            default:
+                if(intval($value) >= $range_from AND intval($value) <= $range_to) return true;
+                break;
+        }
+        
+        return false;
+    }
+
+    function create_value($data) {
+        if($data AND $data != '') {
+            $data = intval($data);
+        }else {
+            $data = '';
+        }
+        return $data;
+    }
+
+    function get_presentation($data) {
+        return $data->numericrangefrom . '|'. $data->numericrangeto;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/radio/lib.php b/mod/feedback/item/radio/lib.php
new file mode 100644 (file)
index 0000000..0cb2fc9
--- /dev/null
@@ -0,0 +1,307 @@
+<?php  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+define('FEEDBACK_RADIO_LINE_SEP', '|');
+define('FEEDBACK_RADIO_ADJUST_SEP', '<<<<<');
+
+class feedback_item_radio extends feedback_item_base {
+    var $type = "radio";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation = empty($item->presentation) ? '' : $item->presentation;
+        
+        //check, whether the buttons are vertical or horizontal
+        $presentation = $horizontal = '';
+        @list($presentation, $horizontal) = explode(FEEDBACK_RADIO_ADJUST_SEP, $item->presentation);
+        if(isset($horizontal) AND $horizontal == 1) {
+            $horizontal = true;
+        }else {
+            $horizontal = false;
+        }
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('radio', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php
+                    $item->required=isset($item->required)?$item->required:0;
+                    echo ($item->required == 1?'checked="checked"':'');
+                    ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <?php print_string('adjustment', 'feedback');?>:
+                    &nbsp;<?php print_string('vertical', 'feedback');?><input type="radio" name="horizontal" value="0" <?php echo $horizontal ? '' : 'checked="checked"';?> />
+                    &nbsp;<?php print_string('horizontal', 'feedback');?><input type="radio" name="horizontal" value="1" <?php echo $horizontal ? 'checked="checked"' : '';?> />
+                </td>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td>
+                    <?php print_string('radio_values', 'feedback');?>
+                    <?php print_string('use_one_line_for_each_value', 'feedback');?>
+                </td>
+                <td>
+    <?php
+                    $itemvalues = str_replace(FEEDBACK_RADIO_LINE_SEP, "\n", stripslashes_safe($presentation));
+    ?>
+                    <textarea name="itemvalues" cols="30" rows="5"><?php echo $itemvalues;?></textarea>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert ein eindimensionales Array mit drei Werten(typ, name, XXX)
+    //XXX ist ein eindimensionales Array (anzahl der Antworten bei Typ Radio) Jedes Element ist eine Struktur (answertext, answercount)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        //fuer den Anfang erstmal nur die Radiobuttons
+        $analysedItem = array();
+        $analysedItem[] = $item->typ;
+        $analysedItem[] = $item->name;
+        //die moeglichen Antworten extrahieren
+        $answers = null;
+        $presentation = '';
+        @list($presentation) = explode(FEEDBACK_RADIO_ADJUST_SEP, $item->presentation); //remove the adjustment-info
+        
+        $answers = explode (FEEDBACK_RADIO_LINE_SEP, stripslashes_safe($presentation));
+        if(!is_array($answers)) return null;
+
+        //die Werte holen
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if(!$values) return null;
+        //schleife ueber den Werten und ueber die Antwortmoeglichkeiten
+        
+        $analysedAnswer = array();
+
+        for($i = 1; $i <= sizeof($answers); $i++) {
+            $ans = null;
+            $ans->answertext = $answers[$i-1];
+            $ans->answercount = 0;
+            foreach($values as $value) {
+                //ist die Antwort gleich dem index der Antworten + 1?
+                if ($value->value == $i) {
+                    $ans->answercount++;
+                }
+            }
+            $ans->quotient = $ans->answercount / sizeof($values);
+            $analysedAnswer[] = $ans;
+        }
+        $analysedItem[] = $analysedAnswer;
+        return $analysedItem;
+    }
+
+    function get_printval($item, $value) {
+        $printval = '';
+        
+        if(!isset($value->value)) return $printval;
+                
+        @list($presentation) = explode(FEEDBACK_RADIO_ADJUST_SEP, $item->presentation); //remove the adjustment-info
+        
+        $presentation = explode (FEEDBACK_RADIO_LINE_SEP, stripslashes_safe($presentation));
+        $index = 1;
+        foreach($presentation as $pres){
+            if($value->value == $index){
+                $printval = $pres;
+                break;
+            }
+            $index++;
+        }
+        return $printval;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $sep_dec = get_string('separator_decimal', 'feedback');
+        if(substr($sep_dec, 0, 2) == '[['){
+            $sep_dec = FEEDBACK_DECIMAL;
+        }
+        
+        $sep_thous = get_string('separator_thousand', 'feedback');
+        if(substr($sep_thous, 0, 2) == '[['){
+            $sep_thous = FEEDBACK_THOUSAND;
+        }
+            
+        $analysedItem = $this->get_analysed($item, $groupid, $courseid);
+        if($analysedItem) {
+            //echo '<table>';
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . $analysedItem[1] .'</th></tr>';
+            $analysedVals = $analysedItem[2];
+            $pixnr = 0;
+            foreach($analysedVals as $val) {
+                if( function_exists("bcmod")) {
+                    $intvalue = bcmod($pixnr, 10);
+                }else {
+                    $intvalue = 0;
+                }
+                $pix = "pics/$intvalue.gif";
+                $pixnr++;
+                $pixwidth = intval($val->quotient * FEEDBACK_MAX_PIX_LENGTH);
+                $quotient = number_format(($val->quotient * 100), 2, $sep_dec, $sep_thous);
+                echo '<tr><td align="left" valign="top">-&nbsp;&nbsp;' . trim($val->answertext) . ':</td><td align="left" style="width: '.FEEDBACK_MAX_PIX_LENGTH.'"><img alt="'.$intvalue.'" src="'.$pix.'" height="5" width="'.$pixwidth.'" />&nbsp;' . $val->answercount . (($val->quotient > 0)?'&nbsp;('. $quotient . '&nbsp;%)':'').'</td></tr>';
+            }
+            //echo '</table>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+
+        $data = $analysed_item[2];
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        //frage schreiben
+        $worksheet->write_string($rowOffset, 0, $analysed_item[1]);
+        if(is_array($data)) {
+            for($i = 0; $i < sizeof($data); $i++) {
+                $aData = $data[$i];
+                
+                $worksheet->setFormat("<l><f><ro2><vo><c:blue>");
+                $worksheet->write_string($rowOffset, $i + 1, trim($aData->answertext));
+                
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_number($rowOffset + 1, $i + 1, $aData->answercount);
+                $worksheet->setFormat("<l><f><vo><pr>");
+                $worksheet->write_number($rowOffset + 2, $i + 1, $aData->quotient);
+            }
+        }
+        $rowOffset +=3 ;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        //extract the adjustment-info
+        $presentation = $horizontal = '';
+        @list($presentation, $horizontal) = explode(FEEDBACK_RADIO_ADJUST_SEP, $item->presentation);
+        if(isset($horizontal) AND $horizontal == 1) {
+            $horizontal = true;
+        }else {
+            $horizontal = false;
+        }
+        
+        $presentation = explode (FEEDBACK_RADIO_LINE_SEP, stripslashes_safe($presentation));
+        if($highlightrequire AND $item->required AND intval($value) <= 0) {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>"><?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?></td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        $index = 1;
+        $checked = '';
+        if($readonly){
+            foreach($presentation as $radio){
+                if($value == $index){
+                    // print_simple_box_start($align);
+                    print_box_start('generalbox boxalign'.$align);
+                    echo text_to_html($radio, true, false, false);
+                    // print_simple_box_end();
+                    print_box_end();
+                    break;
+                }
+                $index++;
+            }
+        } else {
+    ?>
+            <table><tr>
+            <td valign="top" align="<?php echo $align;?>"><input type="radio"
+                    name="<?php echo $item->typ . '_' . $item->id ;?>"
+                    id="<?php echo $item->typ . '_' . $item->id.'_xxx';?>"
+                    value="" <?php echo $value ? '' : 'checked="checked"';?> />
+            </td>
+            <td align="<?php echo $align;?>">
+                <label for="<?php echo $item->typ . '_' . $item->id.'_xxx';?>"><?php print_string('not_selected', 'feedback');?>&nbsp;</label>
+            </td>
+            </tr></table>
+    <?php
+            if($horizontal) {
+                echo '<table><tr>';
+            }
+            foreach($presentation as $radio){
+                if($value == $index){
+                    $checked = 'checked="checked"';
+                }else{
+                    $checked = '';
+                }
+                $inputname = $item->typ . '_' . $item->id;
+                $inputid = $inputname.'_'.$index;
+                if($horizontal) {
+    ?>
+                    <td valign="top" align="<?php echo $align;?>"><input type="radio"
+                        name="<?php echo $inputname;?>"
+                        id="<?php echo $inputid;?>"
+                        value="<?php echo $index;?>" <?php echo $checked;?> />
+                    </td>
+                    <td align="<?php echo $align;?>">
+                        <label for="<?php echo $inputid;?>"><?php echo text_to_html($radio, true, false, false);?>&nbsp;</label>
+                    </td>
+    <?php
+                }else {
+    ?>
+                    <table><tr>
+                    <td valign="top" align="<?php echo $align;?>"><input type="radio"
+                            name="<?php echo $inputname;?>"
+                            id="<?php echo $inputid;?>"
+                            value="<?php echo $index;?>" <?php echo $checked;?> />
+                    </td><td align="<?php echo $align;?>"><label for="<?php echo $inputid;?>"><?php echo text_to_html($radio, true, false, false);?>&nbsp;</label>
+                    </td></tr></table>
+    <?php
+                }
+                $index++;
+            }
+            if($horizontal) {
+                echo '</tr></table>';
+            }
+            /*
+            if($item->required == 1) {
+                echo '<input type="hidden" name="'.$item->typ . '_' . $item->id.'" value="1" />';
+            }
+            */
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '' OR $value == 0) AND $item->required != 1) return true;
+        if(intval($value) > 0)return true;
+        return false;
+    }
+
+    function create_value($data) {
+        $data = clean_param($data, PARAM_INT);
+        return $data;
+    }
+
+    function get_presentation($data) {
+        $present = str_replace("\n", FEEDBACK_RADIO_LINE_SEP, trim($data->itemvalues));
+        if($data->horizontal == 1) {
+            $present .= FEEDBACK_RADIO_ADJUST_SEP.'1';
+        }
+        return $present;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/radiorated/lib.php b/mod/feedback/item/radiorated/lib.php
new file mode 100644 (file)
index 0000000..18b4a96
--- /dev/null
@@ -0,0 +1,378 @@
+<?php  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+define('FEEDBACK_RADIORATED_MAXCOUNT', 10); //count of possible items
+define('FEEDBACK_RADIORATED_LINE_SEP', '|');
+define('FEEDBACK_RADIORATED_VALUE_SEP', '####');
+define('FEEDBACK_RADIORATED_ADJUST_SEP', '<<<<<');
+
+class feedback_item_radiorated extends feedback_item_base {
+    var $type = "radiorated";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation = empty($item->presentation) ? '' : $item->presentation;
+
+        //check, whether the buttons are vertical or horizontal
+        $presentation = $horizontal = '';
+        @list($presentation, $horizontal) = explode(FEEDBACK_RADIO_ADJUST_SEP, $item->presentation);
+        if(isset($horizontal) AND $horizontal == 1) {
+            $horizontal = true;
+        }else {
+            $horizontal = false;
+        }
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('radiorated', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php
+                    $item->required=isset($item->required)?$item->required:0;
+                    echo ($item->required == 1?'checked="checked"':'');
+                    ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td colspan="2">
+                    <?php print_string('adjustment', 'feedback');?>:
+                    &nbsp;<?php print_string('vertical', 'feedback');?><input type="radio" name="horizontal" value="0" <?php echo $horizontal ? '' : 'checked="checked"';?> />
+                    &nbsp;<?php print_string('horizontal', 'feedback');?><input type="radio" name="horizontal" value="1" <?php echo $horizontal ? 'checked="checked"' : '';?> />
+                </td>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td>
+                    <?php print_string('radio_values', 'feedback');?>
+                </td>
+                <td>
+    <?php
+                    //$itemvalues = str_replace('|', "\n", stripslashes_safe($item->presentation));
+                    if($itemvalues = explode(FEEDBACK_RADIORATED_LINE_SEP, stripslashes_safe($presentation), FEEDBACK_RADIORATED_MAXCOUNT)){
+                        echo '<table>';
+                        echo '<tr>';
+                        echo '<td><b>'.get_string('line_values', 'feedback').'</b></td><td><b>'.get_string('line_labels', 'feedback').'</b></td>';
+                        echo '</tr>';
+                        for ($i = 0; $i < FEEDBACK_RADIORATED_MAXCOUNT; $i++) {
+                            if(count($itemvalues) > $i) {
+                                $value = explode(FEEDBACK_RADIORATED_VALUE_SEP, $itemvalues[$i]);
+                                if(count($value) <= 1) {
+                                    $value[0] = ''; $value[1] = '';
+                                }
+                            }else {
+                                $value[0] = ''; $value[1] = '';
+                            }
+                            echo '<tr>';
+                            echo '<td><input type="text" name="fr_val[]" size="4" maxlength="4" value="'.$value[0].'" /></td>';
+                            echo '<td><input type="text" name="fr_label[]" size="40" maxlength="255" value="'.$value[1].'" /></td>';
+                            echo '</tr>';
+                        }
+                        echo '</table>';
+                    }
+                    
+    ?>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert ein eindimensionales Array mit drei Werten(typ, name, XXX)
+    //XXX ist ein eindimensionales Array (Mittelwert der Werte der Antworten bei Typ Radio_rated) Jedes Element ist eine Struktur (answertext, avg)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        $analysedItem = array();
+        $analysedItem[] = $item->typ;
+        $analysedItem[] = $item->name;
+        //die moeglichen Antworten extrahieren
+        $lines = null;
+        $presentation = '';
+        @list($presentation) = explode(FEEDBACK_RADIORATED_ADJUST_SEP, $item->presentation); //remove the adjustment-info
+        $lines = explode (FEEDBACK_RADIORATED_LINE_SEP, stripslashes_safe($presentation));
+        if(!is_array($lines)) return null;
+
+        //die Werte holen
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if(!$values) return null;
+        //schleife ueber den Werten und ueber die Antwortmoeglichkeiten
+        
+        $analysedAnswer = array();
+
+        for($i = 1; $i <= sizeof($lines); $i++) {
+            $item_values = explode(FEEDBACK_RADIORATED_VALUE_SEP, $lines[$i-1]);
+            $ans = null;
+            $ans->answertext = $item_values[1];
+            $avg = 0.0;
+            $anscount = 0;
+            foreach($values as $value) {
+                //ist die Antwort gleich dem index der Antworten + 1?
+                if ($value->value == $i) {
+                    $avg += $item_values[0]; //erst alle Werte aufsummieren
+                    $anscount++;
+                }
+            }
+            $ans->answercount = $anscount;
+            $ans->avg = doubleval($avg) / doubleval(sizeof($values));
+            $ans->value = $item_values[0];
+            $ans->quotient = $ans->answercount / sizeof($values);
+            $analysedAnswer[] = $ans;
+        }
+        $analysedItem[] = $analysedAnswer;
+        return $analysedItem;
+    }
+
+    function get_printval($item, $value) {
+        $printval = '';
+        
+        if(!isset($value->value)) return $printval;
+                
+        @list($presentation) = explode(FEEDBACK_RADIORATED_ADJUST_SEP, $item->presentation); //remove the adjustment-info
+
+        $presentation = explode (FEEDBACK_RADIORATED_LINE_SEP, stripslashes_safe($presentation));
+        $index = 1;
+        foreach($presentation as $pres){
+            if($value->value == $index){
+                $radio_label = explode(FEEDBACK_RADIORATED_VALUE_SEP, $pres);
+                $printval = $radio_label[1];
+                break;
+            }
+            $index++;
+        }
+        return $printval;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $sep_dec = get_string('separator_decimal', 'feedback');
+        if(substr($sep_dec, 0, 2) == '[['){
+            $sep_dec = FEEDBACK_DECIMAL;
+        }
+        
+        $sep_thous = get_string('separator_thousand', 'feedback');
+        if(substr($sep_thous, 0, 2) == '[['){
+            $sep_thous = FEEDBACK_THOUSAND;
+        }
+            
+        $analysedItem = $this->get_analysed($item, $groupid, $courseid);
+        if($analysedItem) {
+            //echo '<table>';
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . $analysedItem[1] .'</th></tr>';
+            $analysedVals = $analysedItem[2];
+            $pixnr = 0;
+            $avg = 0.0;
+            foreach($analysedVals as $val) {
+                
+                if( function_exists("bcmod")) {
+                    $intvalue = bcmod($pixnr, 10);
+                }else {
+                    $intvalue = 0;
+                }
+                $pix = "pics/$intvalue.gif";
+                $pixnr++;
+                $pixwidth = intval($val->quotient * FEEDBACK_MAX_PIX_LENGTH);
+                
+                $avg += $val->avg;
+                $quotient = number_format(($val->quotient * 100), 2, $sep_dec, $sep_thous);
+                echo '<tr><td align="left" valign="top">-&nbsp;&nbsp;' . trim($val->answertext) . ' ('.$val->value.'):</td><td align="left" style="width: '.FEEDBACK_MAX_PIX_LENGTH.'"><img alt="'.$intvalue.'" src="'.$pix.'" height="5" width="'.$pixwidth.'" />' . $val->answercount. (($val->quotient > 0)?'&nbsp;('. $quotient . '&nbsp;%)':'') . '</td></tr>';
+            }
+            $avg = number_format(($avg), 2, $sep_dec, $sep_thous);
+            echo '<tr><td align="left" colspan="2"><b>'.get_string('average', 'feedback').': '.$avg.'</b></td></tr>';
+            //echo '</table>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+
+        $data = $analysed_item[2];
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        //frage schreiben
+        $worksheet->write_string($rowOffset, 0, $analysed_item[1]);
+        if(is_array($data)) {
+            $avg = 0.0;
+            for($i = 0; $i < sizeof($data); $i++) {
+                $aData = $data[$i];
+                
+                $worksheet->setFormat("<l><f><ro2><vo><c:blue>");
+                $worksheet->write_string($rowOffset, $i + 1, trim($aData->answertext).' ('.$aData->value.')');
+                
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_number($rowOffset + 1, $i + 1, $aData->answercount);
+                //$worksheet->setFormat("<l><f><vo>");
+                //$worksheet->write_number($rowOffset + 2, $i + 1, $aData->avg);
+                $avg += $aData->avg;
+            }
+            //mittelwert anzeigen
+            $worksheet->setFormat("<l><f><ro2><vo><c:red>");
+            $worksheet->write_string($rowOffset, sizeof($data) + 1, get_string('average', 'feedback'));
+            
+            $worksheet->setFormat("<l><f><vo>");
+            $worksheet->write_number($rowOffset + 1, sizeof($data) + 1, $avg);
+        }
+        $rowOffset +=2 ;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        //extract the adjustment-info
+        $presentation = $horizontal = '';
+        @list($presentation, $horizontal) = explode(FEEDBACK_RADIORATED_ADJUST_SEP, $item->presentation);
+        if(isset($horizontal) AND $horizontal == 1) {
+            $horizontal = true;
+        }else {
+            $horizontal = false;
+        }
+        
+        $lines = explode (FEEDBACK_RADIORATED_LINE_SEP, stripslashes_safe($presentation));
+        if($highlightrequire AND $item->required AND intval($value) <= 0) {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>"><?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?></td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        $index = 1;
+        $checked = '';
+        if($readonly){
+            foreach($lines as $line){
+                if($value == $index){
+                    $radio_value = explode(FEEDBACK_RADIORATED_VALUE_SEP, $line);
+                    // print_simple_box_start('left');
+                    print_box_start('generalbox boxalign'.$align);
+                    echo text_to_html($radio_value[1], true, false, false);
+                    // print_simple_box_end();
+                    print_box_end();
+                    break;
+                }
+                $index++;
+            }
+        } else {
+    ?>
+            <table><tr>
+            <td valign="top" align="<?php echo $align;?>"><input type="radio"
+                    name="<?php echo $item->typ . '_' . $item->id ;?>"
+                    id="<?php echo $item->typ.'_'.$item->id.'_xxx';?>"
+                    value="" <?php echo $value ? '' : 'checked="checked"';?> />
+            </td>
+            <td align="<?php echo $align;?>">
+                <label for="<?php echo $item->typ.'_'.$item->id.'_xxx';?>"><?php print_string('not_selected', 'feedback');?>&nbsp;</label>
+            </td>
+            </tr></table>
+    <?php
+            if($horizontal) {
+                echo '<table><tr>';
+            }
+            foreach($lines as $line){
+                if($value == $index){
+                    $checked = 'checked="checked"';
+                }else{
+                    $checked = '';
+                }
+                $radio_value = explode(FEEDBACK_RADIORATED_VALUE_SEP, $line);
+                $inputname = $item->typ . '_' . $item->id;
+                $inputid = $inputname.'_'.$index;
+                if($horizontal) {
+    ?>
+                    <td valign="top" align="<?php echo $align;?>"><input type="radio"
+                            name="<?php echo $inputname;?>"
+                            id="<?php echo $inputid;?>"
+                            value="<?php echo $index;?>" <?php echo $checked;?> />
+                    </td><td align="<?php echo $align;?>"><label for="<?php echo $inputid;?>"><?php
+                                    if($edit) {
+                                        echo text_to_html('('.$radio_value[0].') '.$radio_value[1], true, false, false);
+                                    }else {
+                                        echo text_to_html($radio_value[1], true, false, false);
+                                    }
+                                ?>&nbsp;</label>
+                    </td>
+    <?php
+                }else {
+    ?>
+                    <table><tr>
+                    <td valign="top" align="<?php echo $align;?>"><input type="radio"
+                            name="<?php echo $inputname;?>"
+                            id="<?php echo $inputid;?>"
+                            value="<?php echo $index;?>" <?php echo $checked;?> />
+                    </td><td align="<?php echo $align;?>"><label for="<?php echo $inputid;?>"><?php
+                                    if($edit) {
+                                        echo text_to_html('('.$radio_value[0].') '.$radio_value[1], true, false, false);
+                                    }else {
+                                        echo text_to_html($radio_value[1], true, false, false);
+                                    }
+                                ?>&nbsp;</label>
+                    </td></tr></table>
+    <?php
+                }
+                $index++;
+            }
+            if($horizontal) {
+                echo '</tr></table>';
+            }
+            /*
+            if($item->required == 1) {
+                echo '<input type="hidden" name="'.$item->typ . '_' . $item->id.'" value="1" />';
+            }
+            */
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        if((!isset($value) OR $value == '' OR $value == 0) AND $item->required != 1) return true;
+        if(intval($value) > 0)return true;
+        return false;
+    }
+
+    function create_value($data) {
+        $data = clean_param($data, PARAM_INT);
+        return $data;
+    }
+
+    function get_presentation($data) {
+        $valuelines = $data->fr_val;
+        $labellines = $data->fr_label;
+        $present = '';
+        if(!is_array($valuelines) AND !is_array($labellines)) {
+            return $present;
+        }
+        
+        //if( trim($valuelines[0]) != ''){
+            $value = intval($valuelines[0]);
+            $label = $labellines[0];
+            $present .= $value.FEEDBACK_RADIORATED_VALUE_SEP.$label;
+        //}
+        
+        for($i = 1; $i < FEEDBACK_RADIORATED_MAXCOUNT; $i++) {
+            if( (trim($valuelines[$i]) == '') AND (trim($labellines[$i]) == ''))continue;
+            
+            $value = intval($valuelines[$i]);
+            $label = $labellines[$i];
+            $present .= FEEDBACK_RADIORATED_LINE_SEP.$value.FEEDBACK_RADIORATED_VALUE_SEP.$label;
+        }
+        //$present = str_replace("\n", '|', trim($data->itemvalues));
+        if($data->horizontal == 1) {
+            $present .= FEEDBACK_RADIORATED_ADJUST_SEP.'1';
+        }
+        return $present;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/textarea/lib.php b/mod/feedback/item/textarea/lib.php
new file mode 100644 (file)
index 0000000..8bbd1be
--- /dev/null
@@ -0,0 +1,166 @@
+<?php  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+class feedback_item_textarea extends feedback_item_base {
+    var $type = "textarea";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation=empty($item->presentation)?'':$item->presentation;
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('textarea', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php 
+                $item->required=isset($item->required)?$item->required:0;
+                echo ($item->required == 1?'checked="checked"':'');
+                ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td><?php print_string('textarea_width', 'feedback');?></td>
+                <td>
+                    <select name="itemwidth">
+    <?php
+                        //Dropdown-Items fuer die Textareabreite
+                        $widthAndHeight = explode('|',$item->presentation);
+                        feedback_print_numeric_option_list(5, 80, $widthAndHeight[0]?$widthAndHeight[0]:30, 5);
+    ?>
+                    </select>
+                </td>
+            </tr>
+            <tr>
+                <td><?php print_string('textarea_height', 'feedback');?></td>
+                <td>
+                    <select name="itemheight">
+    <?php
+                        //Dropdown-Items fuer die Textareahoehe
+                        feedback_print_numeric_option_list(5, 40, $widthAndHeight[1], 5);
+    ?>
+                    </select>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert eine Struktur ->name, ->data = array(mit Antworten)
+    function get_analysed($item, $groupid, $courseid = false) {
+        $aVal = null;
+        $aVal->data = array();
+        $aVal->name = $item->name;
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if($values) {
+            $data = array();
+            foreach($values as $value) {
+                $data[] = str_replace("\n", '<br />', $value->value);
+            }
+            $aVal->data = $data;
+        }
+        return $aVal;
+    }
+
+    function get_printval($item, $value) {
+        
+        if(!isset($value->value)) return '';
+
+        return $value->value;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if($values) {
+            //echo '<table>';2
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . stripslashes_safe($item->name) .'</th></tr>';
+            foreach($values as $value) {
+                echo '<tr><td valign="top" align="left">-&nbsp;&nbsp;</td><td align="left" valign="top">' . str_replace("\n", '<br />', $value->value) . '</td></tr>';
+            }
+            //echo '</table>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        $worksheet->write_string($rowOffset, 0, stripslashes_safe($item->name));
+        $data = $analysed_item->data;
+        if(is_array($data)) {
+            $worksheet->setFormat("<l><ro2><vo>");
+            $worksheet->write_string($rowOffset, 1, $data[0]);
+            $rowOffset++;
+            for($i = 1; $i < sizeof($data); $i++) {
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_string($rowOffset, 1, $data[$i]);
+                $rowOffset++;
+            }
+        }
+        $rowOffset++;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        $presentation = explode ("|", $item->presentation);
+        if($highlightrequire AND $item->required AND strval($value) == '') {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>"><?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?></td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        if($readonly){
+            // print_simple_box_start($align);
+            print_box_start('generalbox boxalign'.$align);
+            echo $value?str_replace("\n",'<br />',$value):'&nbsp;';
+            // print_simple_box_end();
+            print_box_end();
+        }else {
+    ?>
+            <textarea name="<?php echo $item->typ . '_' . $item->id;?>"
+                        cols="<?php echo $presentation[0];?>"
+                        rows="<?php echo $presentation[1];?>"><?php echo $value?htmlspecialchars($value):'';?></textarea>
+    <?php
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '') AND $item->required != 1) return true;
+        if($value == "")return false;
+        return true;
+    }
+
+    function create_value($data) {
+        $data = addslashes(clean_text($data));
+        return $data;
+    }
+
+    function get_presentation($data) {
+        return $data->itemwidth . '|'. $data->itemheight;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/item/textfield/lib.php b/mod/feedback/item/textfield/lib.php
new file mode 100644 (file)
index 0000000..a45758a
--- /dev/null
@@ -0,0 +1,167 @@
+<?php  // $Id$
+defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+require_once($CFG->dirroot.'/mod/feedback/item/feedback_item_class.php');
+
+class feedback_item_textfield extends feedback_item_base {
+    var $type = "textfield";
+    function init() {
+    
+    }
+    
+    function show_edit($item, $usehtmleditor = false) {
+
+        $item->presentation=empty($item->presentation)?'':$item->presentation;
+
+    ?>
+        <table>
+            <tr>
+                <th colspan="2"><?php print_string('textfield', 'feedback');?>
+                    &nbsp;(<input type="checkbox" name="required" value="1" <?php 
+                $item->required=isset($item->required)?$item->required:0;
+                echo ($item->required == 1?'checked="checked"':'');
+                ?> />&nbsp;<?php print_string('required', 'feedback');?>)
+                </th>
+            </tr>
+            <tr>
+                <td><?php print_string('item_name', 'feedback');?></td>
+                <td><input type="text" id="itemname" name="itemname" size="40" maxlength="255" value="<?php echo isset($item->name)?htmlspecialchars(stripslashes_safe($item->name)):'';?>" /></td>
+            </tr>
+            <tr>
+                <td><?php print_string('textfield_size', 'feedback');?></td>
+                <td>
+                    <select name="itemsize">
+    <?php
+                        //Dropdown-Items fuer die Textfeldbreite
+                        $sizeAndLength = explode('|',$item->presentation);
+                        $selected = '';
+                        feedback_print_numeric_option_list(5, 50, ($sizeAndLength[0])?$sizeAndLength[0]:40, 5);
+    ?>
+                    </select>
+                </td>
+            </tr>
+            <tr>
+                <td><?php print_string('textfield_maxlength', 'feedback');?></td>
+                <td>
+                    <select name="itemmaxlength">
+    <?php
+                        //Dropdown-Items fuer die Textlaenge
+                        feedback_print_numeric_option_list(5, 50, ($sizeAndLength[1])?$sizeAndLength[1]:40, 5);
+    ?>
+                    </select>
+                </td>
+            </tr>
+        </table>
+    <?php
+    }
+
+    //liefert eine Struktur ->name, ->data = array(mit Antworten)
+    function get_analysed($item, $groupid = false, $courseid = false) {
+        $aVal = null;
+        $aVal->data = null;
+        $aVal->name = $item->name;
+        //$values = get_records('feedback_value', 'item', $item->id);
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if($values) {
+            $data = array();
+            foreach($values as $value) {
+                $data[] = str_replace("\n", '<br />', $value->value);
+            }
+            $aVal->data = $data;
+        }
+        return $aVal;
+    }
+
+    function get_printval($item, $value) {
+        
+        if(!isset($value->value)) return '';
+        return $value->value;
+    }
+
+    function print_analysed($item, $itemnr = 0, $groupid = false, $courseid = false) {
+        $values = feedback_get_group_values($item, $groupid, $courseid);
+        if($values) {
+            //echo '<table>';2
+            $itemnr++;
+            echo '<tr><th colspan="2" align="left">'. $itemnr . '.)&nbsp;' . stripslashes_safe($item->name) .'</th></tr>';
+            foreach($values as $value) {
+                echo '<tr><td colspan="2" valign="top" align="left">-&nbsp;&nbsp;' . str_replace("\n", '<br />', $value->value) . '</td></tr>';
+            }
+            //echo '</table>';
+        }
+        return $itemnr;
+    }
+
+    function excelprint_item(&$worksheet, $rowOffset, $item, $groupid, $courseid = false) {
+        $analysed_item = $this->get_analysed($item, $groupid, $courseid);
+
+        $worksheet->setFormat("<l><f><ro2><vo><c:green>");
+        $worksheet->write_string($rowOffset, 0, stripslashes_safe($item->name));
+        $data = $analysed_item->data;
+        if(is_array($data)) {
+            $worksheet->setFormat("<l><ro2><vo>");
+            $worksheet->write_string($rowOffset, 1, $data[0]);
+            $rowOffset++;
+            for($i = 1; $i < sizeof($data); $i++) {
+                $worksheet->setFormat("<l><vo>");
+                $worksheet->write_string($rowOffset, 1, $data[$i]);
+                $rowOffset++;
+            }
+        }
+        $rowOffset++;
+        return $rowOffset;
+    }
+
+    function print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+        $align = get_string('thisdirection') == 'ltr' ? 'left' : 'right';
+        
+        $presentation = explode ("|", $item->presentation);
+        if($highlightrequire AND $item->required AND strval($value) == '') {
+            $highlight = 'bgcolor="#FFAAAA" class="missingrequire"';
+        }else {
+            $highlight = '';
+        }
+        $requiredmark =  ($item->required == 1)?'<span class="feedback_required_mark">*</span>':'';
+    ?>
+        <td <?php echo $highlight;?> valign="top" align="<?php echo $align;?>"><?php echo format_text(stripslashes_safe($item->name) . $requiredmark, true, false, false);?></td>
+        <td valign="top" align="<?php echo $align;?>">
+    <?php
+        if($readonly){
+            // print_simple_box_start($align);
+            print_box_start('generalbox boxalign'.$align);
+            echo $value?$value:'&nbsp;';
+            // print_simple_box_end();
+            print_box_end();
+        }else {
+    ?>
+            <input type="text" name="<?php echo $item->typ . '_' . $item->id;?>"
+                                    size="<?php echo $presentation[0];?>"
+                                    maxlength="<?php echo $presentation[1];?>"
+                                    value="<?php echo $value?htmlspecialchars($value):'';?>" />
+    <?php
+        }
+    ?>
+        </td>
+    <?php
+    }
+
+    function check_value($value, $item) {
+        //if the item is not required, so the check is true if no value is given
+        if((!isset($value) OR $value == '') AND $item->required != 1) return true;
+        if($value == "")return false;
+        return true;
+    }
+
+    function create_value($data) {
+        $data = addslashes(clean_text($data));
+        return $data;
+    }
+
+    function get_presentation($data) {
+        return $data->itemsize . '|'. $data->itemmaxlength;
+    }
+
+    function get_hasvalue() {
+        return 1;
+    }
+}
+?>
diff --git a/mod/feedback/lib.php b/mod/feedback/lib.php
new file mode 100644 (file)
index 0000000..593e77a
--- /dev/null
@@ -0,0 +1,1759 @@
+<?php // $Id$
+/**
+* includes the main-part of feedback-functions
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+/// Library of functions and constants for module feedback
+
+define('FEEDBACK_INCLUDE_TEST', 1);
+define('FEEDBACK_ANONYMOUS_YES', 1);
+define('FEEDBACK_ANONYMOUS_NO', 2);
+define('FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP', 2);
+define('FEEDBACK_DECIMAL', '.');
+define('FEEDBACK_THOUSAND', ',');
+define('FEEDBACK_RESETFORM_RESET', 'feedback_reset_data_');
+define('FEEDBACK_RESETFORM_DROP', 'feedback_drop_feedback_');
+define('FEEDBACK_MAX_PIX_LENGTH', '400'); //max. Breite des grafischen Balkens in der Auswertung
+
+$feedback_names = feedback_load_feedback_items('mod/feedback/item');
+
+/**
+* this will create a new instance and return the id number 
+* of the new instance.
+* @param object $feedback the object given by mod_feedback_mod_form
+* @return int
+*/
+function feedback_add_instance($feedback) {
+
+    $feedback->timemodified = time();
+    $feedback->id = '';
+
+    //check if openenable and/or closeenable is set and set correctly to save in db
+    if(empty($feedback->openenable)) {
+        $feedback->timeopen = 0;
+    }
+    if(empty($feedback->closeenable)) {
+        $feedback->timeclose = 0;
+    }
+
+    //saving the feedback in db
+    if(!$feedbackid = insert_record("feedback", $feedback)) {
+        return false;
+    }
+    
+    feedback_set_events($feedback);
+    
+    return $feedbackid;
+}
+
+/**
+* this will update a given instance
+* @param object $feedback the object given by mod_feedback_mod_form
+* @return boolean
+*/
+function feedback_update_instance($feedback) {
+
+    $feedback->timemodified = time();
+    $feedback->id = $feedback->instance;
+
+    //check if openenable and/or closeenable is set and set correctly to save in db
+    if(empty($feedback->openenable)) {
+        $feedback->timeopen = 0;
+    }
+    if(empty($feedback->closeenable)) {
+        $feedback->timeclose = 0;
+    }
+
+    //save the feedback into the db
+    if(!update_record("feedback", $feedback)) {
+        return false;
+    }
+
+    //create or update the new events
+    feedback_set_events($feedback);
+     
+    return true;
+}
+
+/**
+* this will delete a given instance.
+* all referenced data also will be deleted
+* @param int $id the instanceid of feedback
+* @return boolean
+*/
+function feedback_delete_instance($id) {
+    //get all referenced items
+    $feedbackitems = get_records('feedback_item', 'feedback', $id);
+    
+    //deleting all referenced items and values
+    if (is_array($feedbackitems)){
+        foreach($feedbackitems as $feedbackitem){
+            @delete_records("feedback_value", "item", $feedbackitem->id);
+            @delete_records("feedback_valuetmp", "item", $feedbackitem->id);
+        }
+        @delete_records("feedback_item", "feedback", $id);
+    }
+    
+    //deleting the referenced tracking data
+    @delete_records('feedback_tracking', 'feedback', $id);
+    
+    //deleting the completeds
+    @delete_records("feedback_completed", "feedback", $id);
+    
+    //deleting the unfinished completeds
+    @delete_records("feedback_completedtmp", "feedback", $id);
+    
+    //deleting old events
+    @delete_records('event', 'modulename', 'feedback', 'instance', $id);
+    return @delete_records("feedback", "id", $id);
+}
+
+/**
+* this is called after deleting all instances if the course will be deleted.
+* only templates have to be deleted
+* @param object $course
+* @return boolean
+*/
+function feedback_delete_course($course) {
+    //delete all templates of given course
+    return delete_records('feedback_template', 'course', $course->id);
+}
+
+/**
+* Return a small object with summary information about what a 
+* user has done with a given particular instance of this module
+* Used for user activity reports.
+* $return->time = the time they did it
+* $return->info = a short text description
+* @param object $course
+* @param object $user
+* @param object $mod
+* @param object $feedback
+* @return object
+*/
+function feedback_user_outline($course, $user, $mod, $feedback) {
+
+    return $return;
+}
+
+/**
+* Print a detailed representation of what a  user has done with
+* a given particular instance of this module, for user activity reports.
+* @param object $course
+* @param object $user
+* @param object $mod
+* @param object $feedback
+* @return object
+*/
+function feedback_user_complete($course, $user, $mod, $feedback) {
+
+    return true;
+}
+
+
+function feedback_cron () {
+    return true;
+}
+
+function feedback_grades($feedbackid) {
+
+    return NULL;
+}
+
+function feedback_get_participants($feedbackid) {
+
+    return false;
+}
+
+function feedback_scale_used ($feedbackid,$scaleid) {
+    $return = false;
+
+    return $return;
+}
+
+/** 
+ * This function is used by the remove_course_userdata function in moodlelib.
+ * If this function exists, remove_course_userdata will execute it.
+ * This function will remove all completeds from the specified feedback.
+ * @param object $data
+ * @param boolean $showfeedback
+ * @return void
+ */
+function feedback_delete_userdata($data, $showfeedback=true) {
+    global $CFG;
+    
+    $resetfeedbacks = array();
+    $dropfeedbacks = array();
+    
+    //get the relevant entries from $data
+    foreach($data as $key => $value) {
+        switch(true) {
+            case substr($key, 0, strlen(FEEDBACK_RESETFORM_RESET)) == FEEDBACK_RESETFORM_RESET:
+                if($value == 1) {
+                    $templist = explode('_', $key);
+                    if(isset($templist[3]))$resetfeedbacks[] = intval($templist[3]);
+                }
+            break;
+            case substr($key, 0, strlen(FEEDBACK_RESETFORM_DROP)) == FEEDBACK_RESETFORM_DROP:
+                if($value == 1) {
+                    $templist = explode('_', $key);
+                    if(isset($templist[3]))$dropfeedbacks[] = intval($templist[3]);
+                }
+            break;
+        }
+    }
+    
+    //reset the selected feedbacks
+    foreach($resetfeedbacks as $id) {
+        feedback_delete_all_completeds($id);
+    }
+    
+    //drop the selected feedbacks
+    foreach($dropfeedbacks as $id) {
+        $cm = get_coursemodule_from_instance('feedback', $id);
+        feedback_delete_instance($id);
+        feedback_delete_course_module($cm->id);
+    }
+}
+
+/** 
+ * Called by course/reset.php and shows the formdata by coursereset.
+ * it prints checkboxes for each feedback available at the given course
+ * there are two checkboxes: 1) delete userdata and keep the feedback 2) delete userdata and drop the feedback
+ * @param object $course
+ * @return void
+ */
+function feedback_reset_course_form($course) {
+    echo get_string('resetting_feedbacks', 'feedback'); echo ':<br />';
+    if(!$feedbacks = get_records('feedback', 'course', $course->id, 'name'))return;
+    
+    foreach($feedbacks as $feedback) {
+        echo '<p>';
+        echo get_string('name','feedback').': '.$feedback->name.'<br />';
+        print_checkbox(FEEDBACK_RESETFORM_RESET.$feedback->id, 1, true, get_string('resetting_data','feedback'), '', '');  echo '<br />';
+        print_checkbox(FEEDBACK_RESETFORM_DROP.$feedback->id, 1, false, get_string('drop_feedback','feedback'), '', '');
+        echo '</p>';
+    }
+}
+
+/** 
+ *  This creates new events given as timeopen and closeopen by $feedback.
+ *  @param object $feedback
+ *  @return void
+ */
+function feedback_set_events($feedback) {
+    // adding the feedback to the eventtable (I have seen this at quiz-module)
+    delete_records('event', 'modulename', 'feedback', 'instance', $feedbackid);
+
+    // the open-event
+    if($feedback->timeopen > 0) {
+        $event = NULL;
+        $event->name          = get_string('start', 'feedback').' '.$feedback->name;
+        $event->description = $feedback->summary;
+        $event->courseid     = $feedback->course;
+        $event->groupid      = 0;
+        $event->userid        = 0;
+        $event->modulename  = 'feedback';
+        $event->instance     = $feedbackid;
+        $event->eventtype    = 'open';
+        $event->timestart    = $feedback->timeopen;
+        $event->visible      = instance_is_visible('feedback', $feedback);
+        if($feedback->timeclose > 0) {
+            $event->timeduration = ($feedback->timeclose - $feedback->timeopen);
+        } else {
+            $event->timeduration = 0;
+        }
+    
+        add_event($event);
+    }
+
+    // the close-event
+    if($feedback->timeclose > 0) {
+        $event = NULL;
+        $event->name          = get_string('stop', 'feedback').' '.$feedback->name;
+        $event->description = $feedback->summary;
+        $event->courseid     = $feedback->course;
+        $event->groupid      = 0;
+        $event->userid        = 0;
+        $event->modulename  = 'feedback';
+        $event->instance     = $feedbackid;
+        $event->eventtype    = 'close';
+        $event->timestart    = $feedback->timeclose;
+        $event->visible      = instance_is_visible('feedback', $feedback);
+        $event->timeduration = 0;
+
+        add_event($event);
+    }
+}
+
+/** 
+ *  this function is called by {@link feedback_delete_userdata()}
+ *  it drops the feedback-instance from the course_module table
+ *  @param int $id the id from the coursemodule
+ *  @return boolean
+ */
+function feedback_delete_course_module($id) {
+    if (!$cm = get_record('course_modules', 'id', $id)) {
+        return true;
+    }
+    return delete_records('course_modules', 'id', $cm->id);
+}
+
+
+
+////////////////////////////////////////////////
+//functions to handle capabilities
+////////////////////////////////////////////////
+
+/** 
+ *  returns the context-id related to the given coursemodule-id
+ *  @param int $cmid the coursemodule-id
+ *  @return object $context
+ */
+function feedback_get_context($cmid) {
+    static $context;
+    
+    if(isset($context)) return $context;
+    
+    if (!$context = get_context_instance(CONTEXT_MODULE, $cmid)) {
+            print_error('badcontext');
+    }
+    return $context;
+}
+
+/** 
+ *  get the capabilities for the feedback
+ *  @param int $cmid
+ *  @return object the available capabilities from current user
+ */
+function feedback_load_capabilities($cmid) {
+    static $cb;
+    
+    if(isset($cb)) return $cb;
+    
+    $context = feedback_get_context($cmid);
+    
+    $cb = new object;
+    $cb->view = has_capability('mod/feedback:view', $context, NULL, false);
+    $cb->complete = has_capability('mod/feedback:complete', $context, NULL, false);
+    $cb->deletesubmissions = has_capability('mod/feedback:deletesubmissions', $context, NULL, false);
+    $cb->mapcourse = has_capability('mod/feedback:mapcourse', $context, NULL, false);
+    $cb->edititems = has_capability('mod/feedback:edititems', $context, NULL, false);
+    $cb->viewreports = has_capability('mod/feedback:viewreports', $context, NULL, false);
+    $cb->createprivatetemplate = has_capability('mod/feedback:createprivatetemplate', $context, NULL, false);
+    $cb->createpublictemplate = has_capability('mod/feedback:createpublictemplate', $context, NULL, false);
+    $cb->deletetemplate = has_capability('mod/feedback:deletetemplate', $context, NULL, false);
+    
+    $cb->siteadmin = has_capability('moodle/site:doanything', $context);
+    
+    $cb->viewhiddenactivities = has_capability('moodle/course:viewhiddenactivities', $context, NULL, false);
+    
+    return $cb;
+
+}
+
+/** 
+ *  get the capabilities for the course.
+ *  this is used by feedback/index.php
+ *  @param int $courseid
+ *  @return object the available capabilities from current user
+ */
+function feedback_load_course_capabilities($courseid) {
+    static $ccb;
+    
+    if(isset($ccb)) return $ccb;
+    
+    $context = get_context_instance(CONTEXT_COURSE, $courseid);
+    
+    $ccb = new object;
+    $ccb->view = has_capability('mod/feedback:view', $context, NULL, false);
+    $ccb->complete = has_capability('mod/feedback:complete', $context, NULL, false);
+    $ccb->deletesubmissions = has_capability('mod/feedback:deletesubmissions', $context, NULL, false);
+    $ccb->mapcourse = has_capability('mod/feedback:mapcourse', $context, NULL, false);
+    $ccb->edititems = has_capability('mod/feedback:edititems', $context, NULL, false);
+    $ccb->viewreports = has_capability('mod/feedback:viewreports', $context, NULL, false);
+    $ccb->createprivatetemplate = has_capability('mod/feedback:createprivatetemplate', $context, NULL, false);
+    $ccb->createpublictemplate = has_capability('mod/feedback:createpublictemplate', $context, NULL, false);
+    $ccb->deletetemplate = has_capability('mod/feedback:deletetemplate', $context, NULL, false);
+    
+    $ccb->siteadmin = has_capability('moodle/site:doanything', $context);
+    
+    $ccb->viewhiddenactivities = has_capability('moodle/course:viewhiddenactivities', $context, NULL, false);
+    
+    return $ccb;
+
+}
+
+/** 
+ *  returns true if the current role is faked by switching role feature
+ *  @return boolean
+ */
+function feedback_check_is_switchrole(){
+    global $USER;
+    if(isset($USER->switchrole) AND is_array($USER->switchrole) AND count($USER->switchrole) > 0) {
+        return true;
+    }
+    return false;
+}
+
+/** 
+ *  get users which have the complete-capability
+ *  @param int $cmid
+ *  @param mixed $groups single groupid or array of groupids - group(s) user is in
+ *  @return object the userrecords
+ */
+function feedback_get_complete_users($cmid, $groups = false) {
+
+    if (!$context = get_context_instance(CONTEXT_MODULE, $cmid)) {
+            print_error('badcontext');
+    }
+    
+    //description of the call below: get_users_by_capability($context, $capability, $fields='', $sort='', $limitfrom='', $limitnum='', $groups='', $exceptions='', $doanything=true)
+    return get_users_by_capability($context, 'mod/feedback:complete', '', 'lastname', '', '', $groups, '', false);
+}
+
+/** 
+ *  get users which have the viewreports-capability
+ *  @param int $cmid
+ *  @param mixed $groups single groupid or array of groupids - group(s) user is in
+ *  @return object the userrecords
+ */
+function feedback_get_viewreports_users($cmid, $groups = false) {
+
+    if (!$context = get_context_instance(CONTEXT_MODULE, $cmid)) {
+            print_error('badcontext');
+    }
+    
+    //description of the call below: get_users_by_capability($context, $capability, $fields='', $sort='', $limitfrom='', $limitnum='', $groups='', $exceptions='', $doanything=true)
+    return get_users_by_capability($context, 'mod/feedback:viewreports', '', 'lastname', '', '', $groups, '', false);
+}
+
+////////////////////////////////////////////////
+//functions to handle the templates
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+
+/** 
+ *  creates a new template-record.
+ *  @param int $courseid
+ *  @param string $name the name of template shown in the templatelist
+ *  @param int $ispublic 0:privat 1:public
+ *  @return int the new templateid
+ */
+function feedback_create_template($courseid, $name, $ispublic = 0) {
+    $templ->id = '';
+    $templ->course = $courseid;
+    
+    $templ->name = addslashes($name);
+    
+    $templ->ispublic = $ispublic;
+    return insert_record('feedback_template', $templ);
+}
+
+/** 
+ *  creates new template items.
+ *  all items will be copied and the attribute feedback will be set to 0
+ *  and the attribute template will be set to the new templateid
+ *  @param object $feedback
+ *  @param string $name the name of template shown in the templatelist
+ *  @param int $ispublic 0:privat 1:public
+ *  @return boolean
+ */
+function feedback_save_as_template($feedback, $name, $ispublic = 0) {
+    $feedbackitems = get_records('feedback_item', 'feedback', $feedback->id);
+    if(!is_array($feedbackitems)){
+        return false;
+    }
+    
+    if(!$newtempl = feedback_create_template($feedback->course, $name, $ispublic)) {
+        return false;
+    }
+    //create items of this new template
+    foreach($feedbackitems as $item) {
+        $item->id = '';
+        $item->feedback = 0;
+        $item->template = $newtempl;
+        $item->name = addslashes($item->name);
+        $item->presentation = addslashes($item->presentation);
+        insert_record('feedback_item', $item);
+    }
+    return true;
+}
+
+/** 
+ *  deletes all feedback_items related to the given template id
+ *  @param int $id the templateid
+ *  @return void
+ */
+function feedback_delete_template($id) {
+    @delete_records("feedback_item", "template", $id);
+    @delete_records("feedback_template", "id", $id);
+}
+
+/** 
+ *  creates new feedback_item-records from template.
+ *  if $deleteold is set true so the existing items of the given feedback will be deleted
+ *  if $deleteold is set false so the new items will be appanded to the old items
+ *  @param object $feedback
+ *  @param int $templateid
+ *  @param boolean $deleteold
+ */
+function feedback_items_from_template($feedback, $templateid, $deleteold = false) {
+    //get all templateitems
+    if(!$templitems = get_records('feedback_item', 'template', $templateid)) {
+        return false;
+    }
+    
+    //if deleteold then delete all old items before
+    //get all items
+    if($deleteold) {
+        if($feedbackitems = get_records('feedback_item', 'feedback', $feedback->id)){
+            //delete all items of this feedback
+            foreach($feedbackitems as $item) {
+                feedback_delete_item($item->id, false);
+            }
+            //delete tracking-data
+            @delete_records('feedback_tracking', 'feedback', $feedback->id);
+            @delete_records('feedback_completed', 'feedback', $feedback->id);
+            @delete_records('feedback_completedtmp', 'feedback', $feedback->id);
+            $positionoffset = 0;
+        }
+    }else {
+        //if the old items are kept the new items will be appended
+        //therefor the new position has an offset
+        $positionoffset = count_records('feedback_item', 'feedback', $feedback->id);
+    }
+    
+    foreach($templitems as $newitem) {
+        $newitem->id = '';
+        $newitem->feedback = $feedback->id;
+        $newitem->template = 0;
+        $newitem->name = addslashes($newitem->name);
+        $newitem->presentation = addslashes($newitem->presentation);
+        $newitem->position = $newitem->position + $positionoffset;
+        insert_record('feedback_item', $newitem);
+    }
+}
+
+/** 
+ *  get the list of available templates.
+ *  if the $onlyown param is set true so only templates from own course will be served
+ *  this is important for droping templates
+ *  @param object $course
+ *  @param boolean $onlyown
+ *  @return array the template recordsets
+ */
+function feedback_get_template_list($course, $onlyown = false) {
+    if($onlyown) {
+        $templates = get_records('feedback_template', 'course', $course->id);
+    } else {
+        $templates = get_records_select('feedback_template', 'course = ' . $course->id . ' OR ispublic = 1');
+    }
+    return $templates;
+}
+
+////////////////////////////////////////////////
+//Handling der Items
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+
+/** 
+ *  load the available item plugins from given subdirectory of $CFG->dirroot
+ *  the default is "mod/feedback/item"
+ *  @param string $dir the subdir
+ *  @return array pluginnames as string
+ */
+function feedback_load_feedback_items($dir = 'mod/feedback/item') {
+    global $CFG;
+    $names =get_list_of_plugins($dir);
+    $ret_names = array();
+
+    foreach($names as $name) {
+        require_once($CFG->dirroot.'/'.$dir.'/'.$name.'/lib.php');
+        if(class_exists('feedback_item_'.$name)) {
+          $ret_names[] = $name;
+        }
+    }
+    return $ret_names;
+}
+
+/** 
+ *  load the available item plugins to use as dropdown-options
+ *  @return array pluginnames as string
+ */
+function feedback_load_feedback_items_options() {
+    global $CFG;
+    
+    $feedback_options = array("pagebreak" => get_string('add_pagebreak', 'feedback'));
+    
+    if (!$feedback_names = feedback_load_feedback_items('mod/feedback/item')) {
+        return array();
+    }
+    
+    foreach($feedback_names as $fn) {
+        $feedback_options[$fn] = get_string($fn,'feedback');
+    }
+    asort($feedback_options);
+    $feedback_options = array_merge( array(' ' => get_string('select')), $feedback_options );    
+    return $feedback_options;
+}
+
+/** 
+ *  creates a new item-record
+ *  @param object $data the data from edit_item_form
+ *  @return int the new itemid
+ */
+function feedback_create_item($data) {
+    $item = new object;
+    $item->id = '';
+    $item->feedback = intval($data->feedbackid);
+
+    $item->template=0;
+    if (isset($data->templateid)) {
+               $item->template = intval($data->templateid);
+    }    
+
+    $itemname = trim($data->itemname);
+    $item->name = addslashes($itemname ? $data->itemname : get_string('no_itemname', 'feedback'));
+    
+    //get the used class from item-typ
+    $itemclass = 'feedback_item_'.$data->typ;
+    //get the instance of the item class
+    $itemobj = new $itemclass();
+    $item->presentation = addslashes($itemobj->get_presentation($data));
+    
+    $item->hasvalue = $itemobj->get_hasvalue();
+    
+    $item->typ = $data->typ;
+    $item->position = $data->position;
+
+    $item->required=0;
+    if (isset($data->required)) {
+               $item->required=$data->required;
+    }    
+
+    return insert_record('feedback_item', $item);
+}
+
+/** 
+ *  save the changes of a given item.
+ *  @param object $item
+ *  @param object $data the data from edit_item_form
+ *  @return boolean
+ */
+function feedback_update_item($item, $data = null){
+    if($data != null){
+        $itemname = trim($data->itemname);
+        $item->name = addslashes($itemname ? $data->itemname : get_string('no_itemname', 'feedback'));
+    
+        //get the used class from item-typ
+        $itemclass = 'feedback_item_'.$data->typ;
+        //get the instance of the item class
+        $itemobj = new $itemclass();
+        $item->presentation = addslashes($itemobj->get_presentation($data));
+
+        $item->required=0;
+        if (isset($data->required)) {
+               $item->required=$data->required;
+        } 
+    }else {
+        $item->name = addslashes($item->name);
+        $item->presentation = addslashes($item->presentation);
+    }
+
+    return update_record("feedback_item", $item);
+}
+
+/** 
+ *  deletes a item and also deletes all related values
+ *  @param int $itemid
+ *  @param boolean $renumber should the kept items renumbered Yes/No
+ *  @return void
+ */
+function feedback_delete_item($itemid, $renumber = true){
+    $item = get_record('feedback_item', 'id', $itemid);
+    @delete_records("feedback_value", "item", $itemid);
+    @delete_records("feedback_valuetmp", "item", $itemid);
+    delete_records("feedback_item", "id", $itemid);
+    if($renumber) {
+        feedback_renumber_items($item->feedback);
+    }
+}
+
+/** 
+ *  deletes all items of the given feedbackid
+ *  @param int $feedbackid
+ *  @return void
+ */
+function feedback_delete_all_items($feedbackid){
+    if(!$items = get_records('feedback_item', 'feedback', $feedbackid)) {
+        return;
+    }
+    foreach($items as $item) {
+        feedback_delete_item($item->id, false);
+    }
+    @delete_records('feedback_completedtmp', 'feedback', $feedbackid);
+    @delete_records('feedback_completed', 'feedback', $feedbackid);
+}
+
+/** 
+ *  this function toggled the item-attribute required (yes/no)
+ *  @param object $item
+ *  @return boolean
+ */
+function feedback_switch_item_required($item) {
+    if($item->required == 1) {
+        $item->required = 0;
+    } else {
+        $item->required = 1;
+    }
+    $item->name = addslashes($item->name);
+    $item->presentation = addslashes($item->presentation);
+    return update_record('feedback_item', $item);
+}
+
+/** 
+ *  renumbers all items of the given feedbackid
+ *  @param int $feedbackid
+ *  @return void
+ */
+function feedback_renumber_items($feedbackid){
+    $items = get_records('feedback_item', 'feedback', $feedbackid, 'position');
+    $pos = 1;
+    if($items) {
+        foreach($items as $item){
+            $item->position = $pos;
+            $pos++;
+            feedback_update_item($item);
+        }
+    }
+}
+
+/** 
+ *  this decreases the position of the given item
+ *  @param object $item
+ *  @return void
+ */
+function feedback_moveup_item($item){
+    if($item->position == 1) return;
+    $item_before = get_record_select('feedback_item', 'feedback = '.$item->feedback.' AND position = '.$item->position . ' - 1');
+    $item_before->position = $item->position;
+    $item->position--;
+    feedback_update_item($item_before);
+    feedback_update_item($item);
+}
+
+/** 
+ *  this increased the position of the given item
+ *  @param object $item
+ *  @return void
+ */
+function feedback_movedown_item($item){
+    if(!$item_after = get_record_select('feedback_item', 'feedback = '.$item->feedback.' AND position = '.$item->position . ' + 1'))
+    {
+        return;
+    }
+    
+    $item_after->position = $item->position;
+    $item->position++;
+    feedback_update_item($item_after);
+    feedback_update_item($item);
+}
+
+/** 
+ *  here the position of the given item will be set to the value in $pos
+ *  @param object $moveitem
+ *  @param int $pos
+ *  @return boolean
+ */
+function feedback_move_item($moveitem, $pos){
+    if($moveitem->position == $pos) return true;
+    if(!$allitems = get_records('feedback_item', 'feedback', $moveitem->feedback, 'position')){
+        return false;
+    }
+    if(is_array($allitems)) {
+        $index = 1;
+        foreach($allitems as $item) {
+            if($item->id == $moveitem->id) continue; //the moving item is handled special
+            
+            if($index == $pos) {
+                $moveitem->position = $index;
+                feedback_update_item($moveitem);
+                $index++;
+            }
+            $item->position = $index;
+            feedback_update_item($item);
+            $index++;
+        }
+        if($pos >= count($allitems)) {
+            $moveitem->position = $index;
+            feedback_update_item($moveitem);
+        }
+        return true;
+    }
+    return false;
+}
+
+/** 
+ *  prints the given item.
+ *  if $readonly is set true so the ouput only is for showing responses and not for editing or completing.
+ *  each item-class has an own print_item function implemented.
+ *  @param object $item the item what we want to print out
+ *  @param mixed $value the value if $readonly is set true and we showing responses
+ *  @param boolean $readonly
+ *  @param boolean $edit should the item print out for completing or for editing?
+ *  @param boolean $highlightrequire if this set true and the value are false on completing so the item will be highlighted
+ *  @return void
+ */
+function feedback_print_item($item, $value = false, $readonly = false, $edit = false, $highlightrequire = false){
+    if($item->typ == 'pagebreak') return;
+    if($readonly)$ro = 'readonly="readonly" disabled="disabled"';
+        
+    //get the class of the given item-typ
+    $itemclass = 'feedback_item_'.$item->typ;
+    //get the instance of the item-class
+    $itemobj = new $itemclass();
+    $itemobj->print_item($item, $value, $readonly, $edit, $highlightrequire);
+}
+
+/** 
+ *  if the user completes a feedback and there is a pagebreak so the values are saved temporary.
+ *  the values are saved permanently not until the user click on save button
+ *  @param object $feedbackcompleted
+ *  @return object temporary saved completed-record
+ */
+function feedback_set_tmp_values($feedbackcompleted){
+    //first we create a completedtmp
+    $tmpcpl = new object();
+    foreach($feedbackcompleted as $key => $value) {
+        $tmpcpl->{$key} = $value;
+    }
+    // $tmpcpl = $feedbackcompleted;
+    $tmpcpl->id = '';
+    $tmpcpl->timemodified = time();
+    if(!$tmpcpl->id = insert_record('feedback_completedtmp', $tmpcpl)) {
+        error('failed create completedtmp');
+    }
+    //get all values of original-completed
+    if(!$values = get_records('feedback_value', 'completed', $feedbackcompleted->id)) {
+        return;
+    }
+    foreach($values as $value) {
+        $value->id = '';
+        $value->completed = $tmpcpl->id;
+        $value->value = addslashes($value->value);
+        insert_record('feedback_valuetmp', $value);
+    }
+    return $tmpcpl;
+}
+
+/** 
+ *  this saves the temporary saved values permanently
+ *  @param object $feedbackcompletedtmp the temporary completed
+ *  @param object $feedbackcompleted the target completed
+ *  @param int $userid
+ *  @return int the id of the completed
+ */
+function feedback_save_tmp_values($feedbackcompletedtmp, $feedbackcompleted, $userid) {
+    $tmpcplid = $feedbackcompletedtmp->id;
+    if(!$feedbackcompleted) {
+
+        //first we create a completedtmp
+        $newcpl = new object();
+        foreach($feedbackcompletedtmp as $key => $value) {
+            $newcpl->{$key} = $value;
+        }
+
+        $newcpl->id = '';
+        $newcpl->userid = $userid;
+        $newcpl->timemodified = time();
+        if(!$newcpl->id = insert_record('feedback_completed', $newcpl)) {
+            error('failed create completed');
+        }
+        //get all values of tmp-completed
+        if(!$values = get_records('feedback_valuetmp', 'completed', $feedbackcompletedtmp->id)) {
+            return false;
+        }
+
+        foreach($values as $value) {
+            $value->id = '';
+            $value->completed = $newcpl->id;
+            insert_record('feedback_value', $value);
+        }
+        //drop all the tmpvalues
+        delete_records('feedback_valuetmp', 'completed', $tmpcplid);
+        delete_records('feedback_completedtmp', 'id', $tmpcplid);
+        return $newcpl->id;
+    }else {
+        //first drop all existing values
+        delete_records('feedback_value', 'completed', $feedbackcompleted->id);
+        //update the current completed
+        $feedbackcompleted->timemodified = time();
+        update_record('feedback_completed', $feedbackcompleted);
+        //save all the new values from feedback_valuetmp
+        //get all values of tmp-completed
+        if(!$values = get_records('feedback_valuetmp', 'completed', $feedbackcompletedtmp->id)) {
+            return false;
+        }
+        foreach($values as $value) {
+            $value->id = '';
+            $value->completed = $feedbackcompleted->id;
+            insert_record('feedback_value', $value);
+        }
+        //drop all the tmpvalues
+        delete_records('feedback_valuetmp', 'completed', $tmpcplid);
+        delete_records('feedback_completedtmp', 'id', $tmpcplid);
+        return $feedbackcompleted->id;
+    }
+}
+
+/** 
+ *  deletes the given temporary completed and all related temporary values
+ *  @param int $tmpcplid
+ *  @return void
+ */
+function feedback_delete_completedtmp($tmpcplid) {
+        delete_records('feedback_valuetmp', 'completed', $tmpcplid);
+        delete_records('feedback_completedtmp', 'id', $tmpcplid);
+}
+
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+//functions to handle the pagebreaks
+////////////////////////////////////////////////
+
+/** 
+ *  this creates a pagebreak.
+ *  a pagebreak is a special kind of item
+ *  @param int $feedbackid
+ *  @return mixed false if there already is a pagebreak on last position or the id of the pagebreak-item
+ */
+function feedback_create_pagebreak($feedbackid) {
+    //check if there already is a pagebreak on the last position
+    $lastposition = count_records('feedback_item', 'feedback', $feedbackid);
+    if($lastposition == feedback_get_last_break_position($feedbackid)) {
+        return false;
+    }
+    
+    $item = new object();
+    $item->id = '';
+    $item->feedback = $feedbackid;
+
+    $item->template=0;
+
+    $item->name = '';
+    
+    $item->presentation = '';
+    $item->hasvalue = 0;
+    
+    $item->typ = 'pagebreak';
+    $item->position = $lastposition + 1;
+
+    $item->required=0;
+
+    return insert_record('feedback_item', $item);
+}
+
+/** 
+ *  get all positions of pagebreaks in the given feedback
+ *  @param int $feedbackid
+ *  @return array all ordered pagebreak positions
+ */
+function feedback_get_all_break_positions($feedbackid) {
+    if(!$allbreaks = get_records_select_menu('feedback_item', "typ = 'pagebreak' AND feedback = ".$feedbackid, 'position', 'id, position')) return false;
+    return array_values($allbreaks);
+}
+
+/** 
+ *  get the position of the last pagebreak
+ *  @param int $feedbackid
+ *  @return int the position of the last pagebreak
+ */
+function feedback_get_last_break_position($feedbackid) {
+    if(!$allbreaks = feedback_get_all_break_positions($feedbackid)) return false;
+    return $allbreaks[count($allbreaks) - 1];
+}
+
+/** 
+ *  this returns the position where the user can continue the completing.
+ *  @param int $feedbackid
+ *  @param int $courseid
+ *  @param string $guestid this id will be saved temporary and is unique
+ *  @return int the position to continue
+ */
+function feedback_get_page_to_continue($feedbackid, $courseid = false, $guestid) {
+    global $CFG, $USER;
+    
+    //is there any break?
+    
+    if(!$allbreaks = feedback_get_all_break_positions($feedbackid)) return false;
+    
+    if($courseid) {
+        $courseselect = "fv.course_id = ".$courseid;
+    }else {
+        $courseselect = "1";
+    }
+    
+    if($guestid) {
+        $userselect = "AND fc.guestid = '".$guestid."'";
+        $usergroup = "GROUP BY fc.guestid";
+    }else {
+        $userselect = "AND fc.userid = ".$USER->id;
+        $usergroup = "GROUP BY fc.userid";
+    }
+    
+    
+    $sql =  "SELECT MAX(fi.position)
+                FROM ".$CFG->prefix."feedback_completedtmp AS fc, ".$CFG->prefix."feedback_valuetmp AS fv, ".$CFG->prefix."feedback_item AS fi
+                WHERE fc.id = fv.completed
+                    ".$userselect."
+                    AND fc.feedback = ".$feedbackid."
+                    AND ".$courseselect."
+                    AND fi.id = fv.item
+                ".$usergroup;
+    
+    $lastpos = get_field_sql($sql);
+
+    //the index of found pagebreak is the searched pagenumber
+    foreach($allbreaks as $pagenr => $br) {
+        if($lastpos < $br) return $pagenr;
+    }
+    return count($allbreaks);
+}
+
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+//functions to handle the values
+////////////////////////////////////////////////
+
+/** 
+ *  this saves the values of an completed.
+ *  if the param $tmp is set true so the values are saved temporary in table feedback_valuetmp
+ *  if there is already a completed and the userid is set so the values are updated
+ *  on all other things new value records will be created
+ *  @param object $data the data from complete form
+ *  @param int $userid
+ *  @param boolean $tmp
+ *  @return mixed false on error or the completeid
+ */
+function feedback_save_values($data, $usrid, $tmp = false) {
+    $tmpstr = $tmp ? 'tmp' : '';
+         $time = time(); //arb
+         $timemodified = mktime(0, 0, 0, date('m', $time),date('d', $time),date('Y', $time)); //arb
+//         $timemodified = time();             
+    if($usrid == 0) {
+        return feedback_create_values($data, $usrid, $timemodified, $tmp);
+    }
+    if(!$data['completedid'] or !$completed = get_record('feedback_completed'.$tmpstr, 'id', $data['completedid'])){
+        return feedback_create_values($data, $usrid, $timemodified, $tmp);
+    }else{
+        $completed->timemodified = $timemodified;
+        return feedback_update_values($data, $completed, $tmp);
+    }
+}
+
+/** 
+ *  this saves the values from anonymous user such as guest on the main-site
+ *  @param object $data the data form complete_guest form
+ *  @param string $guestid the unique guestidentifier
+ *  @return mixed false on error or the completeid
+ */
+function feedback_save_guest_values($data, $guestid) {
+    $timemodified = time();
+    if(!$completed = get_record('feedback_completedtmp', 'id', $data['completedid'])){
+        return feedback_create_values($data, 0, $timemodified, true, $guestid);
+    }else {
+        $completed->timemodified = $timemodified;
+        return feedback_update_values($data, $completed, true);
+    }
+}
+
+/** 
+ *  get the value from the given item related to the given completed.
+ *  the value can come as temporary or as permanently value. the deciding is done by $tmp
+ *  @param int $completeid
+ *  @param int $itemid
+ *  @param boolean $tmp
+ *  @return mixed the value, the type depends on plugin-definition
+ */
+function feedback_get_item_value($completedid, $itemid, $tmp = false) {
+    $tmpstr = $tmp ? 'tmp' : '';
+    return get_field('feedback_value'.$tmpstr, 'value', 'completed', $completedid, 'item', $itemid);
+}
+
+/** 
+ *  this function checks the correctness of values.
+ *  the rules for this are implemented in the class of each item.
+ *  it can be the required attribute or the value self e.g. numeric.
+ *  the params first/lastitem are given to determine the visible range between pagebreaks.
+ *  @param object $data the data of complete form
+ *  @param int $firstitem the position of firstitem for checking
+ *  @param int $lastitem the position of lastitem for checking
+ *  @return boolean
+ */
+function feedback_check_values($data, $firstitem, $lastitem) {
+    //get all items between the first- and lastitem
+    $select = "feedback = ".intval($data['feedbackid'])."
+                    AND position >= ".$firstitem."
+                    AND position <= ".$lastitem."
+                    AND hasvalue = 1";
+    if(!$feedbackitems = get_records_select('feedback_item', $select)) {
+        //if no values are given so no values can be wrong ;-)
+        return true;
+    }
+
+    foreach($feedbackitems as $item) {
+        //the name of the input field of the completeform is given in a special form:
+        //<item-typ>_<item-id> eg. numeric_234
+        //this is the key to get the value for the correct item
+        $formvalname = $item->typ . '_' . $item->id;
+        
+        //check if the value is set
+        if((!isset($data[$formvalname])) AND ($item->required == 1)) {
+            return false;
+        }
+        
+        //if there is a value so save it temporary
+        $value = isset($data[$formvalname]) ? $data[$formvalname] : '';
+
+        //get the class of the item-typ
+        $itemclass = 'feedback_item_'.$item->typ;
+        //get the instance of the item-class
+        $itemobj = new $itemclass();
+        
+        //now we let check the value by the item-class
+        if(!$itemobj->check_value($value, $item)) {
+            return false;
+        }
+    }
+    //if no wrong values so we can return true
+    return true;
+}
+
+/** 
+ *  this function create a complete-record and the related value-records.
+ *  depending on the $tmp (true/false) the values are saved temporary or permanently
+ *  @param object $data the data of the complete form
+ *  @param int $userid
+ *  @param int $timemodified
+ *  @param boolean $tmp
+ *  @param string $guestid a unique identifier to save temporary data
+ *  @return mixed false on error or the completedid
+ */
+function feedback_create_values($data, $usrid, $timemodified, $tmp = false, $guestid = false){
+    $tmpstr = $tmp ? 'tmp' : '';
+    //first we create a new completed record
+    $completed = null;
+    $completed->id = '';
+    $completed->feedback = $data['feedbackid'];
+    $completed->userid = $usrid;
+    $completed->guestid = $guestid;
+    $completed->timemodified = $timemodified;
+    $completed->anonymous_response = $data['anonymous_response'];
+    
+    if(!$completedid = insert_record('feedback_completed'.$tmpstr, $completed)) {
+        return false;
+    }
+    
+    $completed = null;
+    $completed = get_record('feedback_completed'.$tmpstr, 'id', $completedid);
+
+    //$data includes an associative array. the keys are in the form like abc_xxx
+    //with explode we make an array with(abc, xxx) and (abc=typ und xxx=itemnr)
+    $keys = array_keys($data);
+    $errcount = 0;
+    foreach($keys as $key){
+        //ensure the keys are what we want
+        if(eregi('([a-z0-9]{1,})_([0-9]{1,})',$key)){            
+            $value = null;
+            $itemnr = explode('_', $key);
+            $value->id = '';
+            $value->item = intval($itemnr[1]);
+            $value->completed = $completed->id;
+            $value->course_id = intval($data['courseid']);
+            
+            //get the class of item-typ
+            $itemclass = 'feedback_item_'.$itemnr[0];
+            //get the instance of item-class
+            $itemobj = new $itemclass();
+            //the kind of values can be absolutely different so we run create_value directly by the item-class
+            $value->value = $itemobj->create_value($data[$key]);
+
+            if(!insert_record('feedback_value'.$tmpstr, $value)) {
+                $errcount++;
+            }
+        }
+    }
+    
+    //if nothing is wrong so we can return the completedid otherwise false
+    return $errcount == 0 ? $completed->id : false;
+}
+
+/** 
+ *  this function updates a complete-record and the related value-records.
+ *  depending on the $tmp (true/false) the values are saved temporary or permanently
+ *  @param object $data the data of the complete form
+ *  @param object $completed
+ *  @param boolean $tmp
+ *  @return int the completedid
+ */
+function feedback_update_values($data, $completed, $tmp = false){
+    $tmpstr = $tmp ? 'tmp' : '';
+    
+    update_record('feedback_completed'.$tmpstr, $completed);
+    //get the values of this completed
+    $values = get_records('feedback_value'.$tmpstr,'completed', $completed->id);
+    
+    //$data includes an associative array. the keys are in the form like abc_xxx
+    //with explode we make an array with(abc, xxx) and (abc=typ und xxx=itemnr)
+    $keys = array_keys($data);
+    foreach($keys as $key){
+        //ensure the keys are what we want
+        if(eregi('([a-z0-9]{1,})_([0-9]{1,})',$key)){            
+            //build the new value to update([id], item, completed, value)
+            $itemnr = explode('_', $key);
+            $newvalue = null;
+            $newvalue->id = '';
+            $newvalue->item = intval($itemnr[1]);
+            $newvalue->completed = $completed->id;
+            $newvalue->course_id = intval($data['courseid']);
+            
+            //get the class of item-typ
+            $itemclass = 'feedback_item_'.$itemnr[0];
+            //get the instace of the item-class
+            $itemobj = new $itemclass();
+            //the kind of values can be absolutely different so we run create_value directly by the item-class
+            $newvalue->value = $itemobj->create_value($data[$key]);
+            
+            //check, if we have to create or update the value
+            $exist = false;
+            foreach($values as $value){
+                if($value->item == $newvalue->item){
+                    $newvalue->id = $value->id;
+                    $exist = true;
+                    break;
+                }
+            }
+            if($exist){
+                update_record('feedback_value'.$tmpstr, $newvalue);
+            }else {
+                insert_record('feedback_value'.$tmpstr, $newvalue);
+            }
+            
+        }
+    }
+
+    return $completed->id;
+}
+
+/** 
+ *  get the values of an item depending on the given groupid.
+ *  if the feedback is anonymous so the values are shuffled
+ *  @param object $item
+ *  @param int $groupid
+ *  @param int $courseid
+ *  @return array the value-records
+ */
+function feedback_get_group_values($item, $groupid = false, $courseid = false){
+    global $CFG;
+
+    //if the groupid is given?
+    if(intval($groupid) > 0) {
+        $query = 'SELECT fbv .  *
+                        FROM '.$CFG->prefix . 'feedback_value AS fbv, '.$CFG->prefix . 'feedback_completed AS fbc, '.$CFG->prefix . 'groups_members AS gm
+                        WHERE fbv.item = '.$item->id . '
+                             AND fbv.completed = fbc.id 
+                             AND fbc.userid = gm.userid 
+                             AND gm.groupid = '.$groupid . '
+                        ORDER BY fbc.timemodified';
+        $values = get_records_sql($query);
+    }else {
+        if ($courseid) {
+             $values = get_records_select('feedback_value', "item = '$item->id' and course_id = '$courseid'");
+        } else {
+             $values = get_records('feedback_value', 'item', $item->id);
+        }
+    }    
+    if(get_field('feedback', 'anonymous', 'id', $item->feedback) == FEEDBACK_ANONYMOUS_YES) {
+        if(is_array($values))
+            shuffle($values);
+    }
+    return $values;
+}
+
+/** 
+ *  check for multiple_submit = false.
+ *  if the feedback is global so the courseid must be given
+ *  @param int $feedbackid
+ *  @param int $courseid
+ *  @return boolean true if the feedback already is submitted otherwise false
+ */
+function feedback_is_already_submitted($feedbackid, $courseid = false) {
+    global $USER;
+    
+    $select = 'userid = '.$USER->id.' AND feedback = '.$feedbackid;
+    if(!$trackings = get_records_select_menu('feedback_tracking', $select, '', 'id, completed')) {
+        return false;
+    }
+
+    if($courseid) {
+        $select = 'completed IN ('.implode(',',$trackings).') AND course_id = '.$courseid;
+        if(!$values = get_records_select('feedback_value', $select)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+/** 
+ *  if the completion of a feedback will be continued eg. by pagebreak or by multiple submit so the complete must be found.
+ *  if the param $tmp is set true so all things are related to temporary completeds
+ *  @param int $feedbackid
+ *  @param boolean $tmp
+ *  @param int $courseid
+ *  @param string $guestid
+ *  return int the id of the found completed
+ */
+function feedback_get_current_completed($feedbackid, $tmp = false, $courseid = false, $guestid = false) {
+    global $USER, $CFG;
+    
+    $tmpstr = $tmp ? 'tmp' : '';
+    
+    if(!$courseid) {
+        if($guestid) {
+            return get_record('feedback_completed'.$tmpstr,'feedback', $feedbackid, 'guestid', $guestid);
+        }else {
+            return get_record('feedback_completed'.$tmpstr,'feedback', $feedbackid, 'userid', $USER->id);
+        }
+    }
+    
+    $courseid = intval($courseid);
+    
+    if($guestid) {
+        $userselect = "AND fc.guestid = '".$guestid."'";
+    }else {
+        $userselect = "AND fc.userid = ".$USER->id;
+    }
+    //if courseid is set the feedback is global. there can be more than one completed on one feedback
+    $sql =  "SELECT fc.* FROM
+                    ".$CFG->prefix."feedback_value".$tmpstr." AS fv, ".$CFG->prefix."feedback_completed".$tmpstr." AS fc
+                WHERE fv.course_id = ".$courseid."
+                    AND fv.completed = fc.id
+                    ".$userselect."
+                    AND fc.feedback = ".$feedbackid;
+
+    if(!$sqlresult = get_records_sql($sql)) return false;
+    foreach($sqlresult as $r) {
+        return get_record('feedback_completed'.$tmpstr, 'id', $r->id);
+    }
+}
+
+/** 
+ *  get the completeds depending on the given groupid.
+ *  @param object $feedback
+ *  @param int $groupid
+ *  @return mixed array of found completeds otherwise false
+ */
+function feedback_get_completeds_group($feedback, $groupid = false) {
+    global $CFG;
+    if(intval($groupid) > 0){
+        $query = 'SELECT fbc.*
+                        FROM '.$CFG->prefix . 'feedback_completed AS fbc, '.$CFG->prefix . 'groups_members AS gm
+                        WHERE  fbc.feedback = '.$feedback->id . '
+                            AND gm.groupid = '.$groupid . '
+                            AND fbc.userid = gm.userid';
+        if($values = get_records_sql($query)) {
+            return $values;
+        }else {return false;}
+    }else {
+        if($values = get_records('feedback_completed', 'feedback', $feedback->id)){
+            return $values;
+        }else{return false;}
+    }
+}
+
+/** 
+ *  get the count of completeds depending on the given groupid.
+ *  @param object $feedback
+ *  @param int $groupid
+ *  @param int $courseid
+ *  @return mixed count of completeds or false
+ */
+function feedback_get_completeds_group_count($feedback, $groupid = false, $courseid = false) {
+    global $CFG;
+    if($courseid > 0 AND !$groupid <= 0) {
+        $sql = 'SELECT id, COUNT( item ) ci
+                    FROM  '.$CFG->prefix . 'feedback_value 
+                    WHERE  course_id  = '.$courseid.'
+                    GROUP  BY  item ORDER BY ci DESC';
+        if($foundrecs = get_records_sql($sql)) {
+            $foundrecs = array_values($foundrecs);
+            return $foundrecs[0]->ci;
+        }
+        return false;
+    }
+    if($values = feedback_get_completeds_group($feedback, $groupid)) {
+        return sizeof($values);
+    }else {
+        return false;
+    }
+}
+
+/* get the own groupid.
+@param object $course
+@param object $cm
+function feedback_get_groupid($course, $cm) {
+    $groupmode = groupmode($course, $cm);
+    
+    //get groupid
+    if($groupmode > 0 && !isadmin()) {
+        if($mygroupid = mygroupid($course->id)) {
+            return $mygroupid[0]; //get the first groupid
+        }
+    }else {
+        return false;
+    }
+}
+ */
+
+/** 
+ *  deletes all completed-recordsets from a feedback.
+ *  all related data such as values also will be deleted
+ *  @param int $feedbackid
+ *  @return void
+ */
+function feedback_delete_all_completeds($feedbackid) {
+    if(!$completeds = get_records('feedback_completed', 'feedback', $feedbackid)) return;
+    foreach($completeds as $completed) {
+        feedback_delete_completed($completed->id);
+    }
+}
+
+/** 
+ *  deletes a completed given by completedid.
+ *  all related data such values or tracking data also will be deleted
+ *  @param int $completedid
+ *  @return boolean
+ */
+function feedback_delete_completed($completedid) {
+    if(!$completed = get_record('feedback_completed', 'id', $completedid)) {
+        return false;
+    }
+    //first we delete all related values
+    @delete_records('feedback_value', 'completed', $completed->id);
+    
+    //now we delete all tracking data
+    if($tracking = get_record_select('feedback_tracking', " completed = ".$completed->id." AND feedback = ".$completed->feedback." ")) {
+        @delete_records('feedback_tracking', 'completed', $completed->id);
+    }
+        
+    //last we delete the completed-record
+    return delete_records('feedback_completed', 'id', $completed->id);
+}
+
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+//functions to handle sitecourse mapping
+////////////////////////////////////////////////
+
+/** 
+ *  checks if the course and the feedback is in the table feedback_sitecourse_map.
+ *  @param int $feedbackid
+ *  @param int $courseid
+ *  @return int the count of records
+ */
+function feedback_is_course_in_sitecourse_map($feedbackid, $courseid) {
+    global $CFG;
+    return count_records('feedback_sitecourse_map', 'feedbackid', $feedbackid, 'courseid', $courseid);
+}
+
+/** 
+ *  checks if the feedback is in the table feedback_sitecourse_map.
+ *  @param int $feedbackid
+ *  @return boolean
+ */
+function feedback_is_feedback_in_sitecourse_map($feedbackid) {
+    global $CFG;
+    return record_exists('feedback_sitecourse_map', 'feedbackid', $feedbackid);
+}
+
+/** 
+ *  gets the feedbacks from table feedback_sitecourse_map.
+ *  this is used to show the global feedbacks on the feedback block
+ *  all feedbacks with the following criteria will be selected:<br />
+ *  1) all feedbacks which id are listed together with the courseid in sitecoursemap and<br />
+ *  2) all feedbacks which not are listed in sitecoursemap
+ *  @param int $courseid
+ *  @return array the feedback-records
+ */
+function feedback_get_feedbacks_from_sitecourse_map($courseid) {
+    global $CFG;
+    
+    //first get all feedbacks listed in sitecourse_map with named courseid
+    $sql = "SELECT f.id as id, cm.id as cmid, f.name as name, f.timeopen as timeopen, f.timeclose as timeclose
+              FROM {$CFG->prefix}feedback f, {$CFG->prefix}course_modules cm, {$CFG->prefix}feedback_sitecourse_map sm, {$CFG->prefix}modules m
+              WHERE f.id = cm.instance
+                AND f.course = '".SITEID."'
+                AND m.id = cm.module 
+                AND m.name = 'feedback'
+                AND sm.courseid = $courseid 
+                AND sm.feedbackid = f.id";
+    
+    if(!$feedbacks1 = get_records_sql($sql)) {
+        $feedbacks1 = array();
+    }
+    
+    //second get all feedbacks not listed in sitecourse_map
+    $feedbacks2 = array();
+    $sql = "SELECT f.id as id, cm.id as cmid, f.name as name, f.timeopen as timeopen, f.timeclose as timeclose
+              FROM {$CFG->prefix}feedback f, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
+              WHERE f.id = cm.instance
+                AND f.course = '".SITEID."'
+                AND m.id = cm.module
+                AND m.name = 'feedback'";
+    if(!$allfeedbacks = get_records_sql($sql)) {
+        $allfeedbacks = array();
+    }
+    foreach($allfeedbacks as $a) {
+        if(!record_exists('feedback_sitecourse_map', 'feedbackid', $a->id)) {
+            $feedbacks2[] = $a;
+        }
+    }
+    
+    return array_merge($feedbacks1, $feedbacks2);
+    
+}
+
+/** 
+ *  gets the courses from table feedback_sitecourse_map.
+ *  @param int $feedbackid
+ *  @return array the course-records
+ */
+function feedback_get_courses_from_sitecourse_map($feedbackid) {
+    global $CFG;
+    
+    $sql = "select f.id, f.courseid, c.fullname, c.shortname
+                from {$CFG->prefix}feedback_sitecourse_map f, {$CFG->prefix}course c
+                where c.id = f.courseid
+                and f.feedbackid = $feedbackid
+                order by c.fullname";
+    
+    return get_records_sql($sql);
+    
+}
+
+/** 
+ *  removes non existing courses or feedbacks from sitecourse_map.
+ *  it shouldn't be called all too often
+ *  a good place for it could be the mapcourse.php or unmapcourse.php
+ *  @return void
+ */
+function feedback_clean_up_sitecourse_map() {
+    $maps = get_records('feedback_sitecourse_map');
+    foreach($maps as $map) {
+        if(!get_record('course', 'id', $map->courseid)) {
+            delete_records('feedback_sitecourse_map', 'courseid', $map->courseid, 'feedbackid', $map->feedbackid);
+            continue;
+        }
+        if(!get_record('feedback', 'id', $map->feedbackid)) {
+            delete_records('feedback_sitecourse_map', 'courseid', $map->courseid, 'feedbackid', $map->feedbackid);
+            continue;
+        }
+        
+    }
+}
+
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+////////////////////////////////////////////////
+//not relatable functions
+////////////////////////////////////////////////
+
+/** 
+ *  prints the option items of a selection-input item (dropdownlist).
+ *  @param int $startval the first value of the list
+ *  @param int $endval the last value of the list
+ *  @param int $selectval which item should be selected
+ *  @param int $interval the stepsize from the first to the last value
+ *  @return void
+ */
+function feedback_print_numeric_option_list($startval, $endval, $selectval = '', $interval = 1){
+    for($i = $startval; $i <= $endval; $i += $interval){
+        if($selectval == ($i)){
+            $selected = 'selected="selected"';
+        }else{
+            $selected = '';
+        }
+        echo '<option '.$selected.'>'.$i.'</option>';
+    }
+}
+
+/** 
+ *  sends an email to the teachers of the course where the given feedback is placed.
+ *  @param object $cm the coursemodule-record
+ *  @param $feedback
+ *  @param $course
+ *  @param $userid
+ *  @return void
+ */
+function feedback_email_teachers($cm, $feedback, $course, $userid) {
+    
+    global $CFG;
+    
+    if ($feedback->email_notification == 0) {  // No need to do anything
+        return;
+    }
+    
+    $user = get_record('user', 'id', $userid);
+    
+    if (groupmode($course, $cm) == SEPARATEGROUPS) {    // Separate groups are being used
+        $groups = get_records_sql_menu("SELECT g.name, g.id
+                                          FROM {$CFG->prefix}groups g,
+                                                 {$CFG->prefix}groups_members m
+                                          WHERE g.courseid = '$course->id'
+                                             AND g.id = m.groupid
+                                             AND m.userid = '$userid'
+                                             ORDER BY name ASC");
+        $groups = array_values($groups);
+        
+        $teachers = feedback_get_viewreports_users($cm->id, $groups);
+    } else {
+        $teachers = feedback_get_viewreports_users($cm->id);
+    }
+    
+    if ($teachers) {
+
+        $strfeedbacks = get_string('modulenameplural', 'feedback');
+        $strfeedback  = get_string('modulename', 'feedback');
+        $strcompleted  = get_string('completed', 'feedback');
+        $printusername = $feedback->anonymous == FEEDBACK_ANONYMOUS_NO ? fullname($user) : get_string('anonymous_user', 'feedback');
+        
+        foreach ($teachers as $teacher) {
+            unset($info);
+            $info->username = $printusername;
+            $info->feedback = format_string($feedback->name,true);
+            $info->url = $CFG->wwwroot.'/mod/feedback/show_entries.php?id='.$cm->id.'&userid='.$userid.'&do_show=showentries';
+
+            $postsubject = $strcompleted.': '.$info->username.' -> '.$feedback->name;
+            $posttext = feedback_email_teachers_text($info, $course);
+            $posthtml = ($teacher->mailformat == 1) ? feedback_email_teachers_html($info, $course, $cm) : '';
+            
+            if($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) {
+                @email_to_user($teacher, $user, $postsubject, $posttext, $posthtml);
+            }else {
+                @email_to_user($teacher, $teacher, $postsubject, $posttext, $posthtml);
+            }
+        }
+    }
+}
+
+/** 
+ *  sends an email to the teachers of the course where the given feedback is placed.
+ *  @param object $cm the coursemodule-record
+ *  @param $feedback
+ *  @param $course
+ *  @return void
+ */
+function feedback_email_teachers_anonym($cm, $feedback, $course) {
+    
+    global $CFG;
+    
+    if ($feedback->email_notification == 0) {             // No need to do anything
+        return;
+    }
+    
+    // $teachers = get_course_teachers($course->id);
+    $teachers = feedback_get_viewreports_users($cm->id);
+
+    if ($teachers) {
+
+        $strfeedbacks = get_string('modulenameplural', 'feedback');
+        $strfeedback  = get_string('modulename', 'feedback');
+        $strcompleted  = get_string('completed', 'feedback');
+        $printusername = get_string('anonymous_user', 'feedback');
+        
+        foreach ($teachers as $teacher) {
+            unset($info);
+            $info->username = $printusername;
+            $info->feedback = format_string($feedback->name,true);
+            $info->url = $CFG->wwwroot.'/mod/feedback/show_entries_anonym.php?id='.$cm->id;
+
+            $postsubject = $strcompleted.': '.$info->username.' -> '.$feedback->name;
+            $posttext = feedback_email_teachers_text($info, $course);
+            $posthtml = ($teacher->mailformat == 1) ? feedback_email_teachers_html($info, $course, $cm) : '';
+            
+            @email_to_user($teacher, $teacher, $postsubject, $posttext, $posthtml);
+        }
+    }
+}
+
+/** 
+ *  send the text-part of the email
+ *  @param object $info includes some infos about the feedback you want to send
+ *  @param object $course
+ *  @return string the text you want to post
+ */
+function feedback_email_teachers_text($info, $course) {
+    $posttext  = $course->shortname.' -> '.get_string('modulenameplural', 'feedback').' -> '.
+                    $info->feedback."\n";
+    $posttext .= '---------------------------------------------------------------------'."\n";
+    $posttext .= get_string("emailteachermail", "feedback", $info)."\n";
+    $posttext .= '---------------------------------------------------------------------'."\n";
+    return $posttext;
+}
+
+
+/** 
+ *  send the html-part of the email
+ *  @param object $info includes some infos about the feedback you want to send
+ *  @param object $course
+ *  @return string the text you want to post
+ */
+function feedback_email_teachers_html($info, $course, $cm) {
+    global $CFG;
+    $posthtml  = '<p><font face="sans-serif">'.
+                '<a href="'.$CFG->wwwroot.htmlspecialchars('/course/view.php?id='.$course->id).'">'.$course->shortname.'</a> ->'.
+                '<a href="'.$CFG->wwwroot.htmlspecialchars('/mod/feedback/index.php?id='.$course->id).'">'.get_string('modulenameplural', 'feedback').'</a> ->'.
+                '<a href="'.$CFG->wwwroot.htmlspecialchars('/mod/feedback/view.php?id='.$cm->id).'">'.$info->feedback.'</a></font></p>';
+    $posthtml .= '<hr /><font face="sans-serif">';
+    $posthtml .= '<p>'.get_string('emailteachermailhtml', 'feedback', $info).'</p>';
+    $posthtml .= '</font><hr />';
+    return $posthtml;
+}
+
+/** 
+ *  print some errors to inform users about this.
+ *  @return void
+ */
+function feedback_print_errors() {
+    global $SESSION;
+               
+    if(empty($SESSION->feedback->errors)) {
+               return;
+    }
+
+    // print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox");
+    print_box_start('generalbox errorboxcontent boxaligncenter boxwidthnormal');
+    print_heading(get_string('handling_error', 'feedback'));
+
+    echo '<p align="center"><b><font color="black"><pre>';
+    print_r($SESSION->feedback->errors) . "\n";
+    echo '</pre></font></b></p>';
+       
+    // print_simple_box_end();
+    print_box_end();
+    echo '<br /><br />';
+    $SESSION->feedback->errors = array(); //remove errors
+} 
+
+?>
diff --git a/mod/feedback/mapcourse.php b/mod/feedback/mapcourse.php
new file mode 100644 (file)
index 0000000..75007ec
--- /dev/null
@@ -0,0 +1,142 @@
+<?php // $Id$
+/**
+* print the form to map courses for global feedbacks
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once("$CFG->libdir/tablelib.php");
+    
+    $id = required_param('id', PARAM_INT); // Course Module ID, or
+    $searchcourse = optional_param('searchcourse', '', PARAM_ALPHANUM);
+    $coursefilter = optional_param('coursefilter', '', PARAM_INT);
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    // $SESSION->feedback->current_tab = 'mapcourse';
+    $current_tab = 'mapcourse';
+    
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+    
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+        
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+    
+    require_login($course->id);
+    
+    if (!$capabilities->mapcourse) {
+        error ('access not allowed');
+    }
+    
+    if ($coursefilter) {
+        $map->feedbackid = $feedback->id;
+        $map->courseid = $coursefilter;
+        // insert a map only if it does exists yet
+        $sql = "select id, feedbackid from {$CFG->prefix}feedback_sitecourse_map where feedbackid = $map->feedbackid and courseid = $map->courseid";
+        if (!get_records_sql($sql) && !insert_record('feedback_sitecourse_map', $map)) {
+            error("Database problem, unable to map feedback = $feedback->id to course = $course->id");
+        }
+    }
+    
+    /// Print the page header
+    // $strfeedbacks = get_string("modulenameplural", "feedback");
+    // $strfeedback = get_string("modulename", "feedback");
+    // $navigation = '';
+    
+    // $feedbackindex = '<a href="'.htmlspecialchars('index.php?id='.$course->id).'">'.$strfeedbacks.'</a> ->';
+    // if ($course->category) {
+        // $navigation = '<a href="'.htmlspecialchars('../../course/view.php?id='.$course->id).'">'.$course->shortname.'</a> ->';
+    // }else if ($courseid > 0 AND $courseid != SITEID) {
+        // $usercourse = get_record('course', 'id', $courseid);
+        // $navigation = '<a href="'.htmlspecialchars('../../course/view.php?id='.$usercourse->id).'">'.$usercourse->shortname.'</a> ->';
+        // $feedbackindex = '';
+    // }
+    
+    // print_header($course->shortname.': '.$feedback->name, $course->fullname,
+                // $navigation.' '.$feedbackindex.' <a href="'.htmlspecialchars('view.php?id='.$id).'">'.$feedback->name.'</a> -> '.get_string('mapcourses', 'feedback'),
+                // '', '', true, update_module_button($cm->id, $course->id, $strfeedback), navmenu($course, $cm));
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    include('tabs.php');
+
+    // print_simple_box(get_string('mapcourseinfo', 'feedback'), 'center', '80%');
+    print_box(get_string('mapcourseinfo', 'feedback'), 'generalbox boxaligncenter boxwidthwide');
+    // print_simple_box_start('center', '70%');
+    print_box_start('generalbox boxaligncenter boxwidthwide');
+    echo '<form method="post">';
+    echo '<input type="hidden" name="id" value="'.$id.'" />';
+    echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
+    
+    $sql = "select c.id, c.shortname from {$CFG->prefix}course c
+            where
+                c.shortname ".sql_ilike()." '%{$searchcourse}%'
+            OR c.fullname ".sql_ilike()." '%{$searchcourse}%'";
+    
+    if (($courses = get_records_sql_menu($sql)) && !empty($searchcourse)) {
+        echo ' ' . get_string('courses') . ': ';
+        choose_from_menu ($courses, 'coursefilter', $coursefilter, 'choose');
+        echo '<input type="submit" value="'.get_string('mapcourse', 'feedback').'"/>';
+        helpbutton('mapcourses', '', 'feedback', true, true);
+        echo '<input type="button" value="'.get_string('searchagain').'" onclick="document.location=\'mapcourse.php?id='.$id.'\'"/>';
+        echo '<input type="hidden" name="searchcourse" value="'.$searchcourse.'"/>';
+        echo '<input type="hidden" name="feedbackid" value="'.$feedback->id.'"/>';
+        helpbutton('searchcourses', '', 'feedback', true, true);
+    } else {
+        echo '<input type="text" name="searchcourse" value="'.$searchcourse.'"/> <input type="submit" value="'.get_string('searchcourses').'"/>';
+        helpbutton('searchcourses', '', 'feedback', true, true);
+    }
+    
+    echo '</form>';
+    
+    if($coursemap = feedback_get_courses_from_sitecourse_map($feedback->id)) {
+        $table = new flexible_table('coursemaps');
+        $table->define_columns( array('course'));
+        $table->define_headers( array(get_string('mappedcourses', 'feedback')));
+    
+        $table->setup();
+    
+        foreach ($coursemap as $cmap) {
+            $table->add_data(array('<a href="'.htmlspecialchars('unmapcourse.php?id='.$id.'&cmapid='.$cmap->id).'"><img src="'.$CFG->pixpath.'/t/delete.gif" alt="Delete" /></a> ('.$cmap->shortname.') '.$cmap->fullname));
+        }
+    
+        $table->print_html();
+    } else {
+        echo '<h3>'.get_string('mapcoursenone', 'feedback').'</h3>';
+    }
+    
+    
+    // print_simple_box_end();
+    print_box_end();
+    
+    print_footer($course);
+
+?>
\ No newline at end of file
diff --git a/mod/feedback/mod.html b/mod/feedback/mod.html
new file mode 100644 (file)
index 0000000..5917386
--- /dev/null
@@ -0,0 +1,156 @@
+<!-- This page defines the form to create or edit an instance of this module -->
+<!-- It is used from /course/mod.php.  The whole instance is available as $form. -->
+
+<?php require_once($CFG->dirroot.'/mod/feedback/lib.php'); ?>
+
+<script type="text/javascript" language="javascript">
+    var openitems = ['openday','openmonth','openyear','openhour', 'openminute'];
+    var closeitems = ['closeday','closemonth','closeyear','closehour', 'closeminute'];
+</script>
+
+<form name="form" method="post" action="<?php echo $ME ?>">
+<center>
+<table cellpadding=5>
+<tr>
+    <td align=right valign=top><p><b><?php  print_string("name", "feedback") ?>:</b></p></td>
+    <td align="left">
+        <input type="text" id="name" name="name" size=30 value="<?php p(isset($form->name)?$form->name:'') ?>" />
+    </td>
+</tr>
+<tr>
+    <td align=right valign=top><p><b><?php  print_string("description", "feedback") ?>:</b></p></td>
+    <td align="left">
+    <?php
+          $form->summary=isset($form->summary)?$form->summary:'';
+       print_textarea($usehtmleditor, 20, 60, 680, 400, "summary", $form->summary);
+    ?>
+    </td>
+</tr>
+<tr valign="top">
+   <td align="right"><b><?php print_string("feedbackopen", "feedback") ?>:</b></td>
+    <td align="left">
+    <?php $form->timeopen=isset($form->timeopen)?$form->timeopen:NULL;?>
+        <input name="openenable" type="checkbox" value="1" alt="<?php print_string("feedbackopen", "feedback") ?>" onclick="return lockoptions('form', 'openenable', openitems)" <?php if ($form->timeopen) echo 'checked="checked"' ?> />
+    <?php
+           print_date_selector("openday", "openmonth", "openyear", $form->timeopen);
+           echo "&nbsp;-&nbsp;";
+           print_time_selector("openhour", "openminute", $form->timeopen);
+           helpbutton('timeopen', get_string('feedbackopens', 'feedback'), 'feedback');
+     ?>
+        <input type="hidden" name="hopenday"    value="0" />
+        <input type="hidden" name="hopenmonth"  value="0" />
+        <input type="hidden" name="hopenyear"   value="0" />
+        <input type="hidden" name="hopenhour"   value="0" />
+        <input type="hidden" name="hopenminute" value="0" />
+    </td>
+</tr>
+<tr valign="top">
+   <td align="right"><b><?php print_string("feedbackclose", "feedback") ?>:</b></td>
+    <td align="left">
+    <?php $form->timeclose=isset($form->timeclose)?$form->timeclose:NULL;?>
+        <input name="closeenable" type="checkbox" value="1" alt="<?php print_string("feedbackclose", "feedback") ?>" onclick="return lockoptions('form', 'closeenable', closeitems)" <?php if ($form->timeclose) echo 'checked="checked"' ?> />
+    <?php
+           print_date_selector("closeday", "closemonth", "closeyear", $form->timeclose);
+           echo "&nbsp;-&nbsp;";
+           print_time_selector("closehour", "closeminute", $form->timeclose);
+           helpbutton('timeclose', get_string('feedbackcloses', 'feedback'), 'feedback');
+     ?>
+        <input type="hidden" name="hcloseday"    value="0" />
+        <input type="hidden" name="hclosemonth"  value="0" />
+        <input type="hidden" name="hcloseyear"   value="0" />
+        <input type="hidden" name="hclosehour"   value="0" />
+        <input type="hidden" name="hcloseminute" value="0" />
+    </td>
+</tr>
+<tr>
+    <td align=right valign=top><p><b><?php  print_string("anonymous_edit", "feedback") ?>:</b></p></td>
+    <td align="left">
+      <?php 
+         $form->anonymous=isset($form->anonymous)?$form->anonymous:NULL;
+         if($form->anonymous == '')$form->anonymous = 1;
+         ?>
+      <input type="radio" name="anonymous" <?php echo ($form->anonymous <= 1)?'checked="checked"':'';?> value="1" />&nbsp;<?php print_string('anonymous', 'feedback');?>
+      <input type="radio" name="anonymous" <?php echo ($form->anonymous == 2)?'checked="checked"':'';?> value="2" />&nbsp;<?php print_string('non_anonymous', 'feedback');?>
+    </td>
+</tr>
+<tr>
+    <?php $form->publish_stats=isset($form->publish_stats)?$form->publish_stats:NULL;?>
+    <td align=right valign=top><p><b><?php  print_string("publish_stats_on_students", "feedback") ?>:</b></p></td>
+    <td align="left">
+      <select name="publish_stats">
+         <option value="0"<?php echo ($form->publish_stats == 0?' selected="selected"':'');?>><?php  print_string("no") ?></option>
+         <option value="1"<?php echo ($form->publish_stats == 1?' selected="selected"':'');?>><?php  print_string("yes") ?></option>
+      </select>
+    </td>
+</tr>
+<tr>
+    <td align=right valign=top><p><b>
+       <?php
+       print_string("email_notification", "feedback");
+    $form->email_notification=isset($form->email_notification)?$form->email_notification:NULL;
+    $form->multiple_submit=isset($form->multiple_submit)?$form->multiple_submit:NULL;
+       ?>:</b></p></td>
+    <td align="left">
+      <select name="email_notification">
+         <option value="0"<?php echo ($form->email_notification == 0?' selected="selected"':'');?>><?php  print_string("no") ?></option>
+         <option value="1"<?php echo ($form->email_notification == 1?' selected="selected"':'');?>><?php  print_string("yes") ?></option>
+      </select>
+      <?php helpbutton('emailnotification', '', 'feedback', true, true); ?>
+    </td>
+</tr>
+<?php
+// check if there is existing responses to this feedback
+if ($feedback = get_record("feedback", "id", $form->instance)) {
+    $completedFeedbackCount = feedback_get_completeds_group_count($feedback);
+} else {
+    $completedFeedbackCount = false;
+}
+?>
+
+<tr>
+    <td align=right valign=top><p><b><?php  print_string("multiple_submit", "feedback") ?>:</b></p></td>
+    <td align="left">
+    <?php if (!$completedFeedbackCount) { ?>
+      <select name="multiple_submit">
+         <option value="0"<?php echo ($form->multiple_submit == 0?' selected="selected"':'');?>><?php  print_string("no") ?></option>
+         <option value="1"<?php echo ($form->multiple_submit == 1?' selected="selected"':'');?>><?php  print_string("yes") ?></option>
+      </select>
+    <?php 
+      helpbutton('multiplesubmit', '', 'feedback', true, true);
+    } else {
+        intval($form->multiple_submit) === 0 ? print_string('no') : print_string('yes');
+    }
+    ?>
+    </td>
+</tr>
+<tr>
+    <td align=right valign=top><p><b><?php  print_string("page_after_submit", "feedback") ?>:</b></p></td>
+    <td align="left">
+      <?php
+         $form->page_after_submit=isset($form->page_after_submit)?$form->page_after_submit:'';
+         print_textarea($usehtmleditor, 20, 60, 680, 400, "page_after_submit", $form->page_after_submit);
+      ?>
+    </td>
+</tr>
+<?php print_standard_coursemodule_settings($form); ?>
+<!-- More rows go in here... -->
+
+</table>
+<!-- These hidden variables are always the same -->
+<input type="hidden" name=course        value="<?php  p($form->course) ?>" />
+<input type="hidden" name=coursemodule  value="<?php  p($form->coursemodule) ?>" />
+<input type="hidden" name=section       value="<?php  p($form->section) ?>" />
+<input type="hidden" name=module        value="<?php  p($form->module) ?>" />
+<input type="hidden" name=modulename    value="<?php  p($form->modulename) ?>" />
+<input type="hidden" name=instance      value="<?php  p($form->instance) ?>" />
+<input type="hidden" name=mode          value="<?php  p($form->mode) ?>" />
+<input type="hidden" name="sesskey" value="<?php p($USER->sesskey);?>" />
+<input type="submit" value="<?php  print_string("savechanges") ?>" />
+</center>
+</form>
+<script type="text/javascript">
+<?php 
+    if (!$form->timeclose) echo "lockoptions('form','closeenable', closeitems);";
+    if (!$form->timeopen) echo "lockoptions('form','openenable', openitems);";
+?>
+</script>
diff --git a/mod/feedback/mod_form.php b/mod/feedback/mod_form.php
new file mode 100644 (file)
index 0000000..2b094e8
--- /dev/null
@@ -0,0 +1,109 @@
+<?php // $Id$
+/**
+* print the form to add or edit a feedback-instance
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once ($CFG->dirroot.'/course/moodleform_mod.php');
+
+class mod_feedback_mod_form extends moodleform_mod {
+
+    function definition() {
+        global $CFG;
+
+        $mform    =& $this->_form;
+
+        //-------------------------------------------------------------------------------
+        $mform->addElement('header', 'general', get_string('general', 'form'));
+        
+        $mform->addElement('text', 'name', get_string('name', 'feedback'), array('size'=>'64'));
+        $mform->setType('name', PARAM_TEXT);
+        $mform->addRule('name', null, 'required', null, 'client');
+
+        $mform->addElement('htmleditor', 'summary', get_string("description", "feedback"), array('rows' => 20));
+        $mform->setType('summary', PARAM_RAW);
+        $mform->addRule('summary', null, 'required', null, 'client');
+        $mform->setHelpButton('summary', array('writing', 'questions', 'richtext'), false, 'editorhelpbutton');
+
+        //-------------------------------------------------------------------------------
+        $mform->addElement('header', 'timinghdr', get_string('timing', 'form'));
+        
+        $enableopengroup = array();
+        $enableopengroup[] =& $mform->createElement('checkbox', 'openenable', get_string('feedbackopen', 'feedback'));
+        $enableopengroup[] =& $mform->createElement('date_time_selector', 'timeopen', '');
+        $mform->addGroup($enableopengroup, 'enableopengroup', get_string('feedbackopen', 'feedback'), ' ', false);
+        $mform->setHelpButton('enableopengroup', array('timeopen', get_string('feedbackopens', 'feedback'), 'feedback'));
+        $mform->disabledIf('enableopengroup', 'openenable', 'notchecked');
+        
+        $enableclosegroup = array();
+        $enableclosegroup[] =& $mform->createElement('checkbox', 'closeenable', get_string('feedbackclose', 'feedback'));
+        $enableclosegroup[] =& $mform->createElement('date_time_selector', 'timeclose', '');
+        $mform->addGroup($enableclosegroup, 'enableclosegroup', get_string('feedbackclose', 'feedback'), ' ', false);
+        $mform->setHelpButton('enableclosegroup', array('timeclose', get_string('feedbackcloses', 'feedback'), 'feedback'));
+        $mform->disabledIf('enableclosegroup', 'closeenable', 'notchecked');
+        
+        //-------------------------------------------------------------------------------
+        $mform->addElement('header', 'feedbackhdr', get_string('feedback_options', 'feedback'));
+        
+        $options=array();
+        $options[1]  = get_string('anonymous', 'feedback');
+        $options[2]  = get_string('non_anonymous', 'feedback');
+        $mform->addElement('select', 'anonymous', get_string('anonymous_edit', 'feedback'), $options);
+        
+        $mform->addElement('selectyesno', 'publish_stats', get_string('publish_stats_on_students', 'feedback'));
+        $mform->addElement('selectyesno', 'email_notification', get_string('email_notification', 'feedback'));
+        $mform->setHelpButton('email_notification', array('emailnotification', get_string('email_notification', 'feedback'), 'feedback'));
+        
+        // check if there is existing responses to this feedback
+        if ($this->_instance and $feedback = get_record("feedback", "id", $this->_instance)) {
+            $completedFeedbackCount = feedback_get_completeds_group_count($feedback);
+        } else {
+            $completedFeedbackCount = false;
+        }
+        
+        if($completedFeedbackCount) {
+            $multiple_submit_value = $feedback->multiple_submit ? get_string('yes') : get_string('no');
+            $mform->addElement('text', 'multiple_submit_static', get_string('multiple_submit', 'feedback'), array('size'=>'4','disabled'=>'disabled', 'value'=>$multiple_submit_value));
+            $mform->addElement('hidden', 'multiple_submit', '');
+        }else {
+            $mform->addElement('selectyesno', 'multiple_submit', get_string('multiple_submit', 'feedback'));
+        }
+        $mform->setHelpButton('multiple_submit', array('multiplesubmit', get_string('multiple_submit', 'feedback'), 'feedback'));
+        
+        //-------------------------------------------------------------------------------
+        $mform->addElement('header', 'aftersubmithdr', get_string('after_submit', 'feedback'));
+        
+        $mform->addElement('htmleditor', 'page_after_submit', get_string("page_after_submit", "feedback"), array('rows' => 20));
+        $mform->setType('page_after_submit', PARAM_RAW);
+        $mform->setHelpButton('page_after_submit', array('writing', 'questions', 'richtext'), false, 'editorhelpbutton');
+        //-------------------------------------------------------------------------------
+        $this->standard_coursemodule_elements();
+        //-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons();
+    }
+
+    function data_preprocessing(&$default_values){
+        if (empty($default_values['timeopen'])) {
+            $default_values['openenable'] = 0;
+        } else {
+            $default_values['openenable'] = 1;
+        }
+        if (empty($default_values['timeclose'])) {
+            $default_values['closeenable'] = 0;
+        } else {
+            $default_values['closeenable'] = 1;
+        }
+
+    }
+
+    function validation($data){
+
+    }
+
+}
+?>
\ No newline at end of file
diff --git a/mod/feedback/pics/0.gif b/mod/feedback/pics/0.gif
new file mode 100644 (file)
index 0000000..35f2a2e
Binary files /dev/null and b/mod/feedback/pics/0.gif differ
diff --git a/mod/feedback/pics/1.gif b/mod/feedback/pics/1.gif
new file mode 100644 (file)
index 0000000..1d29a80
Binary files /dev/null and b/mod/feedback/pics/1.gif differ
diff --git a/mod/feedback/pics/2.gif b/mod/feedback/pics/2.gif
new file mode 100644 (file)
index 0000000..f4af444
Binary files /dev/null and b/mod/feedback/pics/2.gif differ
diff --git a/mod/feedback/pics/3.gif b/mod/feedback/pics/3.gif
new file mode 100644 (file)
index 0000000..493a95b
Binary files /dev/null and b/mod/feedback/pics/3.gif differ
diff --git a/mod/feedback/pics/4.gif b/mod/feedback/pics/4.gif
new file mode 100644 (file)
index 0000000..907e4e0
Binary files /dev/null and b/mod/feedback/pics/4.gif differ
diff --git a/mod/feedback/pics/5.gif b/mod/feedback/pics/5.gif
new file mode 100644 (file)
index 0000000..4464b0f
Binary files /dev/null and b/mod/feedback/pics/5.gif differ
diff --git a/mod/feedback/pics/6.gif b/mod/feedback/pics/6.gif
new file mode 100644 (file)
index 0000000..a6a2988
Binary files /dev/null and b/mod/feedback/pics/6.gif differ
diff --git a/mod/feedback/pics/7.gif b/mod/feedback/pics/7.gif
new file mode 100644 (file)
index 0000000..d57f330
Binary files /dev/null and b/mod/feedback/pics/7.gif differ
diff --git a/mod/feedback/pics/8.gif b/mod/feedback/pics/8.gif
new file mode 100644 (file)
index 0000000..fc21d18
Binary files /dev/null and b/mod/feedback/pics/8.gif differ
diff --git a/mod/feedback/pics/9.gif b/mod/feedback/pics/9.gif
new file mode 100644 (file)
index 0000000..ddc1492
Binary files /dev/null and b/mod/feedback/pics/9.gif differ
diff --git a/mod/feedback/pics/notrequired.gif b/mod/feedback/pics/notrequired.gif
new file mode 100644 (file)
index 0000000..30ab231
Binary files /dev/null and b/mod/feedback/pics/notrequired.gif differ
diff --git a/mod/feedback/pics/required.gif b/mod/feedback/pics/required.gif
new file mode 100644 (file)
index 0000000..6b0f9a4
Binary files /dev/null and b/mod/feedback/pics/required.gif differ
diff --git a/mod/feedback/print.php b/mod/feedback/print.php
new file mode 100644 (file)
index 0000000..dfbd503
--- /dev/null
@@ -0,0 +1,105 @@
+<?php // $Id$
+/**
+* print a printview of feedback-items
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    $id = required_param('id', PARAM_INT); 
+
+    $formdata = data_submitted('nomatch');
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error(get_string('error'));
+    }
+    
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(format_text($feedback->name));
+
+    feedback_print_errors();
+    
+    $feedbackitems = get_records('feedback_item', 'feedback', $feedback->id, 'position');
+    if(is_array($feedbackitems)){
+        $itemnr = 0;
+        
+        // print_simple_box_start('center', '80%');
+        print_box_start('generalbox boxaligncenter boxwidthwide');
+        echo '<div align="center" class="printview"><table>';
+        //print the inserted items
+        $itempos = 0;
+        foreach($feedbackitems as $feedbackitem){
+            $itempos++;
+            echo '<tr>';
+            //Items without value only are labels
+            if($feedbackitem->hasvalue == 1) {
+                $itemnr++;
+                echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+            } else {
+                echo '<td>&nbsp;</td>';
+            }
+            if($feedbackitem->typ != 'pagebreak') {
+                feedback_print_item($feedbackitem, false, false, true);
+            }else {
+                echo '<td class="feedback_print_pagebreak" colspan="2">&nbsp;</td>';
+            }
+            echo '</tr>';
+        }
+        echo '</table>';
+        echo '<font color="red">(*)' . get_string('items_are_required', 'feedback') . '</font>';
+        echo '</div>';
+        // print_simple_box_end();
+        print_box_end();
+    }else{
+        // print_simple_box(get_string('no_items_available_yet','feedback'),"center");
+        print_box(get_string('no_items_available_yet','feedback'),'generalbox boxaligncenter boxwidthwide');
+    }
+    print_continue('view.php?id='.$id);
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/restorelib.php b/mod/feedback/restorelib.php
new file mode 100644 (file)
index 0000000..93f4c90
--- /dev/null
@@ -0,0 +1,360 @@
+<?php // $Id$
+    //This php script contains all the stuff to backup/restore
+    //feedback mods
+
+    //This is the "graphical" structure of the feedback mod:
+    //
+    //                            feedback---------------------------------feedback_tracking
+    //                          (CL,pk->id)                                     (UL, pk->id, fk->feedback,completed)
+    //                                |                                                         |
+    //                                |                                                         |
+    //                                |                                                         |
+    //                      feedback_template                                     feedback_completed
+    //                         (CL,pk->id)                                    (UL, pk->id, fk->feedback)
+    //                                |                                                         |
+    //                                |                                                         |
+    //                                |                                                         |
+    //                      feedback_item---------------------------------feedback_value
+    //          (ML,pk->id, fk->feedback, fk->template)         (UL, pk->id, fk->item, fk->completed)
+    //
+    // Meaning: pk->primary key field of the table
+    //             fk->foreign key to link with parent
+    //             CL->course level info
+    //             ML->modul level info
+    //             UL->userid level info
+    //             message->text of each feedback_posting
+    //
+    //-----------------------------------------------------------
+     
+    function feedback_restore_mods($mod,$restore) {
+
+        global $CFG;
+        
+        $allValues = array();
+        $allTrackings = array();
+
+        $status = true;
+        $restore_userdata = restore_userdata_selected($restore,'feedback',$mod->id);
+        
+        //Get record from backup_ids
+        $data = backup_getid($restore->backup_unique_code,$mod->modtype,$mod->id);
+        if ($data) {
+            //Now get completed xmlized object    
+            $info = $data->info;
+            
+            //check of older backupversion of feedback
+            $version = intval(backup_todb($info['MOD']['#']['VERSION']['0']['#']));
+            
+            //Now, build the feedback record structure
+            $feedback->course = $restore->course_id;
+            $feedback->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+            $feedback->summary = backup_todb($info['MOD']['#']['SUMMARY']['0']['#']);
+            $feedback->anonymous = backup_todb($info['MOD']['#']['ANONYMOUS']['0']['#']);
+            $feedback->email_notification = backup_todb($info['MOD']['#']['EMAILNOTIFICATION']['0']['#']);
+            $feedback->multiple_submit = backup_todb($info['MOD']['#']['MULTIPLESUBMIT']['0']['#']);
+            $feedback->page_after_submit = backup_todb($info['MOD']['#']['PAGEAFTERSUB']['0']['#']);
+            $feedback->publish_stats = backup_todb($info['MOD']['#']['PUBLISHSTATS']['0']['#']);
+            $feedback->timeopen = backup_todb($info['MOD']['#']['TIMEOPEN']['0']['#']);
+            $feedback->timeclose = backup_todb($info['MOD']['#']['TIMECLOSE']['0']['#']);
+            $feedback->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+
+            //The structure is equal to the db, so insert the feedback
+            $newid = insert_record ("feedback",$feedback);
+            
+            //create events
+            // the open-event
+            if($feedback->timeopen > 0) {
+                $event = NULL;
+                $event->name          = get_string('start', 'feedback').' '.$feedback->name;
+                $event->description = $feedback->summary;
+                $event->courseid     = $feedback->course;
+                $event->groupid      = 0;
+                $event->userid        = 0;
+                $event->modulename  = 'feedback';
+                $event->instance     = $newid;
+                $event->eventtype    = 'open';
+                $event->timestart    = $feedback->timeopen;
+                $event->visible      = instance_is_visible('feedback', $feedback);
+                if($feedback->timeclose > 0) {
+                  $event->timeduration = ($feedback->timeclose - $feedback->timeopen);
+                } else {
+                  $event->timeduration = 0;
+                }
+            
+                add_event($event);
+            }
+        
+            // the close-event
+            if($feedback->timeclose > 0) {
+                $event = NULL;
+                $event->name          = get_string('stop', 'feedback').' '.$feedback->name;
+                $event->description = $feedback->summary;
+                $event->courseid     = $feedback->course;
+                $event->groupid      = 0;
+                $event->userid        = 0;
+                $event->modulename  = 'feedback';
+                $event->instance     = $newid;
+                $event->eventtype    = 'close';
+                $event->timestart    = $feedback->timeclose;
+                $event->visible      = instance_is_visible('feedback', $feedback);
+                $event->timeduration = 0;
+            
+                add_event($event);
+             }
+
+            //Do some output      
+            echo "<ul><li>".get_string("modulename","feedback")." \"".$feedback->name."\"<br />";
+            backup_flush(300);
+
+            if ($newid) {
+                //Now, build the feedback_item record structure
+                $items = $info['MOD']['#']['ITEMS']['0']['#']['ITEM'];
+                for($i = 0; $i < sizeof($items); $i++) {
+                    $item_info = $items[$i];
+                    $item->feedback = $newid;
+                    $item->template = 0;
+                    $item->name = backup_todb($item_info['#']['NAME']['0']['#']);
+                    $item->presentation = backup_todb($item_info['#']['PRESENTATION']['0']['#']);
+                    $item->presentation = str_replace("\n", '', $item->presentation);
+                    if($version >= 1) {
+                        $item->typ = backup_todb($item_info['#']['TYP']['0']['#']);
+                        $item->hasvalue = backup_todb($item_info['#']['HASVALUE']['0']['#']);
+                    } else {
+                        $oldtyp = intval(backup_todb($item_info['#']['TYP']['0']['#']));
+                        switch($oldtyp) {
+                            case 0:
+                                $item->typ = 'label';
+                                $item->hasvalue = 0;
+                                break;
+                            case 1:
+                                $item->typ = 'textfield';
+                                $item->hasvalue = 1;
+                                break;
+                            case 2:
+                                $item->typ = 'textarea';
+                                $item->hasvalue = 1;
+                                break;
+                            case 3:
+                                $item->typ = 'radio';
+                                $item->hasvalue = 1;
+                                break;
+                            case 4:
+                                $item->typ = 'check';
+                                $item->hasvalue = 1;
+                                break;
+                            case 5:
+                                $item->typ = 'dropdown';
+                                $item->hasvalue = 1;
+                                break;
+                        }
+                    }
+                    $item->position = backup_todb($item_info['#']['POSITION']['0']['#']);
+                    $item->required = backup_todb($item_info['#']['REQUIRED']['0']['#']);
+                    //put this new item into the database
+                    $newitemid = insert_record('feedback_item', $item);
+
+                    //Now check if want to restore user data and do it.
+                    if ($restore_userdata) {
+                        $values = $item_info['#']['FBVALUES']['0']['#']['FBVALUE'];
+                        for($ii = 0; $ii < sizeof($values); $ii++) {
+                            $value_info = $values[$ii];
+                            $value->id = '';
+                            $value->item = $newitemid;
+                            $value->completed = 0;
+                            $value->tmp_completed = backup_todb($value_info['#']['COMPLETED']['0']['#']);
+                            $value->value = backup_todb($value_info['#']['VAL']['0']['#']);
+                            $value->value = addslashes($value->value);
+                            $value->course_id = backup_todb($value_info['#']['COURSE_ID']['0']['#']);
+                            //put this new value into the database
+                            $newvalueid = insert_record('feedback_value', $value);
+                            $value->id = $newvalueid;
+                            $allValues[] = $value;
+                        }
+                    }
+                }
+                //Now check if want to restore user data again and do it.
+                if ($restore_userdata) {
+                    //restore tracking-data
+                    $trackings = $info['MOD']['#']['TRACKINGS']['0']['#']['TRACKING'];
+                    for($i = 0; $i < sizeof($trackings); $i++) {
+                        $tracking_info = $trackings[$i];
+                        $tracking->id = '';
+                        $tracking->userid = backup_todb($tracking_info['#']['USERID']['0']['#']); //have to change later
+                        $tracking->feedback = $newid;
+                        $tracking->completed = backup_todb($tracking_info['#']['COMPLETED']['0']['#']); //have to change later
+                        $tracking->count = backup_todb($tracking_info['#']['COUNT']['0']['#']);
+                        if($tracking->userid > 0) {
+                            //We have to recode the userid field
+                            $user = backup_getid($restore->backup_unique_code,"user",$tracking->userid);
+                            if ($user) {
+                                $tracking->userid = $user->new_id;
+                            }
+                        }
+                        
+                        //save the tracking
+                        $newtrackingid = insert_record('feedback_tracking', $tracking);
+                        $tracking->id = $newtrackingid;
+                        $allTrackings[] = $tracking;
+                    }
+                    
+                    //restore completeds
+                    $completeds = $info['MOD']['#']['COMPLETEDS']['0']['#']['COMPLETED'];
+                    for($i = 0; $i < sizeof($completeds); $i++) {
+                        $completed_info = $completeds[$i];
+                        $completed->feedback = $newid;
+                        $completed->userid = backup_todb($completed_info['#']['USERID']['0']['#']);
+                        $completed->timemodified = backup_todb($completed_info['#']['TIMEMODIFIED']['0']['#']);
+                        $completed->random_response = backup_todb($completed_info['#']['RANDOMRESPONSE']['0']['#']);
+                        if(!$anonymous_response = backup_todb($completed_info['#']['ANONYMOUSRESPONSE']['0']['#'])) {
+                            $anonymous_response = 1;
+                        }
+                        $completed->anonymous_response = $anonymous_response;
+                        if($completed->userid > 0) {
+                            //We have to recode the userid field
+                            $user = backup_getid($restore->backup_unique_code,"user",$completed->userid);
+                            if ($user) {
+                                $completed->userid = $user->new_id;
+                            }
+                        }
+                        //later this have to be changed
+                        $oldcompletedid = backup_todb($completed_info['#']['ID']['0']['#']);
+                        
+                        //save the completed
+                        $newcompletedid = insert_record('feedback_completed', $completed);
+                        
+                        //the newcompletedid have to be changed at every values
+                        $tochangevals = get_records('feedback_value', 'tmp_completed', $oldcompletedid);
+                        if($tochangevals) {
+                            foreach($tochangevals as $tmpVal) {
+                                $tmpVal->completed = $newcompletedid;
+                                $tmpVal->tmp_completed = 0;
+                                update_record('feedback_value', $tmpVal);
+                            }
+                        }
+                    
+                        //the newcompletedid have to be changed at every tracking
+                        $tochangetracks = get_records('feedback_tracking', 'completed', $oldcompletedid);
+                        if($tochangetracks) {
+                            foreach($tochangetracks as $tmpTrack) {
+                                $tmpTrack->completed = $newcompletedid;
+                                $tmpTrack->tmp_completed = 0;
+                                update_record('feedback_tracking', $tmpTrack);
+                            }
+                        }
+                    }
+                }
+                
+                //We have the newid, update backup_ids
+                backup_putid($restore->backup_unique_code,$mod->modtype, $mod->id, $newid);
+            } else {
+                $status = false;
+            }
+
+            //Finalize ul          
+            echo "</ul>";
+      
+        } else {
+            $status = false;
+        }
+
+      return $status;
+    }
+
+    //This function returns a log record with all the necessay transformations
+    //done. It's used by restore_log_module() to restore modules log.
+    function feedback_restore_logs($restore,$log) {
+
+        $status = false;
+        
+        //Depending of the action, we recode different things
+        switch ($log->action) {
+        case "add":
+            if ($log->cmid) {
+                //Get the new_id of the module (to recode the info field)
+                $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
+                if ($mod) {
+                    $log->url = "view.php?id=".$log->cmid;
+                    $log->info = $mod->new_id;
+                    $status = true;
+                }
+            }
+            break;
+        case "update":
+            if ($log->cmid) {
+                //Get the new_id of the module (to recode the info field)
+                $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
+                if ($mod) {
+                    $log->url = "view.php?id=".$log->cmid;
+                    $log->info = $mod->new_id;
+                    $status = true;
+                }
+            }
+            break;
+        case "view":
+            if ($log->cmid) {
+                //Get the new_id of the module (to recode the info field)
+                $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
+                if ($mod) {
+                    $log->url = "view.php?id=".$log->cmid;
+                    $log->info = $mod->new_id;
+                    $status = true;
+                }
+            }
+            break;
+        case "add entry":
+            if ($log->cmid) {
+                //Get the new_id of the module (to recode the info field)
+                $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
+                if ($mod) {
+                    $log->url = "view.php?id=".$log->cmid;
+                    $log->info = $mod->new_id;
+                    $status = true;
+                }
+            }
+            break;
+        case "update entry":
+            if ($log->cmid) {
+                //Get the new_id of the module (to recode the info field)
+                $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
+                if ($mod) {
+                    $log->url = "view.php?id=".$log->cmid;
+                    $log->info = $mod->new_id;
+                    $status = true;
+                }
+            }
+            break;
+        case "view responses":
+            if ($log->cmid) {
+                //Get the new_id of the module (to recode the info field)
+                $mod = backup_getid($restore->backup_unique_code,$log->module,$log->info);
+                if ($mod) {
+                    $log->url = "report.php?id=".$log->cmid;
+                    $log->info = $mod->new_id;
+                    $status = true;
+                }
+            }
+            break;
+        case "update feedback":
+            if ($log->cmid) {
+                $log->url = "report.php?id=".$log->cmid;
+                $status = true;
+            }
+            break;
+        case "view all":
+            $log->url = "index.php?id=".$log->course;
+            $status = true;
+            break;
+        default:
+            if (!defined('RESTORE_SILENTLY')) {
+                echo "action (".$log->module."-".$log->action.") unknown. Not restored<br />";                      //Debug
+            }
+            break;
+        }
+
+        if ($status) {
+            $status = $log;
+        }
+        return $status;
+    }
+
+?>
diff --git a/mod/feedback/show_entries.php b/mod/feedback/show_entries.php
new file mode 100644 (file)
index 0000000..204f74e
--- /dev/null
@@ -0,0 +1,303 @@
+<?php // $Id$
+/**
+* print the single entries
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    
+    ////////////////////////////////////////////////////////
+    //get the params
+    ////////////////////////////////////////////////////////
+    $id = required_param('id', PARAM_INT);
+    $userid = optional_param('userid', false, PARAM_INT);
+    $lstgroupid = optional_param('lstgroupid', -2, PARAM_INT); //groupid (choosen from dropdownlist)
+    $do_show = required_param('do_show', PARAM_ALPHA);
+    // $SESSION->feedback->current_tab = $do_show;
+    $current_tab = $do_show;
+
+    //check, whether a group is selected
+    if($lstgroupid == -1) {
+        $SESSION->feedback->lstgroupid = false;
+    }else {
+        if((!isset($SESSION->feedback->lstgroupid)) || $lstgroupid != -2)
+            $SESSION->feedback->lstgroupid = $lstgroupid;
+    }
+    
+    ////////////////////////////////////////////////////////
+    //get the objects
+    ////////////////////////////////////////////////////////
+    
+    if($userid) {
+        $formdata->userid = intval($userid);
+    }
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    
+    if(isset($SESSION->feedback->lstgroupid)) {
+        if($tmpgroup = groups_get_group($SESSION->feedback->lstgroupid)) {
+            if($tmpgroup->courseid != $course->id) {
+                $SESSION->feedback->lstgroupid = false;
+            }
+        }else {
+            $SESSION->feedback->lstgroupid = false;
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+    
+    if(!$capabilities->viewreports){
+        error(get_string('error'));
+    }
+
+    ////////////////////////////////////////////////////////
+    //get the responses of given user
+    ////////////////////////////////////////////////////////
+    if($do_show == 'showoneentry') {
+        //get the feedbackitems
+        $feedbackitems = get_records('feedback_item', 'feedback', $feedback->id, 'position');
+        $feedbackcompleted = get_record_select('feedback_completed','feedback='.$feedback->id.' AND userid='.$formdata->userid.' AND anonymous_response='.FEEDBACK_ANONYMOUS_NO); //arb
+    }
+    
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+                 
+    include('tabs.php');
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    ////////////////////////////////////////////////////////
+    /// Print the links to get responses and analysis
+    ////////////////////////////////////////////////////////
+    if($do_show == 'showentries'){
+        //print the link to analysis
+        if($capabilities->viewreports) {
+            //get the effective groupmode of this course and module
+            $groupmode = groupmode($course, $cm);
+            
+            //get students in conjunction with groupmode
+            if($groupmode > 0) {
+                if($SESSION->feedback->lstgroupid == -2) {
+                    if(isadmin()) {
+                        $mygroupid = false;
+                        $SESSION->feedback->lstgroupid = false;
+                    }else{
+                        if($mygroupid = mygroupid($course->id)) {
+                            $mygroupid = $mygroupid[0]; //get the first groupid
+                        }
+                    }
+                }else {
+                    $mygroupid = $SESSION->feedback->lstgroupid;
+                }
+                if($mygroupid) {
+                    $students = feedback_get_complete_users($cm->id, $mygroupid);
+                } else {
+                    $students = feedback_get_complete_users($cm->id);
+                }
+            }else {
+                $students = feedback_get_complete_users($cm->id);
+            }
+
+            $mygroupid=isset($mygroupid)?$mygroupid:NULL;
+
+            $completedFeedbackCount = feedback_get_completeds_group_count($feedback, $mygroupid);
+            if($feedback->course == SITEID){
+                echo '<div align="center"><a href="'.htmlspecialchars('analysis_course.php?id=' . $id . '&courseid='.$courseid).'">';
+                echo get_string('course') .' '. get_string('analysis', 'feedback') . ' ('.get_string('completed_feedbacks', 'feedback').': '.intval($completedFeedbackCount).')</a>';
+                helpbutton('viewcompleted', '', 'feedback', true, true);
+                echo '</div>';
+            }else {
+                echo '<div align="center"><a href="'.htmlspecialchars('analysis.php?id=' . $id . '&courseid='.$courseid).'">';
+                echo get_string('analysis', 'feedback') . ' ('.get_string('completed_feedbacks', 'feedback').': '.intval($completedFeedbackCount).')</a>';
+                echo '</div>';
+            }
+        }
+    
+        //####### viewreports-start
+        if($capabilities->viewreports) {
+            //print the list of students
+            // print_simple_box_start('center', '80%');
+            print_box_start('generalbox boxaligncenter boxwidthwide');
+
+            //available group modes (NOGROUPS, SEPARATEGROUPS or VISIBLEGROUPS)
+            $feedbackgroups = get_groups($course->id);
+            //if(is_array($feedbackgroups) && $groupmode != SEPARATEGROUPS){
+            if(is_array($feedbackgroups) && $groupmode > 0){
+                require_once('choose_group_form.php');
+                //the use_template-form
+                $choose_group_form = new feedback_choose_group_form();
+                $choose_group_form->set_feedbackdata(array('groups'=>$feedbackgroups, 'mygroupid'=>$mygroupid));
+                $choose_group_form->set_form_elements();
+                $choose_group_form->set_data(array('id'=>$id, 'lstgroupid'=>$SESSION->feedback->lstgroupid, 'do_show'=>$do_show));
+                $choose_group_form->display();
+            }
+            echo '<div align="center"><table><tr><td width="400">';
+            if (!$students) {
+                if($courseid != SITEID){
+                    notify(get_string('noexistingstudents'));
+                }
+            } else{
+                echo print_string('non_anonymous_entries', 'feedback');
+                echo ' ('.count_records_select('feedback_completed', 'feedback = ' . $feedback->id.' AND anonymous_response='.FEEDBACK_ANONYMOUS_NO).')<hr />';
+
+                foreach ($students as $student){
+                    $completedCount = count_records_select('feedback_completed', 'userid = ' . $student->id . ' AND feedback = ' . $feedback->id.' AND anonymous_response='.FEEDBACK_ANONYMOUS_NO);
+                    if($completedCount > 0) {
+                     // Are we assuming that there is only one response per user? Should westep through a feedbackcompleteds? I added the addition anonymous check to the select so that only non-anonymous submissions are retrieved. 
+                        $feedbackcompleted = get_record_select('feedback_completed','feedback='.$feedback->id.' AND userid='.$student->id.' AND anonymous_response='.FEEDBACK_ANONYMOUS_NO);
+                    ?>
+                        <table width="100%">
+                            <tr>
+                                <td align="left">
+                                    <?php echo print_user_picture($student->id, $course->id, $student->picture, false, true);?>
+                                </td>
+                                <td align="left">
+                                    <?php echo fullname($student);?>
+                                </td>
+                                <td align="right">
+                                <?php
+                                    $show_button_link = $ME;
+                                    $show_button_options = array('sesskey'=>$USER->sesskey, 'userid'=>$student->id, 'do_show'=>'showoneentry', 'id'=>$id);
+                                    $show_button_label = get_string('show_entries', 'feedback');
+                                    print_single_button($show_button_link, $show_button_options, $show_button_label, 'post');
+                                ?>
+                                </td>
+                    <?php
+                        if($capabilities->deletesubmissions) {
+                    ?>
+                                <td align="right">
+                                <?php
+                                    $delete_button_link = 'delete_completed.php';
+                                    $delete_button_options = array('sesskey'=>$USER->sesskey, 'completedid'=>$feedbackcompleted->id, 'do_show'=>'showoneentry', 'id'=>$id);
+                                    $delete_button_label = get_string('delete_entry', 'feedback');
+                                    print_single_button($delete_button_link, $delete_button_options, $delete_button_label, 'post');
+                                ?>
+                                </td>
+                    <?php
+                        }
+                    ?>
+                            </tr>
+                        </table>
+                    <?php
+                    }
+                }
+            }
+    ?>
+            <hr />
+            <table width="100%">
+                <tr>
+                    <td align="left" colspan="2">
+                        <?php print_string('anonymous_entries', 'feedback');?>&nbsp;(<?php echo count_records_select('feedback_completed', 'feedback = ' . $feedback->id.' AND anonymous_response='.FEEDBACK_ANONYMOUS_YES);?>)
+                    </td>
+                    <td align="right">
+                        <?php
+                            $show_anon_button_link = 'show_entries_anonym.php';
+                            $show_anon_button_options = array('sesskey'=>$USER->sesskey, 'userid'=>0, 'do_show'=>'showoneentry', 'id'=>$id);
+                            $show_anon_button_label = get_string('show_entries', 'feedback');
+                            print_single_button($show_anon_button_link, $show_anon_button_options, $show_anon_button_label, 'post');
+                        ?>
+                    </td>
+                </tr>
+            </table> 
+    <?php
+            echo '</td></tr></table></div>';
+            // print_simple_box_end();
+            print_box_end();
+        }
+    
+    }
+    ////////////////////////////////////////////////////////
+    /// Print the responses of the given user
+    ////////////////////////////////////////////////////////
+    if($do_show == 'showoneentry') {
+        print_heading(format_text($feedback->name));
+        
+        //print the items
+        if(is_array($feedbackitems)){
+            $usr = get_record('user', 'id', $formdata->userid);
+            if($feedbackcompleted) {
+                echo '<p align="center">'.UserDate($feedbackcompleted->timemodified).'<br />('.fullname($usr).')</p>';
+            } else {
+                echo '<p align="center">'.get_string('not_completed_yet','feedback').'</p>';
+            }
+            // print_simple_box_start("center", '50%');
+            print_box_start('generalbox boxaligncenter boxwidthnormal');
+            echo '<form>';
+            echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+            echo '<table width="100%">';
+            $itemnr = 0;
+            foreach($feedbackitems as $feedbackitem){
+                //get the values
+                $value = get_record_select('feedback_value','completed ='.$feedbackcompleted->id.' AND item='.$feedbackitem->id);
+                echo '<tr>';
+                if($feedbackitem->hasvalue == 1) {
+                    $itemnr++;
+                    echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+                } else {
+                    echo '<td>&nbsp;</td>';
+                }
+                
+                if($feedbackitem->typ != 'pagebreak') {
+                    if(isset($value->value)) {
+                        feedback_print_item($feedbackitem, $value->value, true);
+                    }else {
+                        feedback_print_item($feedbackitem, false, true);
+                    }
+                }else {
+                    echo '<td><hr /></td>';
+                }
+                echo '</tr>';
+            }
+            echo '<tr><td colspan="2" align="center">';
+            echo '</td></tr>';
+            echo '</table>';
+            echo '</form>';
+            // print_simple_box_end();
+            print_box_end();
+        }
+        print_continue(htmlspecialchars('show_entries.php?id='.$id.'&do_show=showentries'));
+    }
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/show_entries_anonym.php b/mod/feedback/show_entries_anonym.php
new file mode 100644 (file)
index 0000000..c776de4
--- /dev/null
@@ -0,0 +1,181 @@
+<?php // $Id$
+/**
+* print the single-values of anonymous completeds
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    // $SESSION->feedback->current_tab = 'showoneentry';
+    $current_tab = 'showentries';
+
+    $id = required_param('id', PARAM_INT); 
+    $userid = optional_param('userid', false, PARAM_INT);
+    
+    if(($formdata = data_submitted('nomatch')) AND !confirm_sesskey()) {
+        error('no sesskey defined');
+    }
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->viewreports){
+        error(get_string('error'));
+    }
+
+
+    //get the completeds
+    // if a new anonymous record has not been assigned a random response number
+    if ($feedbackcompleteds = get_records_select('feedback_completed','feedback='.$feedback->id.' AND random_response=0 AND anonymous_response='.FEEDBACK_ANONYMOUS_YES, 'random_response')){ //arb
+        //then get all of the anonymous records and go through them  
+        $feedbackcompleteds = get_records_select('feedback_completed','feedback='.$feedback->id.' AND anonymous_response='.FEEDBACK_ANONYMOUS_YES,'id'); //arb
+        shuffle($feedbackcompleteds);
+        $num = 1;
+        foreach($feedbackcompleteds as $compl){
+            $compl->random_response = $num;
+            update_record('feedback_completed', $compl);
+            $num++;
+        }
+    }
+    $feedbackcompleteds = get_records_select('feedback_completed','feedback='.$feedback->id.' AND anonymous_response='.FEEDBACK_ANONYMOUS_YES, 'random_response'); //arb
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    include('tabs.php');
+    
+    print_heading(format_text($feedback->name));
+    
+    print_continue(htmlspecialchars('show_entries.php?id='.$id.'&do_show=showentries'));
+    //print the list with anonymous completeds
+    // print_simple_box_start("center");
+    print_box_start('generalbox boxaligncenter boxwidthwide');
+?>
+    <script type="text/javascript">
+        function feedbackGo2delete(form)
+        {
+            form.action = "<?php echo $CFG->wwwroot;?>/mod/feedback/delete_completed.php";
+            form.submit();
+        }
+    </script>
+
+    <div align="center">
+    <form name="frm" action="<?php echo me();?>" method="post">
+        <table>
+            <tr>
+                <td>
+                    <input type="hidden" name="sesskey" value="<?php echo $USER->sesskey;?>" />
+                    <select name="completedid" size="<?php echo (sizeof($feedbackcompleteds)>10)?10:5;?>">
+<?php
+                    if(is_array($feedbackcompleteds)) {
+                        $num = 1;
+                        foreach($feedbackcompleteds as $compl) {
+                            $selected = (isset($formdata->completedid) AND $formdata->completedid == $compl->id)?'selected="selected"':'';
+                            echo '<option value="'.$compl->id.'" '. $selected .'>'.get_string('response_nr', 'feedback').': '. $compl->random_response. '</option>';//arb
+                            $num++;
+                        }
+                    }
+?>
+                    </select>
+                    <input type="hidden" name="showanonym" value="<?php echo FEEDBACK_ANONYMOUS_YES;?>" />
+                    <input type="hidden" name="id" value="<?php echo $id;?>" />
+                </td>
+                <td valign="top">
+                    <button type="submit"><?php print_string('show_entry', 'feedback');?></button><br />
+                    <button type="button" onclick="feedbackGo2delete(this.form);"><?php print_string('delete_entry', 'feedback');?></button>
+                </td>
+            </tr>
+        </table>
+    </form>
+    </div>
+<?php
+    // print_simple_box_end();
+    print_box_end();
+    if(!isset($formdata->completedid)) {
+        $formdata = null;
+    }
+    //print the items
+    if(isset($formdata->showanonym) && $formdata->showanonym == FEEDBACK_ANONYMOUS_YES) {
+        //get the feedbackitems
+        $feedbackitems = get_records('feedback_item', 'feedback', $feedback->id, 'position');
+        $feedbackcompleted = get_record('feedback_completed', 'id', $formdata->completedid);
+        if(is_array($feedbackitems)){
+            if($feedbackcompleted) {
+                echo '<p align="center">'.get_string('chosen_feedback_response', 'feedback').'<br />('.get_string('anonymous', 'feedback').')</p>';//arb
+            } else {
+                echo '<p align="center">'.get_string('not_completed_yet','feedback').'</p>';
+            }
+            // print_simple_box_start("center", '50%');
+            print_box_start('generalbox boxaligncenter boxwidthnormal');
+            echo '<form>';
+            echo '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />';
+            echo '<table width="100%">';
+            $itemnr = 0;
+            foreach($feedbackitems as $feedbackitem){
+                //get the values
+                $value = get_record_select('feedback_value','completed ='.$feedbackcompleted->id.' AND item='.$feedbackitem->id);
+                echo '<tr>';
+                if($feedbackitem->hasvalue == 1) {
+                    $itemnr++;
+                    echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+                } else {
+                    echo '<td>&nbsp;</td>';
+                }
+                if($feedbackitem->typ != 'pagebreak') {
+                    $itemvalue = isset($value->value) ? $value->value : false;
+                    feedback_print_item($feedbackitem, $itemvalue, true);
+                }else {
+                    echo '<td colspan="2"><hr /></td>';
+                }
+                echo '</tr>';
+            }
+            echo '<tr><td colspan="2" align="center">';
+            echo '</td></tr>';
+            echo '</table>';
+            echo '</form>';
+            // print_simple_box_end();
+            print_box_end();
+        }
+    }
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/styles.php b/mod/feedback/styles.php
new file mode 100644 (file)
index 0000000..2cfc196
--- /dev/null
@@ -0,0 +1,9 @@
+/* styles using by feedback */
+.feedback_required_mark {
+    color: #FF0000;
+}
+
+.feedback_switchrequired img{
+}
+
+
diff --git a/mod/feedback/tabs.php b/mod/feedback/tabs.php
new file mode 100644 (file)
index 0000000..f8952a6
--- /dev/null
@@ -0,0 +1,47 @@
+<?php // $Id$
+/**
+* prints the tabbed bar
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+    defined('FEEDBACK_INCLUDE_TEST') OR die('not allowed');
+
+    $tabs = array();
+    $row  = array();
+    $inactive = array();
+    $activated = array();
+
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    // $current_tab = $SESSION->feedback->current_tab;
+    if (!isset($current_tab)) {
+        $current_tab = '';
+    }
+
+    $row[] = new tabobject('view', $CFG->wwwroot.htmlspecialchars('/mod/feedback/view.php?id='.$id.'&do_show=view'), get_string('overview', 'feedback'));
+    
+    if($capabilities->edititems) {
+        $row[] = new tabobject('edit', $CFG->wwwroot.htmlspecialchars('/mod/feedback/edit.php?id='.$id.'&do_show=edit'), get_string('edit_items', 'feedback'));
+        $row[] = new tabobject('templates', $CFG->wwwroot.htmlspecialchars('/mod/feedback/edit.php?id='.$id.'&do_show=templates'), get_string('templates', 'feedback'));
+    }
+    
+    if($capabilities->viewreports) {
+        if($feedback->course == SITEID){
+            $row[] = new tabobject('analysis', $CFG->wwwroot.htmlspecialchars('/mod/feedback/analysis_course.php?id='.$id.'&courseid='.$courseid.'&do_show=analysis'), get_string('analysis', 'feedback'));
+        }else {
+            $row[] = new tabobject('analysis', $CFG->wwwroot.htmlspecialchars('/mod/feedback/analysis.php?id='.$id.'&courseid='.$courseid.'&do_show=analysis'), get_string('analysis', 'feedback'));
+        }
+    }
+    
+    if($capabilities->viewreports) {
+        $row[] = new tabobject('showentries', $CFG->wwwroot.htmlspecialchars('/mod/feedback/show_entries.php?id='.$id.'&do_show=showentries'), get_string('show_entries', 'feedback'));
+    }
+    
+    if(count($row) > 1) {
+        $tabs[] = $row;
+
+        print_tabs($tabs, $current_tab, $inactive, $activated);
+    }
+?>
diff --git a/mod/feedback/unmapcourse.php b/mod/feedback/unmapcourse.php
new file mode 100644 (file)
index 0000000..2b73bfc
--- /dev/null
@@ -0,0 +1,46 @@
+<?php // $Id$
+/**
+* drops records from feedback_sitecourse_map
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once($CFG->dirroot.'/mod/feedback/lib.php');
+
+    $id = required_param('id', PARAM_INT);
+    $cmapid = required_param('cmapid', PARAM_INT);
+    
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+        
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+    
+    if (!$capabilities->mapcourse) {
+        error ('access not allowed');
+    }
+
+
+    // cleanup all lost entries after deleting courses or feedbacks
+    feedback_clean_up_sitecourse_map();
+
+    if (delete_records('feedback_sitecourse_map', 'id', $cmapid)) {
+        redirect (htmlspecialchars('mapcourse.php?id='.$id));
+    } else {
+        error('Database problem, unable to unmap');
+    }
+
+?>
\ No newline at end of file
diff --git a/mod/feedback/use_templ.php b/mod/feedback/use_templ.php
new file mode 100644 (file)
index 0000000..5bcda2b
--- /dev/null
@@ -0,0 +1,128 @@
+<?php // $Id$
+/**
+* print the confirm dialog to use template and create new items from template
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+    require_once("../../config.php");
+    require_once("lib.php");
+    require_once('use_templ_form.php');
+
+    $id = required_param('id', PARAM_INT); 
+    $templateid = optional_param('templateid', false, PARAM_INT);
+    $deleteolditems = optional_param('deleteolditems', 0, PARAM_INT);
+   
+    if(!$templateid) {
+        redirect('edit.php?id='.$id);
+    }
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    require_login($course->id);
+    
+    if(!$capabilities->edititems){
+        error(get_string('error'));
+    }
+    
+    $mform = new mod_feedback_use_templ_form();
+    $newformdata = array('id'=>$id,
+                        'templateid'=>$templateid,
+                        'confirmadd'=>'1',
+                        'deleteolditems'=>'1',
+                        'do_show'=>'edit');
+    $mform->set_data($newformdata);
+    $formdata = $mform->get_data();
+    
+    if ($mform->is_cancelled()) {
+        redirect('edit.php?id='.$id.'&do_show=templates');
+    }
+    
+    if(isset($formdata->confirmadd) AND $formdata->confirmadd == 1){
+        feedback_items_from_template($feedback, $templateid, $deleteolditems);
+        redirect('edit.php?id=' . $id);
+    }
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    print_heading(format_text($feedback->name));
+    
+    // print_simple_box_start("center", "60%", "#FFAAAA", 20, "noticebox");
+    print_box_start('generalbox errorboxcontent boxaligncenter boxwidthnormal');
+    print_heading(get_string('confirmusetemplate', 'feedback'));
+    
+    $mform->display();
+
+    // print_simple_box_end();
+    print_box_end();
+
+    $templateitems = get_records('feedback_item', 'template', $templateid, 'position');
+    if(is_array($templateitems)){
+        $templateitems = array_values($templateitems);
+    }
+
+    if(is_array($templateitems)){
+        $itemnr = 0;
+        echo '<p align="center">'.get_string('preview', 'feedback').'</p>';
+        // print_simple_box_start('center', '75%');
+        print_box_start('generalbox boxaligncenter boxwidthwide');
+        echo '<div align="center"><table>';
+        foreach($templateitems as $templateitem){
+            echo '<tr>';
+            if($templateitem->hasvalue == 1) {
+                $itemnr++;
+                echo '<td valign="top">' . $itemnr . '.)&nbsp;</td>';
+            } else {
+                echo '<td>&nbsp;</td>';
+            }
+            if($templateitem->typ != 'pagebreak') {
+                feedback_print_item($templateitem);
+            }else {
+                echo '<td><hr /></td><td>'.get_string('pagebreak', 'feedback').'</td>';
+            }
+            echo '</tr>';
+            echo '<tr><td>&nbsp;</td></tr>';
+        }
+        echo '</table></div>';
+        // print_simple_box_end();
+        print_box_end();
+    }else{
+        // print_simple_box(get_string('no_items_available_at_this_template','feedback'),"center");
+        print_box(get_string('no_items_available_at_this_template','feedback'),'generalbox boxaligncenter boxwidthwide');
+    }
+
+    print_footer($course);
+
+?>
diff --git a/mod/feedback/use_templ_form.php b/mod/feedback/use_templ_form.php
new file mode 100644 (file)
index 0000000..81a83a4
--- /dev/null
@@ -0,0 +1,37 @@
+<?php // $Id$
+/**
+* prints the form to confirm use template
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+require_once $CFG->libdir.'/formslib.php';
+
+class mod_feedback_use_templ_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        //headline
+        $mform->addElement('header', 'general', '');
+        
+        // visible elements
+        $mform->addElement('radio', 'deleteolditems', get_string('delete_old_items', 'feedback'), '', 1);
+        $mform->addElement('radio', 'deleteolditems', get_string('append_new_items', 'feedback'), '', 0);
+        $mform->setType('deleteolditems', PARAM_INT);
+
+        // hidden elements
+        $mform->addElement('hidden', 'id');
+        $mform->addElement('hidden', 'templateid');
+        $mform->addElement('hidden', 'do_show');
+        $mform->addElement('hidden', 'confirmadd');
+
+        //-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons();
+
+    }
+}
+?>
diff --git a/mod/feedback/version.php b/mod/feedback/version.php
new file mode 100644 (file)
index 0000000..7592d5e
--- /dev/null
@@ -0,0 +1,18 @@
+<?php // $Id$
+/**
+* Code fragment to define the version of feedback
+* This fragment is called by moodle_needs_upgrading() and /admin/index.php
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+
+   
+    $module->version = 2008042300; // The current module version (Date: YYYYMMDDXX)
+    $module->requires = 2007101503;  // Requires this Moodle version
+    $feedback_version_intern = 1; //this version is used for restore older backups
+    $module->cron = 0; // Period for cron to check this module (secs)
+
+?>
diff --git a/mod/feedback/view.php b/mod/feedback/view.php
new file mode 100644 (file)
index 0000000..3a00dad
--- /dev/null
@@ -0,0 +1,190 @@
+<?php // $Id$
+/**
+* the first page to view the feedback
+*
+* @version $Id$
+* @author Andreas Grabs
+* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+* @package feedback
+*/
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    $id = required_param('id', PARAM_INT);
+    $courseid = optional_param('courseid', false, PARAM_INT);
+    
+    // $SESSION->feedback->current_tab = 'view';
+    $current_tab = 'view';
+
+    if ($id) {
+        if (! $cm = get_coursemodule_from_id('feedback', $id)) {
+            error("Course Module ID was incorrect");
+        }
+     
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+     
+        if (! $feedback = get_record("feedback", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    }
+
+    $capabilities = feedback_load_capabilities($cm->id);
+
+    if($feedback->anonymous == FEEDBACK_ANONYMOUS_YES AND !$capabilities->edititems) {
+        $capabilities->complete = true;
+    }
+    
+    //check whether the feedback is located and! started from the mainsite
+    if($course->id == SITEID AND !$courseid) {
+        $courseid = SITEID;
+    }
+    
+    if($feedback->anonymous != FEEDBACK_ANONYMOUS_YES) {
+        require_login($course->id);
+    } else {
+        require_course_login($course);
+    }
+
+    if($feedback->anonymous == FEEDBACK_ANONYMOUS_NO) {
+        add_to_log($course->id, "feedback", "view", "view.php?id=$cm->id", "$feedback->name",$cm->id);
+    }
+
+    /// Print the page header
+    $strfeedbacks = get_string("modulenameplural", "feedback");
+    $strfeedback  = get_string("modulename", "feedback");
+    $buttontext = update_module_button($cm->id, $course->id, $strfeedback);
+    
+    $navlinks = array();
+    $navlinks[] = array('name' => $strfeedbacks, 'link' => "index.php?id=$course->id", 'type' => 'activity');
+    $navlinks[] = array('name' => format_string($feedback->name), 'link' => "", 'type' => 'activityinstance');
+    
+    $navigation = build_navigation($navlinks);
+    
+    print_header_simple(format_string($feedback->name), "",
+                 $navigation, "", "", true, $buttontext, navmenu($course, $cm));
+
+    //ishidden check.
+    if ((empty($cm->visible) and !$capabilities->viewhiddenactivities) AND $course->id != SITEID) {
+        notice(get_string("activityiscurrentlyhidden"));
+    }
+
+    /// Print the main part of the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    /// print the tabs
+    include('tabs.php');
+
+    print_heading(format_text($feedback->name));
+
+    // print_simple_box_start('center', '80%');
+    print_box_start('generalbox boxaligncenter boxwidthwide');
+    echo format_text($feedback->summary);
+    // print_simple_box_end();
+    print_box_end();
+    
+    if($capabilities->edititems) {
+        print_heading(get_string("page_after_submit", "feedback"), '', 4);
+        // print_simple_box_start('center', '80%');
+        print_box_start('generalbox boxaligncenter boxwidthwide');
+        echo format_text($feedback->page_after_submit);
+        // print_simple_box_end();
+        print_box_end();
+    }
+    
+    if( (intval($feedback->publish_stats) == 1) AND !( $capabilities->viewreports) ) {
+        if($multiple_count = count_records('feedback_tracking', 'userid', $USER->id, 'feedback', $feedback->id)) {
+            echo '<div align="center"><a href="'.htmlspecialchars('analysis.php?id=' . $id . '&courseid='.$courseid).'">';
+            echo get_string('completed_feedbacks', 'feedback').'</a>';
+            echo '</div>';
+        }
+    }
+    echo '<p>';
+
+    //####### mapcourse-start
+    if($capabilities->mapcourse) {
+        if($feedback->course == SITEID) {
+            // print_simple_box_start('center', '80%');
+            print_box_start('generalbox boxaligncenter boxwidthwide');
+            echo '<div align="center">';
+            echo '<form action="mapcourse.php" method="get">';
+            echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
+            echo '<input type="hidden" name="id" value="'.$id.'" />';
+            echo '<button type="submit">'.get_string('mapcourses', 'feedback').'</button>';
+            helpbutton('mapcourse', '', 'feedback', true, true);
+            echo '</form>';
+            echo '<br />';
+            echo '</div>';
+            // print_simple_box_end();
+            print_box_end();
+        }
+    }
+    //####### mapcourse-end
+
+    //####### completed-start
+    if($capabilities->complete AND !$capabilities->edititems) {
+        // print_simple_box_start('center', '80%');
+        print_box_start('generalbox boxaligncenter boxwidthwide');
+        //check, whether the feedback is open (timeopen, timeclose)
+        $checktime = time();
+        if(($feedback->timeopen > $checktime) OR ($feedback->timeclose < $checktime AND $feedback->timeclose > 0)) {
+            // print_simple_box_start('center');
+            print_box_start('generalbox boxaligncenter');
+                echo '<h2><font color="red">'.get_string('feedback_is_not_open', 'feedback').'</font></h2>';
+                print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+            // print_simple_box_end();
+            print_box_end();
+            print_footer($course);
+            exit;
+        }
+        
+        //check multiple Submit
+        $feedback_can_submit = true;
+        if($feedback->multiple_submit == 0 ) {
+            if(feedback_is_already_submitted($feedback->id, $courseid)) {
+                $feedback_can_submit = false;
+            }
+        }
+        if($feedback_can_submit) {
+            //if the user is not known so we cannot save the values temporarly
+            if(!isset($USER->username) OR $USER->username == 'guest') {
+                $completefile = 'complete_guest.php';
+                $guestid = $USER->sesskey;
+            }else {
+                $completefile = 'complete.php';
+                $guestid = false;
+            }
+            if($feedbackcompletedtmp = feedback_get_current_completed($feedback->id, true, $courseid, $guestid)) {
+                if($startpage = feedback_get_page_to_continue($feedback->id, $courseid, $guestid)) {
+                    echo '<a href="'.htmlspecialchars($completefile.'?id='.$id.'&gopage='.$startpage.'&courseid='.$courseid).'">'.get_string('continue_the_form', 'feedback').'</a>';
+                }else {
+                    echo '<a href="'.htmlspecialchars($completefile.'?id='.$id.'&gopage=0&courseid='.$courseid).'">'.get_string('continue_the_form', 'feedback').'</a>';
+                }
+            }else {
+                echo '<a href="'.htmlspecialchars($completefile.'?id='.$id.'&gopage=0&courseid='.$courseid).'">'.get_string('complete_the_form', 'feedback').'</a>';
+            }
+        }else {
+            echo '<h2><font color="red">'.get_string('this_feedback_is_already_submitted', 'feedback').'</font></h2>';
+            if($courseid) {
+                print_continue($CFG->wwwroot.'/course/view.php?id='.$courseid);
+            }else {
+                print_continue($CFG->wwwroot.'/course/view.php?id='.$course->id);
+            }
+        }
+        // print_simple_box_end();
+        print_box_end();
+    }
+    //####### completed-end
+    echo "</p>";
+
+    /// Finish the page
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////////
+
+    print_footer($course);
+
+?>