by Ray Kingdon.
Works quite well, but it's not clear yet if this will be part of
major releases (due to the overlap with assignments and workshops
and the confusion this may cause).
--- /dev/null
+<?PHP // $Id$
+
+$string['absent'] = "Absent";
+$string['accumulative'] = "Accumulative";
+$string['action'] = "Action";
+$string['allgradeshaveamaximumof'] = "All Grades have a Maximum of: \$a";
+$string['amendassessmentelements'] = "Amend Assessment Elements";
+$string['amendtitle'] = "Amend Title";
+$string['assess'] = "Assess";
+$string['assessed'] = "Assessed";
+$string['assessment'] = "Assessment";
+$string['assessmentby'] = "Assessment by \$a";
+$string['assessmentform'] = "Assessment Form";
+$string['assessmentmadebythe'] = "Assessment made by the \$a";
+$string['assessments'] = "Assessments";
+$string['assessmentofthissubmission'] = "Assessment of this submission";
+$string['atthisstageyou'] = "At this stage you have completed an assessment.<br />You may want to revise your work in the light of that assessment.<br /> If you do that please remember to also revise your assessment.<br /> You can do this by clicking on the Re-assess link given below.";
+$string['awaitingfeedbackfromthe'] = "Awaiting Feedback from the \$a";
+$string['awaitingassessmentbythe'] = "Awaiting Assessment by the \$a";
+$string['comment'] = "Comment";
+$string['confirmdeletionofthisitem'] = "Confirm Deletion of this \$a";
+$string['correct'] = "Correct";
+$string['criterion'] = "Criterion";
+$string['deadline'] = "Deadline";
+$string['deadlineis'] = "The Deadline is \$a";
+$string['description'] = "Description";
+$string['descriptionofexercise'] = "In an Exercise Assignment the description of the exercise or task to be done by the \$a is put into a Word document or HTML file. This file is uploaded into the exercise before the assignment is opened up to the \$a. It is also possible to create a set of variants on the same exercise or task, again as Word documents or HTML files, and upload these into the exercise before it is opened up to the \$a.";
+$string['delete'] = "Delete";
+$string['deleting'] = "Deleting";
+$string['detailsofassessment'] = "Details of Assessment";
+$string['displayoffinalgrades'] = "Display of Final Grades";
+$string['duedate'] = "Due Date";
+$string['edit'] = "Edit";
+$string['editingassessmentelements'] = "Editing Assessment Elements";
+$string['element'] = "Element";
+$string['elementweight'] = "Element Weight";
+$string['errorbanded'] = "Error Banded";
+$string['excellent'] = "Excellent";
+$string['exerciseassessments'] = "Exercise Assessments";
+$string['exercisefeedback'] = "Exercise Feedback";
+$string['exercisesubmissions'] = "Exercise Submissions";
+$string['generalcomment'] = "General comment";
+$string['good'] = "Good";
+$string['gradeassessment'] = "Grade Assessment";
+$string['gradeforassessment'] = "Grade for Assessment";
+$string['gradeforstudentsassessment'] = "Grade for \$a Assessment";
+$string['gradeforsubmission'] = "Grade for Submission";
+$string['gradetable'] = "Grade Table";
+$string['gradingstrategy'] = "Grading Strategy";
+$string['handlingofmultiplesubmissions'] = "Handling of Multiple Submissions";
+$string['incorrect'] = "Incorrect";
+$string['leaguetable'] = "League Table of Submitted Work";
+$string['managingassignment'] = "Managing the Exercise";
+$string['mail1'] = "Your assignment '\$a' has been assessed by";
+$string['mail2'] = "The comments and grade can be seen in the Exercise Assignment '\$a'";
+$string['mail3'] = "You can see it in your Exercise Assignment";
+$string['mail6'] = "Your assessment of the assignment '\$a' has by reviewed";
+$string['mail7'] = "The comments given by the \$a can be seen in the Exercise Assignment ";
+$string['maximumsize'] = "Maximum Size";
+$string['modulename'] = "Exercise";
+$string['modulenameplural'] = "Exercises";
+$string['movingtophase'] = "Moving to Phase \$a";
+$string['multiplesubmissions'] = "Multiple Submissions";
+$string['noexercisedescriptionssubmitted'] = "No Exercise Descriptions Submitted";
+$string['nosubmissions'] = "No Submissions";
+$string['notavailable'] = "Not Available";
+$string['noteonassessmentelements'] =
+ "Note that grading is broken down into a number of 'Assessment Elements'.<br />
+ This makes the grading easier and more consistent. As teacher you must add these <br />
+ Elements before making the assignment available to students. This is done by<br />
+ clicking on the assignment in the course, if no elements are present you will be asked<br />
+ to add them. You can change the number of elements using the Edit Assignment screen,<br />
+ the elements themselves can be amended from the "Managing Assignment" screen. ";
+$string['noteonstudentassessments'] = "{Grade from student / Grading Grade from teacher}";
+$string['notitlegiven'] = "No Title Given";
+$string['notgraded'] = "Not Graded";
+$string['nowpleasemakeyourownassessment'] = "Now Please make your own Assessment of the Piece of Work from \$a. <br />Note that the Assessment Form is initially given the same grades as the <br />Student's Form. You should make any amendments you think necessary and then <br />click on one of the buttons at the foot of the page.";
+$string['numberofassessmentelements'] = "Number of Comments, Assessment Elements, Grade Bands, Criterion Statments or Categories in a Rubric";
+$string['numberofnegativeresponses'] = "Number of Negative Responses";
+$string['onesubmission'] = "One Submission";
+$string['optionaladjustment'] = "Optional Adjustment";
+$string['overallgrade'] = "Overall Grade";
+$string['phase1'] = "Set Up Exercise";
+$string['phase2'] = "Allow \$a Assessments and Submissions";
+$string['phase3'] = "Stop \$a Assessments and Submissions";
+$string['phase4'] = "Show Overall Grades and League Table";
+$string['pleasegradetheassessment'] = "Please Grade the Assessment of this Piece of Work by \$a";
+$string['pleasesubmityourwork'] = "Please submit your Work using this Form";
+$string['pleaseusethisform'] = "Please complete this form when you have <br />finished the instructions in the exercise shown below.";
+$string['pleaseviewtheexercise'] = "Please view the exercise given below by clicking on it's title.<br />You should follow the instructions in this exercise. <br/>When you are happy that you have completed the exercise<br /> successfully you should click on Assess (or Re-assess) link to the <br />right of the title. When you have done this assessment you will be <br />shown further instructions on what happens next.";
+$string['poor'] = "Poor";
+$string['present'] = "Present";
+$string['reasonforadjustment'] = "Reason for Adjustment";
+$string['reassess'] = "Re-assess";
+$string['resubmitnote'] = "* means that the \$a is allowed to redo this submission. <br /> This flag can be given to any submission by re-assessing it and clicking <br />on the <b>Allow \$a to Re-submit</b> button. <br />The student can resubmit when this flag is present on <b>any</b> of their submissions.";
+$string['rubric'] = "Rubric";
+$string['savemyassessment'] = "Save my Assessment";
+$string['savedok'] = "Saved OK";
+$string['saveweights'] = "Save Weights";
+$string['scaleyes'] = "2 point Yes/No scale";
+$string['scalepresent'] = "2 point Present/Absent scale";
+$string['scalecorrect'] = "2 point Correct/Incorrect scale";
+$string['scalegood3'] = "3 point Good/Poor scale";
+$string['scaleexcellent4'] = "4 point Excellent/Very Poor scale";
+$string['scaleexcellent5'] = "5 point Excellent/Very Poor scale";
+$string['scaleexcellent7'] = "7 point Excellent/Very Poor scale";
+$string['scale10'] = "Score out of 10";
+$string['scale20'] = "Score out of 20";
+$string['scale100'] = "Score out of 100";
+$string['specimenassessmentform'] = "Specimen Assessment Form";
+$string['studentallowedtoresubmit'] = "\$a ALLOWED to re-submit";
+$string['studentassessments'] = "\$a Assessments";
+$string['studentnotallowed'] = "\$a NOT allowed to re-submit";
+$string['studentsubmissionsforassessment'] = "\$a Student Submissions for Assessment";
+$string['studentsubmissions'] = "\$a Submissions";
+$string['submitexercisedescription'] = "Submit Exercise Description";
+$string['submitted'] = "Submitted";
+$string['submittedby'] = "Submitted by";
+$string['submission'] = "Submission";
+$string['submissions'] = "Submissions";
+$string['suggestedgrade'] = "Suggested Grade";
+$string['teacherassessment'] = "\$a Assessment";
+$string['teacherscomment'] = "Teacher's Comment";
+$string['theexerciseandthesubmissionby'] = "The Exercise and the Submission by \$a";
+$string['thegradeis'] = "The Grade is \$a";
+$string['thereisfeedbackfromthe'] = "There is feedback from the \$a";
+$string['thisisaresubmission'] = "This is a Re-submission by \$a.<br />Your assessment of their previous submission is shown. <br />After looking at the new submission, please Amend this assessment<br /> and click on one of the buttons at the foot of the page.";
+$string['title'] = "Title";
+$string['typeofscale'] = "Type of Scale";
+$string['ungradedstudentassessments'] = "\$a Ungraded Student Assessments";
+$string['usemaximum'] = "Use Maximum";
+$string['usemean'] = "Use Mean";
+$string['verypoor'] = "Very Poor";
+$string['view'] = "View";
+$string['viewassessment'] = "View Assessment";
+$string['warningonamendingelements'] = "WARNING: There are submitted assessments. <br />Do NOT change the number of elements, the scale types or the element weights.";
+$string['weightederrorcount'] = "Weighted Error Count: \$a";
+$string['weightforgradingofassessments'] = "Weight for Grading of Assessments";
+$string['weightforteacherassessments'] = "Weight for \$a Assessments";
+$string['weights'] = "Weights";
+$string['weightssaved'] = "Weights Saved";
+$string['weightsusedforoverallgrade'] = "Weights used for Overall Grade";
+$string['yourassessment'] = "Your Assessment";
+$string['yourfeedbackgoeshere'] = "Your Feedback goes Here";
+$string['yoursubmission'] = "Your Submission";
+
+?>
--- /dev/null
+<P ALIGN=CENTER><B>Administration</B></P>
+
+<p>The first table on this screen shows how the the overall grades for the
+ submissions are calculated. The overall grades are a weighted sum of
+ two components.</p>
+
+<ol><li>The teacher's grade for the student's (initial) assessment of their own work.
+ This can be termed the "grading grade". Once the student has
+ submitted their work the assessment is not revised. The student is NOT asked
+ to re-assess their work each time they resubmit their work. The grade given to
+ student's assessment is relavant to the student's performance but it is not as
+ important as the (teacher's) assessment of the work. In general it should be
+ given a lower weight than...
+<li>The grade given by the teacher to the student pieces of work. These
+ assessments are the normally the main assessment element of an exercise
+ assignment. When the students are allowed to make
+ more than one submission the teacher can decide whether the final grade
+ for the exercise should be the average grade of a student's submissions or
+ the grade from the student's best submission.
+</ol>
+
+<p>These two components are weighted as deemed appropriate for the
+ assignment. The teacher can, for example, weight the (initial) assessment grade
+ (the grading grade) very low, even zero. In this case the student grade is
+ determined largely by or entirely by the grades given to their submissions. The
+ two weighting factors can be changed at any time during the exercise, the effect
+ of any change on the grades seen in the Grades page and in the Final Grades
+ list is immediate.</p>
+
+<p>The Administration page also lists the teacher's submissions (the decriptions of
+ the Exercise), the students' (initial) assessment of their own work, and the students'
+ submissions. These tables allow all these items, where appropriate, to be re-titled,
+ deleted, viewed or re-assessed. This part of the page can be used to monitor the
+ students' progress throughout the course of the exercise.
+</p>
--- /dev/null
+<P ALIGN=CENTER><B>Assignment Elements</B></P>
+
+<P>For ease of grading, a Workshop Assignment should have a reasonable
+ number of "Assessment Elements". Each element should cover
+ a particular aspect of the assignment. Typically an assignment will have
+ something between 5 to 15 elements for comments and grading, the
+ actual number depending on the size and complexity of the assignment. A peer
+ assignment with only one element is allowed and has a similar assessment
+ strategy to the standard Moodle Assignment.
+
+<P>The type of elements dependent of the assignment's grading strategy.
+
+<P><B>Not Graded.</B> The elements are descriptions of aspects of the assignment.
+ The assessor is asked to comment on each of these aspects. As with all the grading
+ strategies, there is also an area for general comments.
+
+
+<P><B>Accumulative Grading.</B> The elements have the following three features:
+<OL>
+<LI>The DESCRIPTION of the assessment element. This should clearly state what
+ aspect of the assignment is being assessed. If the assessment is qualatative
+ it is helpful to give details of what is considered excellent, average
+ and poor.
+
+<LI>The SCALE of the assessment element. There are a number of prefined
+ scales. These range from simple Yes/No scales, through multipoint scales to
+ a full percentage scale. Each element has its own scale which should be choosen
+ to fit the number of possible variations for that element. Note that the scale
+ does NOT determine the element's importance when calculating the overall
+ grade, a two point scale has the same "influence" as a 100 point
+ scale if the respective elements have the same weight...
+
+<LI>The WEIGHT of the assessment element. By default the elements are given the same
+ importance when calculating the overall grade of the assignment. This can be
+ changed by giving the more importance elements a weight greater than one, and
+ the less important elements a weight below one. Changing the weights does NOT
+ effect the maximum grade, that value is fixed by the Maximum Grade parameter
+ of the peer assignment. Weights can be assigned negative values, this is an
+ experimental feature.
+</OL>
+<P><B>Error Banded Grading.</B> The elements will normally describe certain items
+ or aspects which must be present in the assignment. The assessment is made on the
+ present or absence of these items or aspects. The teacher must all set of grade table which
+ give the suggested grades when all the items are present, when one is absent, when two are
+ absent, etc. If certain items are more important than others then those items can be given
+ a weighting greater than one. Minor items can be given a weighting less than one. The
+ overall "error count" is a weighted sum of the missing items. The assessor
+ can always make a minor adjustment to these suggested grades.
+
+<P><B>Criterion Grading.</B> The elements will give a set of "level" statements
+which can be used to rank the assignment. The statements may be cumulative or they may
+each be self contained. The assessor must decide which statement best fits each piece of
+work. The teacher must also relate each criterion statement with a suggested grade. These
+should normally be in order. The assessor can make a minor adjustment to these
+suggested grades.</P>
+
+<P><B>Rubric Grading.</B> This is similar to Criterion Grading but there is more than
+one criteria. The number of criteria is given in the assignment parameters. Within each
+criterion there can be up to five "level" statements. In a given assignment
+the number of levels can vary from criterion to criterion. When setting up a criterion a
+blank level statement signals the end of the level statements. Thus some criteria may have
+two levels, others have three, up to five levels. The criteria can be weighted. The levels
+are scored 0, 1, 2, up to 4. The grade for the assessment is a weighted sum of these
+scores.
+</P>
\ No newline at end of file
--- /dev/null
+<P ALIGN=CENTER><B>The Final Grades</B></P>
+
+<p>The table on this screen lists the overall grades and their breakdown. The first grade is
+ the grade for the (inital) assessment. This is added to the grades given to each
+ submission. The Weights row gives the factors used in the calculation of the overall
+ grade from these two grades. The final grade given for this assignment will either be
+ the average of these overall grades or the overall grade of the best submission.
+
+<p>The League table lists each student's best submission. The table is in grade order with
+ the best submission first.</p>
--- /dev/null
+<p align="center"><b>The Grade of the Exercise</b></p>
+
+<p>This value determines the maximum grade which can be awarded in
+ the exercise. The range is 0 to 100%.. This value can be changed at
+ any time during the exercise. Any change has an immediate effect in
+ the Grades page and to the grades given to assessments and
+ submissions.</p>
--- /dev/null
+<P ALIGN=CENTER><B>Grading of Assignments</B></P>
+
+<p>In this Exercise the same Assessment Form is used by Students and Teachers
+ to assess the work produced. The form is used at different stages of the
+ exercise by the two groups, thus the explaination given here is divided into
+ two parts.</p>
+
+<p><b>For Students</b></p>
+
+<p>The assessment form is used mainly to show you how your work will be
+ assessed by the teacher. You are required to complete this form <b>before</b>
+ you can submit your work. You can use it as a checklist. The form is <b>not</b>
+ sent to the teacher when you save it. You can return to this form and amend it
+ (and your piece of work) as many times as you like provided you have
+ <b>not</b> submitted the work. Note that although you are allowed to, there
+ is no need to submit your work immediately after you have completely this form.
+ However, the contents of your assessment are frozen and made available to the
+ teacher when you submit your work.</p>
+
+<p>If the teacher requests that you make changes to your work and to re-submit
+ it, you will <b>not</b> be asked to re-assess your "new" piece of
+ work. You only make this assessment "first time round".</p>
+
+<p>This (initial) assessment of your work is looked at by the teacher and they
+ can add comments and grade it. You will be able to see these comments and
+ the grade given to your assessment may form part of the final grade you
+ receive from this Exercise.</p>
+
+<p><b>For the Teacher</b></p>
+
+<p>The assessment form is used to grade the submissions of the students.
+ These grades normally form the major component of the students' final grade
+ for the exercise. The assessment, it's grade and any comments you make can
+ be viewed by the student who submitted the work. Once you have made the
+ assessment you should decide whether to allow the student to change and
+ re-submit their work, hopefully with improvements, or not.</p>
+
+<p>When you save an assessment you given a short period of time in which to
+ make any amendments before the assessment to "released" to
+ the student.</p>
--- /dev/null
+<P ALIGN=CENTER><B>Grading of Assessments</B></P>
+
+<p>In the first half of this page the Student Assessment of their own work is shown.
+ This assessment should be graded (out of a maximum of 20). It represents an
+ assessment of the work shown in the second of the Link boxes. (The topmost
+ link box is the description of the exercise itself.) The "Grading Grade"
+ should normally be explained in a comment which you enter in the Teacher's
+ Comment box. The grade should reflect the accuracy of the assessment, an
+ assessment which gives a low grade to a poor piece of work should receive
+ a higher Grading Grade than one which gives a low mark to a good piece of
+ work, for example.</p>
+
+<p>In the second half of this page there is a blank Assessment Form for your
+ own assessment of the piece of work from the student.</p>
+
\ No newline at end of file
--- /dev/null
+<P ALIGN=CENTER><B>Grading Strategy</B></P>
+
+<P>A workshop assignment is quite flexible in the type of grading scheme used. This can be:
+
+<OL>
+<LI><B>No grading:</B> In this type of assignment the teacher is not
+ interested in quantative assessment from the students at all. The students
+ make comments of the pieces of works but do not grade them. The teacher,
+ however, can, if desired, grade the student comments. These
+ "grading grades" form the basis of the students' final grades.
+ If the teacher does not grade the student assessments then the assignment
+ does not have any final grades.
+
+<LI><B>Accumulative grading:</B> This is the default type of grading.
+ In this type of assignment the grade of each
+ assessment is made up of a number of "assessment elements".
+ Each element should cover
+ a particular aspect of the assignment. Typically an assignment will have
+ something between 5 to 15 elements for comments and grading, the
+ actual number depending on the size and complexity of the assignment. An
+ exercise assignment with only one element is allowed and has a similar assessment
+ strategy to the standard Moodle Assignment.
+
+<P>Elements have the following three features:
+<OL>
+<LI>The DESCRIPTION of the assessment element. This should clearly state what
+ aspect of the assignment is being assessed. If the assessment is qualatative
+ it is helpful to give details of what is considered excellent, average
+ and poor.
+
+<LI>The SCALE of the assessment element. There are a number of prefined
+ scales. These range from simple Yes/No scales, through multipoint scales to
+ a full percentage scale. Each element has its own scale which should be choosen
+ to fit the number of possible variations for that element. Note that the scale
+ does NOT determine the element's importance when calculating the overall
+ grade, a two point scale has the same "influence" as a 100 point
+ scale if the respective elements have the same weight...
+
+<LI>The WEIGHT of the assessment element. By default the elements are given the same
+ importance when calculating the overall grade of the assignment. This can be
+ changed by giving the more importance elements a weight greater than one, and
+ the less important elements a weight below one. Changing the weights does NOT
+ effect the maximum grade, that value is fixed by the Maximum Grade parameter
+ of the peer assignment. Weights can be assigned negative values, this is an
+ experimental feature.
+</OL>
+
+<LI><B>Error Banded Grading:</B> In this type of assignment the submissions are
+ graded on a set of Yes/No scales. The grade is determined by the "Grade
+ Table " which gives the relationship between the number of
+ "errors" and the suggested grade. For example an assignment may have six
+ significant items which should be present, the Grade Table will give suggested
+ grades if all are present, one is absent, if two are absent, etc. The individual
+ items can, if desired, be given weighting factors if some items are more important
+ than others. The number of "errors" is a weighted sum of the items not
+ present. By default each item is given a weight of one. The grading table is likely
+ to be non-linear, for example
+ the sugested grades may be 90%, 70%, 50%, 40%, 30%, 20%, 10%, 0%, 0%, 0% for
+ an assignment with 10 items.The assessor can adjust the suggested grade by up
+ to 20% either way to give the submission's final grade.
+
+<LI><B>Criterion Grading:</B> This is simpliest type of assessment to grade (although
+ not necessarily the most straightforward to set up). The submissions are
+ graded against a set of criteria statments. The assessor choses which statement
+ best fits the piece of work. The grade is determined by a "Criteria
+ Table" which gives the suggested grade for each criterion. For example
+ an assignment may be set up with, say, five criteria statements and the assessors
+ must then choose one of the five statements for each of their assessments. As with
+ the Banded assignment the assessor can adjust the suggested grade by up to
+ 20% to give the final grade.
+
+<li><b>Rubric</b> This is a similar to Criterion Grading except there are multiple
+ sets of criteria. Each set covering a particular "Category", can have
+ up to five statements. The sets are given individual
+ weights and the grade is a weighted combination of the scores from each set. There
+ is <b>no</b> adjustment option in this assessment type.
+</OL>
+</P>
--- /dev/null
+<P ALIGN=CENTER><B>Managing an Exercise Assignment</B></P>
+
+<P>An Exercise Assignment is slightly more complex than an ordinary assignment.
+ It involves four steps or phases. These are
+<OL>
+<LI><p><b>Set up Exercise </b> The assessment of the work produced in the
+ exercise is made easier if it is broken into a number of assessment ELEMENTS.
+ This makes the grading of an assignment less
+ arbitary and gives the students a framework on which to make assessments.
+ The teacher has the role of setting up the assessment elements thus making a
+ grading sheet. (See that page for more details.)</p>
+
+ <P>With the assessment elements set up the teacher must submit a
+ Word Document or HTML file which describes the exercise or task to be done
+ by the students. This file is shown to the students in the second phase of
+ the exercise. </p>
+
+ <p>Teachers can, if they wish, prepare a set of similar exercies, again as
+ Word Documents or HTML files, and upload those into the Exercise. Note that
+ these exercises must be quite similar as the same Assessment Form is used
+ for all of these variants. The submission of a multiple set of exercises by
+ the teacher is optional and for certain assignments may not be appropriate.</P>
+
+<LI><p><b>Allow Students Assessments and Submissions</b> The assignment
+ is now opened to the students. If the teacher has set up multiple exercises then
+ the students see different exercises, otherwise all the students see the same
+ exercise.</p>
+
+<p>Before the students can submit their work they must complete the assessment
+ form. Once they have completed the assessment they are shown the upload form.
+ The students can revise their work in the light of their self assessment. The teacher
+ sees student's (self) assessment and an assessment form to grade the student's
+ submission. This is a "dual assessment form". At the end of this
+ form the teacher can either ask the student to re-submit the work or not.</p>
+
+<p>If the student chooses to re-submit, the teacher can re-assess the work. The
+ same option, re-submit or not, allows the teacher to control this cycle of
+ re-submission and assessment. If students are allowed to put in multiple pieces
+ of work into the Exercise, the teacher should decide whether the final grades
+ are based on the student's maximum grade or their average grade over the
+ set of submissions. This option can be changed at any time during the Exercise
+ by updating the Exercise, it's effect is seen immediately in the Grade page.
+</p>
+
+<LI><p><b>Stop Student Assessments and Submissions</b> After the deadline
+ has passed, the teacher moves the Exercise to this phase to stop further
+ assessments and submissions. The teacher should complete the grading
+ any outstanding assessments and submissions before moving the Exercise
+ to its final phase.
+
+<li><p><b>Show Overall Grades and League Table</b> In this final phase of
+ the Exercise the students can see their "final" grades. In all
+ phases of the Exercise (except the first phase), grades are available to
+ the students, they are, however, only "partial" grades as they are
+ calculated on the fly from the assessments available at the time.</p>
+
+<p>The students (and the teacher) are also shown a "League Table"
+ of the student submissions. These are listed in order of grade, the top submission
+ is first. Here the grade given to the submission is teacher's
+ grade. If a student submitted more than one piece of work only their best piece
+ of work is shown in this table. </p>
+</ol>
+
+<p>The student's grade is a weighted combination of the teacher's grading of their
+ (initial) assessment and the teacher's grading of their work. The two weighting
+ factors are initally set to unity. They can changed (on the Administration page)
+ at any time during the exercise and the grades shown both the students and the
+ teacher always reflect the current weighting factors.</p>
+
+<p>At any phase of the assignment the teacher can open the "Administration"
+ page. This shows the current values of the two weighting factors and allows the teacher
+ to change them. It lists the students' assessments (of their own work) and the
+ submissions of the students. The teacher can use this page to assess and re-assess
+ submissions, grade and re-grade assessments, delete submissions and assessments,
+ and generally watch the progress of the assignment.</p>
+
--- /dev/null
+<IMG VALIGN=absmiddle SRC="<?php echo $CFG->wwwroot?>/mod/exercise/icon.gif"> <B>Exercise</B>
+
+<UL>
+<P>An Exercise is a simple but powerful assignment. In an exercise the teacher
+asks the students to do a piece of practical work. It could be writing an essay
+or a report, preparing a presentation, or setting out a spreadsheet, etc. When
+the student has done the task they must first self-assess their work before
+submitting it to the teacher. Once submitted the teacher can assess both the
+student's assessment and the piece of work itself. The teacher can give
+feedback to the student and ask the student to improve the work and re-submit
+it or not as the case may be.</p>
+</UL>
+
--- /dev/null
+<IMG VALIGN=absmiddle SRC="<?php echo $CFG->wwwroot?>/mod/exercise/icon.gif"> <B>Exercise</B>
+
+<P>An Exercise is a simple but powerful assignment. In an exercise the teacher
+asks the students to do a piece of practical work. It could be writing an essay
+or a report, preparing a presentation, or setting out a spreadsheet, etc. When
+the student has done the task they must first self-assess their work before
+submitting it to the teacher. Once submitted the teacher can assess both the
+student's assessment and the piece of work itself. The teacher can give
+feedback to the student and ask the student to improve the work and re-submit
+it or not as the case may be.</p>
+
+<p>Before the start of the exercise the teacher sets up the exercise by
+<ol> <li>Creating a Word document or HTML file which introduces the exercise
+ and tells the students what they have to produce. This file is uploaded
+ into the exercise by the teacher.
+
+<li>Adding the textual elements and choosing the options in the Assessment
+ Form. This form is used by both the students and the teacher to assess the
+ work produced in the exercise. There are various types of assessment
+ which can be used (see the help on "Grading Stratgey")
+</ol></p>
+
+<p>In large classes, the teacher may find to helpful to create more than one version
+ of the exercise. These variants add a degree of variety to the exercise and
+ ensure that students are doing different tasks in the exercise. They
+ are allocated to the students in a random but balanced way. Each student
+ receives only one exercise but the the number of
+ times each variant is allocated in a class is approximately the same. Note
+ the variants should not be too different as the same assessment form is used for
+ all of the variants.</p>
+
+<p>With the description(s) of the exercise and the assessment form in place,
+ the assignment is opened to the students. They are shown a description
+ of the exercise or task. When they have done the exercise they must assess
+ their own work (using the pre-prepared assessment form) before they can
+ submit their work to the teacher. The assessment form can be used as a
+ "checklist" by the students. They can, if they wish, revise both
+ their work and the assessment before they actually submit their work, and
+ probably they should be encouraged to do so!</p>
+
+<p>Once a student has submitted their work both their assessment and the
+ piece of work itself becomes available to the teacher. The assessments can be
+ graded and there is a box for comments. The teacher can also access the piece
+ of work (using the student's assessment as a starting point) and make a
+ decision whether to ask the student to re-submit an improved version of the
+ work or not.</p>
+
+<p>If the teacher feels that the student's piece of work could be improved, the
+ student can be given the opprtunity to re-submit. If this is taken up the
+ teacher re-assesses the work using an assessment form which contains
+ the grades and comments they gave to the student's previous submission.
+ Thus, the re-assessment is then a matter of updating the form in the light
+ of the student revised work rather than undertaking an assessment from
+ scratch.</p>
+
+<p>When the deadline for the exercise the teacher moves the exercise to the
+ next phase. This stops further submissions from the students. The assessments
+ and submissions which have not be graded and assessed should now be done.
+
+<p>With all the submissions graded, the exercise is moved to the
+ final phase. The students can now see their final grades and the grades given to
+ their submissions. A student's grade for the exercise is a weighted combination
+ of the teacher's grade for their self-assessment and the teacher's grade for that
+ work. (The grade given by the student is <b>not</b> used.) For the submissions
+ themselves the grade is teacher's assessment. The weights used for the two
+ grades (the grading grade and the actual grade for the work) can be set and
+ changed at any time during the assignment.</p>
+
+<p>When the teacher allows students to resubmit work, the teacher should
+ consider how to set the option which controls how the student's final grade
+ is calculated from multiple submissions. This option allows the teacher to
+ choose between using the mean grade of the student's submissions or their
+ best submission. This option can changed at any time and it has an immediate
+ effect in the grades screen.</p>
+
+<p>In the final phase of the exercise the students can also see a "League
+ Table" of submissions. This an ordered list of the submissions, the
+ submission which received the highest grade is at the top. When there are
+ multiple submissions only the student's best submission is show in this list.</p>
+
--- /dev/null
+<P ALIGN=CENTER><B>Number of Comments, Elements, Bands, Criteria or Rubrics</B></P>
+
+<P>The number entered here determines how many items will be used in
+ the assessments. Depending on the type of grading strategy, this number
+ gives the number of comments, assessments elements, bands, criteria or
+ categories (sets) of criteria in a rubric. Typically an assignment will have
+ something between 5 to 15 assessment items, the
+ actual number depending on the size and complexity of the assignment.
+
+<p>During the set up phase of the exercise this number can safely be adjusted.
+ Increases the number will cause extra blank elements to be displayed in the
+ asessemnt form. Reducing the number will remove elements from the end
+ of the assessment form.</p>
+
+<P>All assessments have a General Comments field. For a "No
+ Grading" assignment the value given here determines the
+ number of additional comment areas. It can be specified as zero and results
+ in the assessment having only a single General Comments area.
+
+</P>
--- /dev/null
+<p align="center"><b>Specimen Assessment Form</b></p>
+
+<p>This page shows shows the details of the actual form used to grade
+ your assignment. It will be used by yourself and the teacher to grade your
+ work.</p>
+
+<p>Please note that although you can change the grades on
+ this form these changes are NOT saved. This is simply a specimen form,
+ but a very similar form will be used by yourself and the teacher
+ during this assignment.</p>
--- /dev/null
+<P ALIGN=CENTER><B>Submission of Exercise Descriptions</B></P>
+
+<P>The teacher must submit at least one description of the exercise or task.
+ The description can be held in a Word document or HTML file (or
+ any other file type that will display satisfactorily in a browser). This file
+ will be displayed to the students and should contain instructions for them
+ to successfully complete the exercise.</p>
+
+<P>It is permissible for the teacher to submit more than one description of
+ the exercise. These will be used at random and different students will see
+ different versions of the exercise. These variants should be similar as the
+ same Assessment Form is used to assess the work from these instructions.</p>
--- /dev/null
+<P ALIGN=CENTER><B>Take Ownership of the Exercises</B></P>
+
+<p>This link allows the teacher to take ownership of the current set of exercise
+ submissions. You will need to do this if you have imported an exercise from a
+ backup of another course. This link allows you to "claim"
+ all the exercise submissions. In the current course these imported submissions
+ could belong to anyone, even a student. This procedure avoids any problems
+ that this may cause and makes you their owner.
+
+<p>Apart from onwership, the submissions themselves are unchanged by this
+ procedure.</p>
\ No newline at end of file
--- /dev/null
+<p align="center"><b>Handling of Multiple Submissions</b></p>
+
+<p>This option determines how the exercise should calculate the
+ final grades of the students. When there are multiple submissions
+ the teacher can chose between either using the best grade or the
+ mean grade from each students' set of submissions. This option
+ can be changed at any time during the exercise. Any change has an
+ immediate effect in the Grades page (provided, of course, multiple
+ submissions are present).</p>
--- /dev/null
+<?PHP // $Id: lib.php,v 1.1 22 Aug 2003
+
+/*************************************************
+ ACTIONS handled are:
+
+ adminconfirmdelete
+ admindelete
+ adminlist
+ adminlistbystudent
+ assesssubmission
+ displaygradingform
+ editelements (teachers only)
+ insertelements (for teachers)
+ listungradedstudentsubmissions (for teachers)
+ listungradedstudentassessments (for teachers)
+ listteachersubmissions
+ teacherassessment (for teachers)
+ updateassessment
+ updatedualassessment
+ userconfirmdelete
+ userdelete
+ viewassessment
+
+************************************************/
+
+ require("../../config.php");
+ require("lib.php");
+
+ require_variable($id); // Course Module ID
+
+ // get some esential stuff...
+ if (! $cm = get_record("course_modules", "id", $id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if (! $course = get_record("course", "id", $cm->course)) {
+ error("Course is misconfigured");
+ }
+
+ if (! $exercise = get_record("exercise", "id", $cm->instance)) {
+ error("Course module is incorrect");
+ }
+
+
+ require_login($course->id);
+
+ $navigation = "";
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+ $strassessments = get_string("assessments", "exercise");
+
+ // ... print the header and...
+ print_header("$course->shortname: $exercise->name", "$course->fullname",
+ "$navigation <A HREF=index.php?id=$course->id>$strexercises</A> ->
+ <A HREF=\"view.php?id=$cm->id\">$exercise->name</A> -> $strassessments",
+ "", "", true);
+
+ //...get the action
+ require_variable($action);
+
+
+ /******************* admin confirm delete ************************************/
+ if ($action == 'adminconfirmdelete' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_GET['aid'])) {
+ error("Admin confirm delete: assessment id missing");
+ }
+
+ notice_yesno(get_string("confirmdeletionofthisitem","exercise", get_string("assessment", "exercise")),
+ "assessments.php?action=admindelete&id=$cm->id&aid=$_GET[aid]",
+ "submissions.php?action=adminlist&id=$cm->id");
+ }
+
+
+ /******************* admin delete ************************************/
+ elseif ($action == 'admindelete' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_GET['aid'])) {
+ error("Admin delete: submission id missing");
+ }
+
+ print_string("deleting", "exercise");
+ // first delete all the associated records...
+ delete_records("exercise_grades", "assessmentid", $_GET['aid']);
+ // ...now delete the assessment...
+ delete_records("exercise_assessments", "id", $_GET['aid']);
+
+ print_continue("submissions.php?id=$cm->id&action=adminlist");
+ }
+
+
+ /*********************** admin list of asssessments (of a submission) (by teachers)**************/
+ elseif ($action == 'adminlist') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ if (empty($_GET['sid'])) {
+ error ("exercise asssessments: adminlist called with no sid");
+ }
+ $submission = get_record("exercise_submissions", "id", $_GET['sid']);
+ exercise_print_assessments_for_admin($exercise, $submission);
+ print_continue("submissions.php?action=adminlist&id=$cm->id");
+ }
+
+
+ /****************** admin list of asssessments by a student (used by teachers only )******************/
+ elseif ($action == 'adminlistbystudent') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ if (empty($_GET['userid'])) {
+ error ("exercise asssessments: adminlistbystudent called with no userid");
+ }
+ $user = get_record("user", "id", $_GET['userid']);
+ exercise_print_assessments_by_user_for_admin($exercise, $user);
+ print_continue("submissions.php?action=adminlist&id=$cm->id");
+ }
+
+
+ /****************** Assess resubmission (by teacher) ***************************/
+ elseif ($action == 'assessresubmission') {
+
+ require_variable($sid);
+
+ if (! $submission = get_record("exercise_submissions", "id", $sid)) {
+ error("Assess submission is misconfigured - no submission record!");
+ }
+ if (!$submissionowner = get_record("user", "id", $submission->userid)) {
+ error("Assess resubmission: user record not found");
+ }
+
+ // there can be an assessment record, if there isn't...
+ if (!$assessment = exercise_get_submission_assessment($submission, $USER)) {
+ if (!$submissions = exercise_get_user_submissions($exercise, $submissionowner)) {
+ error("Assess resubmission: submission records not found");
+ }
+ $n = 0;
+ foreach ($submissions as $prevsubmission) {
+ if ($n == 1) {
+ break;
+ }
+ $n++;
+ }
+ // get the teacher's assessment of the student's previous submission
+ if (!$prevassessment = exercise_get_submission_assessment($prevsubmission, $USER)) {
+ error("Assess resubmission: Previous assessment record not found");
+ }
+ // copy this assessment with comments...
+ $assessment = exercise_copy_assessment($prevassessment, $submission, true);
+ }
+
+ print_heading(get_string("thisisaresubmission", "exercise",
+ "$submissionowner->firstname $submissionowner->lastname"));
+ // show assessment and allow changes
+ exercise_print_assessment_form($exercise, $assessment, true, $_SERVER["HTTP_REFERER"]);
+ }
+
+
+ /****************** Assess submission (by teacher or student) ***************************/
+ elseif ($action == 'assesssubmission') {
+
+ require_variable($sid);
+
+ if (! $submission = get_record("exercise_submissions", "id", $sid)) {
+ error("Assess submission is misconfigured - no submission record!");
+ }
+
+ // there can be an assessment record (for teacher submissions), if there isn't...
+ if (!$assessment = exercise_get_submission_assessment($submission, $USER)) {
+ $yearfromnow = time() + 365 * 86400;
+ // ...create one and set timecreated way in the future, this is reset when record is updated
+ $assessment->exerciseid = $exercise->id;
+ $assessment->submissionid = $submission->id;
+ $assessment->userid = $USER->id;
+ $assessment->grade = -1; // set impossible grade
+ $assessment->timecreated = $yearfromnow;
+ $assessment->timegraded = 0;
+ if (!$assessment->id = insert_record("exercise_assessments", $assessment)) {
+ error("Could not insert exercise assessment!");
+ }
+ }
+
+ // show assessment and allow changes
+ exercise_print_assessment_form($exercise, $assessment, true, $_SERVER["HTTP_REFERER"]);
+ }
+
+
+ /****************** display grading form (viewed by student) *********************************/
+ elseif ($action == 'displaygradingform') {
+
+ print_heading_with_help(get_string("specimenassessmentform", "exercise"), "specimen", "exercise");
+
+ exercise_print_assessment_form($exercise); // called with no assessment
+ print_continue("view.php?id=$cm->id");
+ }\r
+
+
+ /****************** edit assessment elements (for teachers) ***********************/
+ elseif ($action == 'editelements') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ $count = count_records("exercise_grades", "exercise", $exercise->id);
+ if ($exercise->phase > 1 and $count) {
+ notify(get_string("warningonamendingelements", "exercise"));
+ }
+ // set up heading, form and table
+ print_heading_with_help(get_string("editingassessmentelements", "exercise"), "elements", "exercise");
+ ?>
+ <form name="form" method="post" action="assessments.php">
+ <input type="hidden" name="id" value="<?PHP echo $cm->id ?>">
+ <input type="hidden" name="action" value="insertelements">
+ <CENTER><TABLE cellpadding=5 border=1>
+ <?PHP
+
+ // get existing elements, if none set up appropriate default ones
+ if ($elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC" )) {
+ foreach ($elementsraw as $element) {
+ $elements[] = $element; // to renumber index 0,1,2...
+ }
+ }
+ // check for missing elements (this happens either the first time round or when the number
+ // of elements is icreased)
+ for ($i=0; $i<$exercise->nelements; $i++) {
+ if (!isset($elements[$i])) {
+ $elements[$i]->description = '';
+ $elements[$i]->scale =0;
+ $elements[$i]->maxscore = 0;
+ $elements[$i]->weight = 11;
+ }
+ }
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ for ($i=0; $i<$exercise->nelements; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD ALIGN=RIGHT><P><B>". get_string("element","exercise")." $iplus1:</B></TD>\n";
+ echo "<TD><textarea name=\"description[]\" rows=3 cols=75 wrap=\"virtual\">".
+ $elements[$i]->description."</textarea>\n";
+ echo " </TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD colspan=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 1: // accumulative grading
+ // set up scales name
+ foreach ($EXERCISE_SCALES as $KEY => $SCALE) {
+ $SCALES[] = $SCALE['name'];
+ }
+ for ($i=0; $i<$exercise->nelements; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD ALIGN=RIGHT><P><B>". get_string("element","exercise")." $iplus1:</B></TD>\n";
+ echo "<TD><textarea name=\"description[]\" rows=3 cols=75 wrap=\"virtual\">".
+ $elements[$i]->description."</textarea>\n";
+ echo " </TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("typeofscale", "exercise"). ":</B></P></TD>\n";
+ echo "<TD valign=\"top\">\n";
+ choose_from_menu($SCALES, "scale[]", $elements[$i]->scale, "");
+ if ($elements[$i]->weight == '') { // not set
+ $elements[$i]->weight = 11; // unity
+ }
+ echo "</TR>\n";
+ echo "<TR valign=top><TD ALIGN=RIGHT><B>".get_string("elementweight", "exercise").
+ ":</B></TD><TD>\n";
+ exercise_choose_from_menu($EXERCISE_EWEIGHTS, "weight[]", $elements[$i]->weight, "");
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD colspan=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 2: // error banded grading
+ for ($i=0; $i<$exercise->nelements; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD ALIGN=RIGHT><P><B>". get_string("element","exercise")." $iplus1:</B></TD>\n";
+ echo "<TD><textarea name=\"description[$i]\" rows=3 cols=75 wrap=\"virtual\">".
+ $elements[$i]->description."</textarea>\n";
+ echo " </TD></TR>\n";
+ if ($elements[$i]->weight == '') { // not set
+ $elements[$i]->weight = 11; // unity
+ }
+ echo "</TR>\n";
+ echo "<TR valign=top><TD ALIGN=RIGHT><B>".get_string("elementweight", "exercise").
+ ":</B></TD><TD>\n";
+ exercise_choose_from_menu($EXERCISE_EWEIGHTS, "weight[]", $elements[$i]->weight, "");
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD colspan=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ echo "</CENTER></TABLE><BR>\n";
+ echo "<P><CENTER><B>".get_string("gradetable","exercise")."</B></CENTER>\n";
+ echo "<CENTER><TABLE cellpadding=5 border=1><TR><TD ALIGN=\"CENTER\">".
+ get_string("numberofnegativeresponses", "exercise");
+ echo "</TD><TD>". get_string("suggestedgrade", "exercise")."</TD></TR>\n";
+ for ($j = 100; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ for ($i=0; $i<=$exercise->nelements; $i++) {
+ echo "<TR><TD ALIGN=\"CENTER\">$i</TD><TD ALIGN=\"CENTER\">";
+ if (!isset($elements[$i])) { // the "last one" will be!
+ $elements[$i]->description = "";
+ $elements[$i]->maxscore = 0;
+ }
+ choose_from_menu($numbers, "maxscore[$i]", $elements[$i]->maxscore, "");
+ echo "</TD></TR>\n";
+ }
+ break;
+
+ case 3: // criterion grading
+ for ($j = 100; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ for ($i=0; $i<$exercise->nelements; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";\r
+ echo " <TD ALIGN=RIGHT><P><B>". get_string("criterion","exercise")." $iplus1:</B></TD>\n";
+ echo "<TD><textarea name=\"description[$i]\" rows=3 cols=75 wrap=\"virtual\">".
+ $elements[$i]->description."</textarea>\n";
+ echo " </TD></TR>\n";
+ echo "<TR><TD><B>". get_string("suggestedgrade", "exercise").":</B></TD><TD>\n";
+ choose_from_menu($numbers, "maxscore[$i]", $elements[$i]->maxscore, "");
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";\r
+ echo " <TD colspan=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 4: // rubric
+ for ($j = 100; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if ($rubricsraw = get_records("exercise_rubrics", "exerciseid", $exercise->id)) {
+ foreach ($rubricsraw as $rubric) {
+ $rubrics[$rubric->elementno][$rubric->rubricno] = $rubric->description; // reindex 0,1,2...
+ }
+ }
+ for ($i=0; $i<$exercise->nelements; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD ALIGN=RIGHT><P><B>". get_string("element","exercise")." $iplus1:</B></TD>\n";
+ echo "<TD><textarea name=\"description[$i]\" rows=3 cols=75 wrap=\"virtual\">".
+ $elements[$i]->description."</textarea>\n";
+ echo " </TD></TR>\n";
+ echo "<TR valign=top><TD ALIGN=RIGHT><B>".get_string("elementweight", "exercise").
+ ":</B></TD><TD>\n";
+ exercise_choose_from_menu($EXERCISE_EWEIGHTS, "weight[]", $elements[$i]->weight, "");
+ echo " </TD>\n";
+ echo "</TR>\n";
+
+ for ($j=0; $j<5; $j++) {
+ $jplus1 = $j+1;
+ if (empty($rubrics[$i][$j])) {
+ $rubrics[$i][$j] = "";
+ }
+ echo "<TR valign=top>\n";\r
+ echo " <TD ALIGN=RIGHT><P><B>". get_string("grade","exercise")." $j:</B></TD>\n";\r
+ echo "<TD><textarea name=\"rubric[$i][$j]\" rows=3 cols=75 wrap=\"virtual\">".$rubrics[$i][$j]."</textarea>\n";\r
+ echo " </TD></TR>\n";
+ }
+ echo "<TR valign=top>\n";
+ echo " <TD colspan=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+ }
+ // close table and form\r
+ ?>
+ </table><br />
+ <input type="submit" value="<?php print_string("savechanges") ?>">
+ <input type="submit" name=cancel value="<?php print_string("cancel") ?>">
+ </center>\r
+ </form>
+ <?PHP
+ }
+
+
+ /****************** insert/update assignment elements (for teachers)***********************/
+ elseif ($action == 'insertelements') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ $form = (object)$HTTP_POST_VARS;
+
+ // let's not fool around here, dump the junk!
+ delete_records("exercise_elements", "exerciseid", $exercise->id);
+
+ // determine wich type of grading
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ // Insert all the elements that contain something
+ foreach ($form->description as $key => $description) {
+ if ($description) {
+ unset($element);
+ $element->description = $description;
+ $element->exerciseid = $exercise->id;
+ $element->elementno = $key;
+ if (!$element->id = insert_record("exercise_elements", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ }
+ break;
+
+ case 1: // accumulative grading
+ // Insert all the elements that contain something
+ foreach ($form->description as $key => $description) {
+ if ($description) {
+ unset($element);
+ $element->description = $description;
+ $element->exerciseid = $exercise->id;
+ $element->elementno = $key;
+ if (isset($form->scale[$key])) {
+ $element->scale = $form->scale[$key];
+ switch ($EXERCISE_SCALES[$form->scale[$key]]['type']) {
+ case 'radio' : $element->maxscore = $EXERCISE_SCALES[$form->scale[$key]]['size'] - 1;
+ break;
+ case 'selection' : $element->maxscore = $EXERCISE_SCALES[$form->scale[$key]]['size'];
+ break;
+ }
+ }
+ if (isset($form->weight[$key])) {
+ $element->weight = $form->weight[$key];
+ }
+ if (!$element->id = insert_record("exercise_elements", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ }
+ break;
+
+ case 2: // error banded grading...
+ case 3: // ...and criterion grading
+ // Insert all the elements that contain something, the number of descriptions is
+ // one less than the number of grades
+ foreach ($form->maxscore as $key => $themaxscore) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->elementno = $key;
+ $element->maxscore = $themaxscore;
+ if (isset($form->description[$key])) {
+ $element->description = $form->description[$key];
+ }
+ if (isset($form->weight[$key])) {
+ $element->weight = $form->weight[$key];
+ }
+ if (!$element->id = insert_record("exercise_elements", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ break;
+
+ case 4: // ...and criteria grading
+ // Insert all the elements that contain something
+ foreach ($form->description as $key => $description) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->elementno = $key;
+ $element->description = $description;
+ $element->weight = $form->weight[$key];
+ for ($j=0;$j<5;$j++) {
+ if (empty($form->rubric[$key][$j]))
+ break;
+ }
+ $element->maxscore = $j - 1;
+ if (!$element->id = insert_record("exercise_elements", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ // let's not fool around here, dump the junk!
+ delete_records("exercise_rubrics", "exerciseid", $exercise->id);
+ for ($i=0;$i<$exercise->nelements;$i++) {
+ for ($j=0;$j<5;$j++) {
+ unset($element);
+ if (empty($form->rubric[$i][$j])) { // OK to have an element with fewer than 5 items
+ break;
+ }
+ $element->exerciseid = $exercise->id;
+ $element->elementno = $i;
+ $element->rubricno = $j;
+ $element->description = $form->rubric[$i][$j];
+ if (!$element->id = insert_record("exercise_rubrics", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ }
+ break;
+ } // end of switch
+
+ echo "<P>\n";
+ notice_yesno(get_string("amendassessmentelements","exercise")." ".get_string("again"),
+ "assessments.php?id=$cm->id&action=editelements", "view.php?id=$cm->id");
+ }
+
+
+ /****************** list assessments for grading (Student submissions)(by teachers)*********************/
+ elseif ($action == 'listungradedstudentsubmissions') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ exercise_list_ungraded_assessments($exercise, "student");
+ print_continue("view.php?id=$cm->id");
+ }
+
+
+ /***************** list assessments for grading student assessments ( linked to the
+ ******************Teacher's submissions) (by teachers)****/
+ elseif ($action == 'listungradedstudentassessments') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ exercise_list_ungraded_assessments($exercise, "teacher");
+ print_continue("view.php?id=$cm->id");
+ }
+
+
+ /****************** list teacher submissions ***********************/
+ elseif ($action == 'listteachersubmissions') {
+
+ exercise_list_teacher_submissions($exercise, $USER);
+ print_continue("view.php?id=$cm->id");
+ }
+
+
+ /****************** teacher assessment : grading of assessment and submission (from student) ************/
+ elseif ($action == 'teacherassessment') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ require_variable($aid);
+ require_variable($sid);
+ if (!$assessment = get_record("exercise_assessments", "id", $aid)) {
+ error("Teacher assessment: User's assessment record not found");
+ }
+ if (!$submission = get_record("exercise_submissions", "id", $sid)) {
+ error("Teacher assessment: User's submission record not found");
+ }
+ exercise_print_dual_assessment_form($exercise, $assessment, $submission, $_SERVER["HTTP_REFERER"]);
+ }
+
+
+ /****************** update assessment (by teacher or student) ***************************/
+ elseif ($action == 'updateassessment') {
+
+ $timenow = time();
+ $form = (object)$HTTP_POST_VARS;
+
+ require_variable($aid);
+ if (! $assessment = get_record("exercise_assessments", "id", $aid)) {
+ error("exercise assessment is misconfigured");
+ }
+
+ // first get the assignment elements for maxscores and weights...
+ if (!$elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC")) {
+ print_string("noteonassignmentelements", "exercise");
+ }
+ else {
+ foreach ($elementsraw as $element) {
+ $elements[] = $element; // to renumber index 0,1,2...
+ }
+ }
+
+ // don't fiddle about, delete all the old and then add the new!
+ delete_records("exercise_grades", "assessmentid", $assessment->id);
+
+ //determine what kind of grading we have
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ // Insert all the elements that contain something
+ foreach ($form->feedback as $key => $thefeedback) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $key;
+ $element->feedback = $thefeedback;
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ $grade = 0; // set to satisfy save to db
+ break;
+
+ case 1: // accumulative grading
+ // Insert all the elements that contain something
+ foreach ($form->grade as $key => $thegrade) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $key;
+ $element->feedback = $form->feedback[$key];
+ $element->grade = $thegrade;
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ // now work out the grade...
+ $rawgrade=0;
+ $totalweight=0;
+ foreach ($form->grade as $key => $grade) {
+ $maxscore = $elements[$key]->maxscore;
+ $weight = $EXERCISE_EWEIGHTS[$elements[$key]->weight];
+ if ($weight > 0) {
+ $totalweight += $weight;
+ }
+ $rawgrade += ($grade / $maxscore) * $weight;
+ // echo "\$key, \$maxscore, \$weight, \$totalweight, \$grade, \$rawgrade : $key, $maxscore, $weight, $totalweight, $grade, $rawgrade<BR>";
+ }
+ $grade = 100.0 * ($rawgrade / $totalweight);
+ break;
+
+ case 2: // error banded graded
+ // Insert all the elements that contain something
+ $error = 0.0;
+ for ($i =0; $i < $exercise->nelements; $i++) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $i;
+ $element->feedback = $form->feedback[$i];
+ $element->grade = $form->grade[$i];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ if (empty($form->grade[$i])){
+ $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
+ }
+ }
+ // now save the adjustment
+ unset($element);
+ $i = $exercise->nelements;
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $i;
+ $element->grade = $form->grade[$i];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ $grade = $elements[intval($error + 0.5)]->maxscore + $form->grade[$i];
+ // echo "<P><B>".get_string("weightederrorcount", "exercise", intval($error + 0.5)).
+ // " ".get_string("adjustment", "exercise").": ".$form->grade[$i]."</B>\n";
+ // check the grade for sanity!
+ if ($grade >100.0) {
+ $grade = 100.0;
+ }
+ if ($grade < 0.0) {
+ $grade = 0.0;
+ }
+ break;
+
+ case 3: // criteria grading
+ // save in the selected criteria value in element zero,
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = 0;
+ $element->grade = $form->grade[0];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ // now save the adjustment in element one
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = 1;
+ $element->grade = $form->grade[1];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ $grade = ($elements[$form->grade[0]]->maxscore + $form->grade[1]);
+ // check the grade for sanity!
+ if ($grade >100.0) {
+ $grade = 100.0;
+ }
+ if ($grade < 0.0) {
+ $grade = 0.0;
+ }
+ break;
+
+ case 4: // rubric grading (identical to accumulative grading)
+ // Insert all the elements that contain something
+ foreach ($form->grade as $key => $thegrade) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $key;
+ $element->feedback = $form->feedback[$key];
+ $element->grade = $thegrade;
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ // now work out the grade...
+ $rawgrade=0;
+ $totalweight=0;
+ foreach ($form->grade as $key => $grade) {
+ $maxscore = $elements[$key]->maxscore;
+ $weight = $EXERCISE_EWEIGHTS[$elements[$key]->weight];
+ if ($weight > 0) {
+ $totalweight += $weight;
+ }
+ $rawgrade += ($grade / $maxscore) * $weight;
+ }
+ $grade = 100.0 * ($rawgrade / $totalweight);
+ break;
+
+ } // end of switch
+
+ // update the time of the assessment record (may be re-edited)...
+ set_field("exercise_assessments", "timecreated", $timenow, "id", $assessment->id);
+ set_field("exercise_assessments", "grade", $grade, "id", $assessment->id);
+ // ...and clear any grading of this assessment (these assessments are never graded but...)
+ set_field("exercise_assessments", "timegraded", 0, "id", $assessment->id);
+ set_field("exercise_assessments", "gradinggrade", 0, "id", $assessment->id);
+
+ // any comment?
+ if (!empty($form->generalcomment)) {
+ set_field("exercise_assessments", "generalcomment", $form->generalcomment, "id", $assessment->id);
+ }
+
+ // is user allowed to resubmit?
+ if (isteacher($course->id)) {
+ if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
+ error ("Updateassessment: submission record not found");
+ }
+ if ($form->resubmit == 1) {
+ set_field("exercise_submissions", "resubmit", 1, "id", $submission->id);
+ }
+ else {
+ // clear resubmit flag
+ set_field("exercise_submissions", "resubmit", 0, "id", $submission->id);
+ }
+ }
+
+ add_to_log($course->id, "exercise", "assess", "view.php?id=$cm->id", "$assessment->id");
+
+ // set up return address
+ if (!$returnto = $form->returnto) {
+ $returnto = "view.php?id=$cm->id";
+ }
+
+ // show grade if grading strategy is not zero
+ if ($exercise->gradingstrategy) {
+ redirect($returnto, get_string("thegradeis", "exercise").": ".
+ number_format($grade * $exercise->grade / 100.0, 1)."% (".get_string("maximumgrade").
+ " ".number_format($exercise->grade)."%)");
+ }
+ else {
+ redirect($returnto);
+ }
+ }
+
+
+ /****************** update dual assessment (by teacher only) ***************************/
+ elseif ($action == 'updatedualassessment') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ $timenow = time();
+ $form = (object)$HTTP_POST_VARS;
+
+ // first do the teacher's comments and grading grade of the user's assessment
+ if (!$assessment = get_record("exercise_assessments", "id", $form->aid)) {
+ error("Update dual assessment: user's assessment record not found");
+ }
+ //save the comment and grade for the assessment
+ if (isset($form->teachercomment)) {
+ set_field("exercise_assessments", "teachercomment", $form->teachercomment, "id", $assessment->id);
+ set_field("exercise_assessments", "gradinggrade", $form->gradinggrade, "id", $assessment->id);
+ set_field("exercise_assessments", "timegraded", $timenow, "id", $assessment->id);
+ set_field("exercise_assessments", "mailed", 0, "id", $assessment->id);
+ echo "<CENTRE><B>".get_string("savedok", "exercise")."</B></CENTRE><BR>\n";
+
+ add_to_log($course->id, "exercise", "grade", "view.php?id=$cm->id", "$assessment->id");
+ }
+
+ // now do the assessment of a user's submission
+ if (! $submission = get_record("exercise_submissions", "id", $form->sid)) {
+ error("Update dual assessment: user's submission record not found");
+ }
+ if (!$assessment = exercise_get_submission_assessment($submission, $USER)) {
+ error("Update dual assessment: teacher's assessment record not found");
+ }
+
+ // first get the assignment elements for maxscores and weights...
+ if (!$elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC")) {
+ print_string("noteonassignmentelements", "exercise");
+ }
+ else {
+ foreach ($elementsraw as $element) {
+ $elements[] = $element; // to renumber index 0,1,2...
+ }
+ }
+
+ // don't fiddle about, delete all the old and then add the new!
+ delete_records("exercise_grades", "assessmentid", $assessment->id);
+
+ //determine what kind of grading we have
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ // Insert all the elements that contain something
+ foreach ($form->feedback as $key => $thefeedback) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $key;
+ $element->feedback = $thefeedback;
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ $grade = 0; // set to satisfy save to db
+ break;
+
+ case 1: // accumulative grading
+ // Insert all the elements that contain something
+ foreach ($form->grade as $key => $thegrade) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $key;
+ $element->feedback = $form->feedback[$key];
+ $element->grade = $thegrade;
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ // now work out the grade...
+ $rawgrade=0;
+ $totalweight=0;
+ foreach ($form->grade as $key => $grade) {
+ $maxscore = $elements[$key]->maxscore;
+ $weight = $EXERCISE_EWEIGHTS[$elements[$key]->weight];
+ if ($weight > 0) {
+ $totalweight += $weight;
+ }
+ $rawgrade += ($grade / $maxscore) * $weight;
+ // echo "\$key, \$maxscore, \$weight, \$totalweight, \$grade, \$rawgrade : $key, $maxscore, $weight, $totalweight, $grade, $rawgrade<BR>";
+ }
+ $grade = 100.0 * ($rawgrade / $totalweight);
+ break;
+
+ case 2: // error banded graded
+ // Insert all the elements that contain something
+ $error = 0.0;
+ for ($i =0; $i < $exercise->nelements; $i++) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $i;
+ $element->feedback = $form->feedback[$i];
+ $element->grade = $form->grade[$i];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ if (empty($form->grade[$i])){
+ $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
+ }
+ }
+ // now save the adjustment
+ unset($element);
+ $i = $exercise->nelements;
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $i;
+ $element->grade = $form->grade[$i];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ $grade = ($elements[intval($error + 0.5)]->maxscore + $form->grade[$i]);
+ echo "<P><B>".get_string("weightederrorcount", "exercise", intval($error + 0.5))."</B>\n";
+ break;
+
+ case 3: // criteria grading
+ // save in the selected criteria value in element zero,
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = 0;
+ $element->grade = $form->grade[0];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ // now save the adjustment in element one
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = 1;
+ $element->grade = $form->grade[1];
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ $grade = ($elements[$form->grade[0]]->maxscore + $form->grade[1]);
+ break;
+
+ case 4: // rubric grading (identical to accumulative grading)
+ // Insert all the elements that contain something
+ foreach ($form->grade as $key => $thegrade) {
+ unset($element);
+ $element->exerciseid = $exercise->id;
+ $element->assessmentid = $assessment->id;
+ $element->elementno = $key;
+ $element->feedback = $form->feedback[$key];
+ $element->grade = $thegrade;
+ if (!$element->id = insert_record("exercise_grades", $element)) {
+ error("Could not insert exercise element!");
+ }
+ }
+ // now work out the grade...
+ $rawgrade=0;
+ $totalweight=0;
+ foreach ($form->grade as $key => $grade) {
+ $maxscore = $elements[$key]->maxscore;
+ $weight = $EXERCISE_EWEIGHTS[$elements[$key]->weight];
+ if ($weight > 0) {
+ $totalweight += $weight;
+ }
+ $rawgrade += ($grade / $maxscore) * $weight;
+ }
+ $grade = 100.0 * ($rawgrade / $totalweight);
+ break;
+
+ } // end of switch
+
+ // update the time of the assessment record (may be re-edited)...
+ set_field("exercise_assessments", "timecreated", $timenow, "id", $assessment->id);
+ set_field("exercise_assessments", "grade", $grade, "id", $assessment->id);
+ // ...and clear any grading of this assessment (never needed but...)
+ set_field("exercise_assessments", "timegraded", 0, "id", $assessment->id);
+ set_field("exercise_assessments", "gradinggrade", 0, "id", $assessment->id);
+
+ // any comment?
+ if (!empty($form->generalcomment)) {
+ set_field("exercise_assessments", "generalcomment", $form->generalcomment, "id", $assessment->id);
+ }
+
+ // is user allowed to resubmit?
+ if ($form->resubmit == 1) {
+ set_field("exercise_submissions", "resubmit", 1, "id", $submission->id);
+ }
+ else {
+ // clear resubmit flag
+ set_field("exercise_submissions", "resubmit", 0, "id", $submission->id);
+ }
+
+ add_to_log($course->id, "exercise", "assess", "view.php?id=$cm->id", "$assessment->id");
+
+ // set up return address
+ if (!$returnto = $form->returnto) {
+ $returnto = "view.php?id=$cm->id";
+ }
+
+ // show grade if grading strategy is not zero
+ if ($exercise->gradingstrategy) {
+ redirect($returnto, get_string("thegradeis", "exercise").": ".
+ number_format($grade * $exercise->grade / 100.0, 1)."% (".get_string("maximumgrade").
+ " ".number_format($exercise->grade)."%)");
+ }
+ else {
+ redirect($returnto);
+ }
+ }
+
+
+ /****************** user confirm delete ************************************/
+ elseif ($action == 'userconfirmdelete' ) {
+
+ if (empty($_GET['aid'])) {
+ error("User confirm delete: assessment id missing");
+ }
+
+ notice_yesno(get_string("confirmdeletionofthisitem","exercise", get_string("assessment", "exercise")),
+ "assessments.php?action=userdelete&id=$cm->id&aid=$_GET[aid]", "view.php?id=$cm->id");
+ }
+
+
+ /****************** user delete ************************************/
+ elseif ($action == 'userdelete' ) {
+
+ if (empty($_GET['aid'])) {
+ error("User delete: assessment id missing");
+ }
+
+ print_string("deleting", "exercise");
+ // first delete all the associated records...
+ delete_records("exercise_grades", "assessmentid", $_GET['aid']);
+ // ...now delete the assessment...
+ delete_records("exercise_assessments", "id", $_GET['aid']);
+
+ print_continue("view.php?id=$cm->id");
+ }
+
+
+ /****************** view assessment ***********************/
+ elseif ($action == 'viewassessment') {
+
+ // get the assessment record
+ if (!$assessment = get_record("exercise_assessments", "id", $_GET['aid'])) {
+ error("Assessment record not found");
+ }
+
+ // show assessment but don't allow changes
+ exercise_print_assessment_form($exercise, $assessment);
+
+ print_continue("view.php?id=$cm->id");
+ }
+
+
+ /*************** no man's land **************************************/
+ else {
+ error("Fatal Error: Unknown Action: ".$action."\n");
+ }
+
+ print_footer($course);
+
+?>
+
--- /dev/null
+<?PHP //$Id$
+ //This php script contains all the stuff to backup/restore
+ //exercise mods
+
+ //This is the "graphical" structure of the exercise mod:
+ //
+ // exercise
+ // (CL,pk->id)
+ // |
+ // |
+ // |
+ // |------------------------------|---------------------------------------------|
+ // | |
+ // | |
+ // | exercise_submissions
+ // | (UL,pk->id,fk->exerciseid,files)
+ // | |
+ // | |
+ // | |
+ // | |---------------------| |------------------------------| |
+ // | | | | | |
+ // exercise_elements exercise_grades exercise_assessments
+ // (CL,pk->id,fk->exerciseid) (UL,pk->id,fk->assessmentid) (UL,pk->id,fk->submissionid)
+ // | ( fk->elementno )
+ // |
+ // |
+ // exercise_rubrics
+ // (CL,pk->id,fk->elementno)
+ //
+ // Meaning: pk->primary key field of the table
+ // fk->foreign key to link with parent
+ // nt->nested field (recursive data)
+ // CL->course level info
+ // UL->user level info
+ // files->table may have files)
+ //
+ //-----------------------------------------------------------
+
+ //This function executes all the backup procedure about this mod
+ function exercise_backup_mods($bf,$preferences) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Iterate over exercise table
+ $exercises = get_records ("exercise","course",$preferences->backup_course,"id");
+ if ($exercises) {
+ foreach ($exercises as $exercise) {
+ //Start mod
+ fwrite ($bf,start_tag("MOD",3,true));
+ //Print exercise data
+ fwrite ($bf,full_tag("ID",4,false,$exercise->id));
+ fwrite ($bf,full_tag("MODTYPE",4,false,"exercise"));
+ fwrite ($bf,full_tag("NAME",4,false,$exercise->name));
+ fwrite ($bf,full_tag("NELEMENTS",4,false,$exercise->nelements));
+ fwrite ($bf,full_tag("PHASE",4,false,$exercise->phase));
+ fwrite ($bf,full_tag("GRADINGSTRATEGY",4,false,$exercise->gradingstrategy));
+ fwrite ($bf,full_tag("USEMAXIMUM",4,false,$exercise->usemaximum));
+ fwrite ($bf,full_tag("ANONYMOUS",4,false,$exercise->anonymous));
+ fwrite ($bf,full_tag("MAXBYTES",4,false,$exercise->maxbytes));
+ fwrite ($bf,full_tag("DEADLINE",4,false,$exercise->deadline));
+ fwrite ($bf,full_tag("GRADE",4,false,$exercise->grade));
+ fwrite ($bf,full_tag("TIMEMODIFIED",4,false,$exercise->timemodified));
+ fwrite ($bf,full_tag("TEACHERWEIGHT",4,false,$exercise->teacherweight));
+ fwrite ($bf,full_tag("GRADINGWEIGHT",4,false,$exercise->gradingweight));
+ fwrite ($bf,full_tag("SHOWLEAGUETABLE",4,false,$exercise->showleaguetable));
+ //Now we backup exercise elements
+ $status = backup_exercise_elements($bf,$preferences,$exercise->id);
+ //if we've selected to backup users info, then execute backup_exercise_submisions
+ if ($preferences->mods["exercise"]->userinfo) {
+ $status = backup_exercise_submissions($bf,$preferences,$exercise->id);
+ }
+ //End mod
+ $status =fwrite ($bf,end_tag("MOD",3,true));
+ }
+ }
+ //if we've selected to backup users info, then backup files too
+ if ($status) {
+ if ($preferences->mods["exercise"]->userinfo) {
+ $status = backup_exercise_files($bf,$preferences);
+ }
+ }
+ return $status;
+ }
+
+ //Backup exercise_elements contents (executed from exercise_backup_mods)
+ function backup_exercise_elements ($bf,$preferences,$exercise) {
+
+ global $CFG;
+
+ $status = true;
+
+ $exercise_elements = get_records("exercise_elements","exerciseid",$exercise,"id");
+ //If there is exercise_elements
+ if ($exercise_elements) {
+ //Write start tag
+ $status =fwrite ($bf,start_tag("ELEMENTS",4,true));
+ //Iterate over each element
+ foreach ($exercise_elements as $wor_ele) {
+ //Start element
+ $status =fwrite ($bf,start_tag("ELEMENT",5,true));
+ //Print element contents
+ fwrite ($bf,full_tag("ELEMENTNO",6,false,$wor_ele->elementno));
+ fwrite ($bf,full_tag("DESCRIPTION",6,false,$wor_ele->description));
+ fwrite ($bf,full_tag("SCALE",6,false,$wor_ele->scale));
+ fwrite ($bf,full_tag("MAXSCORE",6,false,$wor_ele->maxscore));
+ fwrite ($bf,full_tag("WEIGHT",6,false,$wor_ele->weight));
+ //Now we backup exercise rubrics
+ $status = backup_exercise_rubrics($bf,$preferences,$exercise,$wor_ele->elementno);
+ //End element
+ $status =fwrite ($bf,end_tag("ELEMENT",5,true));
+ }
+ //Write end tag
+ $status =fwrite ($bf,end_tag("ELEMENTS",4,true));
+ }
+ return $status;
+ }
+
+ //Backup exercise_rubrics contents (executed from backup_exercise_elements)
+ function backup_exercise_rubrics ($bf,$preferences,$exercise,$elementno) {
+
+ global $CFG;
+
+ $status = true;
+
+ $exercise_rubrics = get_records_sql("SELECT * from {$CFG->prefix}exercise_rubrics r
+ WHERE r.exerciseid = '$exercise' and r.elementno = '$elementno'
+ ORDER BY r.elementno");
+
+ //If there is exercise_rubrics
+ if ($exercise_rubrics) {
+ //Write start tag
+ $status =fwrite ($bf,start_tag("RUBRICS",6,true));
+ //Iterate over each element
+ foreach ($exercise_rubrics as $wor_rub) {
+ //Start rubric
+ $status =fwrite ($bf,start_tag("RUBRIC",7,true));
+ //Print rubric contents
+ fwrite ($bf,full_tag("RUBRICNO",8,false,$wor_rub->rubricno));
+ fwrite ($bf,full_tag("DESCRIPTION",8,false,$wor_rub->description));
+ //End rubric
+ $status =fwrite ($bf,end_tag("RUBRIC",7,true));
+ }
+ //Write end tag
+ $status =fwrite ($bf,end_tag("RUBRICS",6,true));
+ }
+ return $status;
+ }
+
+ //Backup exercise_submissions contents (executed from exercise_backup_mods)
+ function backup_exercise_submissions ($bf,$preferences,$exercise) {
+
+ global $CFG;
+
+ $status = true;
+
+ $exercise_submissions = get_records("exercise_submissions","exerciseid",$exercise,"id");
+ //If there is submissions
+ if ($exercise_submissions) {
+ //Write start tag
+ $status =fwrite ($bf,start_tag("SUBMISSIONS",4,true));
+ //Iterate over each submission
+ foreach ($exercise_submissions as $wor_sub) {
+ //Start submission
+ $status =fwrite ($bf,start_tag("SUBMISSION",5,true));
+ //Print submission contents
+ fwrite ($bf,full_tag("ID",6,false,$wor_sub->id));
+ fwrite ($bf,full_tag("USERID",6,false,$wor_sub->userid));
+ fwrite ($bf,full_tag("TITLE",6,false,$wor_sub->title));
+ fwrite ($bf,full_tag("TIMECREATED",6,false,$wor_sub->timecreated));
+ fwrite ($bf,full_tag("RESUBMIT",6,false,$wor_sub->resubmit));
+ fwrite ($bf,full_tag("MAILED",6,false,$wor_sub->mailed));
+ fwrite ($bf,full_tag("ISEXERCISE",6,false,$wor_sub->isexercise));
+ //Now we backup exercise assessments
+ $status = backup_exercise_assessments($bf,$preferences,$exercise,$wor_sub->id);
+ //End submission
+ $status =fwrite ($bf,end_tag("SUBMISSION",5,true));
+ }
+ //Write end tag
+ $status =fwrite ($bf,end_tag("SUBMISSIONS",4,true));
+ }
+ return $status;
+ }
+
+ //Backup exercise_assessments contents (executed from backup_exercise_submissions)
+ function backup_exercise_assessments ($bf,$preferences,$exercise,$submission) {
+
+ global $CFG;
+
+ $status = true;
+
+ //NOTE: I think that the exerciseid can go out (submissionid is a good unique fk), but mantain it, as is in db !!
+ $exercise_assessments = get_records_sql("SELECT * from {$CFG->prefix}exercise_assessments a
+ WHERE a.exerciseid = '$exercise' and a.submissionid = '$submission'
+ ORDER BY a.id");
+
+ //If there is exercise_assessments
+ if ($exercise_assessments) {
+ //Write start tag
+ $status =fwrite ($bf,start_tag("ASSESSMENTS",6,true));
+ //Iterate over each assessment
+ foreach ($exercise_assessments as $wor_ass) {
+ //Start assessment
+ $status =fwrite ($bf,start_tag("ASSESSMENT",7,true));
+ //Print assessment contents
+ fwrite ($bf,full_tag("ID",8,false,$wor_ass->id));
+ fwrite ($bf,full_tag("USERID",8,false,$wor_ass->userid));
+ fwrite ($bf,full_tag("TIMECREATED",8,false,$wor_ass->timecreated));
+ fwrite ($bf,full_tag("TIMEGRADED",8,false,$wor_ass->timegraded));
+ fwrite ($bf,full_tag("GRADE",8,false,$wor_ass->grade));
+ fwrite ($bf,full_tag("GRADINGGRADE",8,false,$wor_ass->gradinggrade));
+ fwrite ($bf,full_tag("MAILED",8,false,$wor_ass->mailed));
+ fwrite ($bf,full_tag("GENERALCOMMENT",8,false,$wor_ass->generalcomment));
+ fwrite ($bf,full_tag("TEACHERCOMMENT",8,false,$wor_ass->teachercomment));
+ //Now we backup exercise grades
+ $status = backup_exercise_grades($bf,$preferences,$exercise,$wor_ass->id);
+ //End assessment
+ $status =fwrite ($bf,end_tag("ASSESSMENT",7,true));
+ }
+ //Write end tag
+ $status =fwrite ($bf,end_tag("ASSESSMENTS",6,true));
+ }
+ return $status;
+ }
+
+
+ //Backup exercise_grades contents (executed from backup_exercise_assessments)
+ function backup_exercise_grades ($bf,$preferences,$exercise,$assessmentid) {
+
+ global $CFG;
+
+ $status = true;
+
+ //NOTE: I think that the exerciseid can go out (assessmentid is a good unique fk), but mantain it, as is in db !!
+ $exercise_grades = get_records_sql("SELECT * from {$CFG->prefix}exercise_grades g
+ WHERE g.exerciseid = '$exercise' and g.assessmentid = '$assessmentid'
+ ORDER BY g.elementno");
+
+ //If there is exercise_grades
+ if ($exercise_grades) {
+ //Write start tag
+ $status =fwrite ($bf,start_tag("GRADES",8,true));
+ //Iterate over each grade
+ foreach ($exercise_grades as $wor_gra) {
+ //Start grade
+ $status =fwrite ($bf,start_tag("GRADE",9,true));
+ //Print grade contents
+ fwrite ($bf,full_tag("ELEMENTNO",10,false,$wor_gra->elementno));
+ fwrite ($bf,full_tag("FEEDBACK",10,false,$wor_gra->feedback));
+ fwrite ($bf,full_tag("GRADE_VALUE",10,false,$wor_gra->grade));
+ //End comment
+ $status =fwrite ($bf,end_tag("GRADE",9,true));
+ }
+ //Write end tag
+ $status =fwrite ($bf,end_tag("GRADES",8,true));
+ }
+ return $status;
+ }
+
+
+ //Backup exercise files because we've selected to backup user info
+ //and files are user info's level
+ function backup_exercise_files($bf,$preferences) {
+
+ global $CFG;
+
+ $status = true;
+
+ //First we check to moddata exists and create it as necessary
+ //in temp/backup/$backup_code dir
+ $status = check_and_create_moddata_dir($preferences->backup_unique_code);
+ //Now copy the exercise dir
+ if ($status) {
+ //Only if it exists !! Thanks to Daniel Miksik.
+ if (is_dir($CFG->dataroot."/".$preferences->backup_course."/".$CFG->moddata."/exercise")) {
+ $status = backup_copy_file($CFG->dataroot."/".$preferences->backup_course."/".$CFG->moddata."/exercise",
+ $CFG->dataroot."/temp/backup/".$preferences->backup_unique_code."/moddata/exercise");
+ }
+ }
+
+ return $status;
+
+ }
+
+ //Return an array of info (name,value)
+ function exercise_check_backup_mods($course,$user_data=false,$backup_unique_code) {
+ //First the course data
+ $info[0][0] = get_string("modulenameplural","exercise");
+ if ($ids = exercise_ids ($course)) {
+ $info[0][1] = count($ids);
+ } else {
+ $info[0][1] = 0;
+ }
+
+ //Now, if requested, the user_data
+ if ($user_data) {
+ $info[1][0] = get_string("submissions","exercise");
+ if ($ids = exercise_submission_ids_by_course ($course)) {
+ $info[1][1] = count($ids);
+ } else {
+ $info[1][1] = 0;
+ }
+ }
+ return $info;
+ }
+
+
+
+
+
+
+ // INTERNAL FUNCTIONS. BASED IN THE MOD STRUCTURE
+
+ //Returns an array of exercise id
+ function exercise_ids ($course) {
+
+ global $CFG;
+
+ return get_records_sql ("SELECT w.id, w.course
+ FROM {$CFG->prefix}exercise w
+ WHERE w.course = '$course'");
+ }
+
+ //Returns an array of exercise_submissions id
+ function exercise_submission_ids_by_course ($course) {
+
+ global $CFG;
+
+ return get_records_sql ("SELECT s.id , s.exerciseid
+ FROM {$CFG->prefix}exercise_submissions s,
+ {$CFG->prefix}exercise w
+ WHERE w.course = '$course' AND
+ s.exerciseid = w.id");
+ }
+?>
--- /dev/null
+<?PHP // $Id$
+
+function exercise_upgrade($oldversion) {
+// This function does anything necessary to upgrade
+// older versions to match current functionality
+
+ global $CFG;
+
+
+ return true;
+}
+
+
+?>
+
--- /dev/null
+#
+# Table structure for table `exercise`
+#
+
+CREATE TABLE `prefix_exercise` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `course` int(10) unsigned NOT NULL default '0',
+ `name` varchar(255) NOT NULL default '',
+ `nelements` tinyint(3) unsigned NOT NULL default '1',
+ `phase` tinyint(3) unsigned NOT NULL default '0',
+ `gradingstrategy` tinyint(3) unsigned NOT NULL default '1',
+ `usemaximum` tinyint(3) unsigned NOT NULL default '0',
+ `anonymous` tinyint(3) unsigned NOT NULL default '0',
+ `maxbytes` int(10) unsigned NOT NULL default '100000',
+ `deadline` int(10) unsigned NOT NULL default '0',
+ `grade` tinyint(3) NOT NULL default '0',
+ `timemodified` int(10) unsigned NOT NULL default '0',
+ `teacherweight` tinyint(3) unsigned NOT NULL default '5',
+ `gradingweight` tinyint(3) unsigned NOT NULL default '5',
+ `showleaguetable` tinyint(3) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id`)
+) COMMENT='Defines exercise';
+# --------------------------------------------------------
+
+#
+# Table structure for table `exercise_submissions`
+#
+
+CREATE TABLE `prefix_exercise_submissions` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `exerciseid` int(10) unsigned NOT NULL default '0',
+ `userid` int(10) unsigned NOT NULL default '0',
+ `title` varchar(100) NOT NULL default '',
+ `timecreated` int(10) unsigned NOT NULL default '0',
+ `resubmit` tinyint(3) unsigned NOT NULL default '0',
+ `mailed` tinyint(3) unsigned NOT NULL default '0',
+ `isexercise` tinyint(3) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id`),
+ INDEX `title` (`title`)
+) COMMENT='Info about submitted work from teacher and students';
+# --------------------------------------------------------
+
+#
+# Table structure for table `exercise_assessments`
+#
+
+CREATE TABLE `prefix_exercise_assessments` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `exerciseid` int(10) unsigned NOT NULL default '0',
+ `submissionid` int(10) unsigned NOT NULL default '0',
+ `userid` int(10) unsigned NOT NULL default '0',
+ `timecreated` int(10) unsigned NOT NULL default '0',
+ `timegraded` int(10) unsigned NOT NULL default '0',
+ `grade` float NOT NULL default '0',
+ `gradinggrade` int(3) NOT NULL default '0',
+ `mailed` tinyint(2) unsigned NOT NULL default '0',
+ `generalcomment` text NOT NULL,
+ `teachercomment` text NOT NULL,
+ PRIMARY KEY (`id`)
+ ) COMMENT='Info about assessments by teacher and students';
+# --------------------------------------------------------
+
+#
+# Table structure for table `exercise_elements`
+#
+
+CREATE TABLE `prefix_exercise_elements` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `exerciseid` int(10) unsigned NOT NULL default '0',
+ `elementno` tinyint(3) unsigned NOT NULL default '0',
+ `description` text NOT NULL,
+ `scale` tinyint(3) unsigned NOT NULL default '0',
+ `maxscore` tinyint(3) unsigned NOT NULL default '1',
+ `weight` tinyint(3) unsigned NOT NULL default '11',
+ PRIMARY KEY (`id`)
+) COMMENT='Info about marking scheme of assignment';
+# --------------------------------------------------------
+
+
+#
+# Table structure for table `exercise_rubrics`
+#
+
+CREATE TABLE `prefix_exercise_rubrics` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `exerciseid` int(10) unsigned NOT NULL default '0',
+ `elementno` int(10) unsigned NOT NULL default '0',
+ `rubricno` tinyint(3) unsigned NOT NULL default '0',
+ `description` text NOT NULL,
+ PRIMARY KEY (`id`)
+) COMMENT='Info about the rubrics marking scheme';
+# --------------------------------------------------------
+
+#
+# Table structure for table `exercise_grades`
+#
+
+CREATE TABLE `prefix_exercise_grades` (
+ `id` int(10) unsigned NOT NULL auto_increment,
+ `exerciseid` int(10) unsigned NOT NULL default '0',
+ `assessmentid` int(10) unsigned NOT NULL default '0',
+ `elementno` int(10) unsigned NOT NULL default '0',
+ `feedback` text NOT NULL default '',
+ `grade` tinyint(3) NOT NULL default '0',
+ PRIMARY KEY (`id`)
+) COMMENT='Info about individual grades given to each element';
+# --------------------------------------------------------
+
+
+
+INSERT INTO `prefix_log_display` VALUES ('exercise', 'close', 'exercise', 'name');
+INSERT INTO `prefix_log_display` VALUES ('exercise', 'open', 'exercise', 'name');
+INSERT INTO `prefix_log_display` VALUES ('exercise', 'submit', 'exercise', 'name');
+INSERT INTO `prefix_log_display` VALUES ('exercise', 'view', 'exercise', 'name');
+INSERT INTO `prefix_log_display` VALUES ('exercise', 'update', 'exercise', 'name');
+
--- /dev/null
+<?PHP // $Id$
+
+ require("../../config.php");
+ require("lib.php");
+
+ require_variable($id); // course
+
+ if (! $course = get_record("course", "id", $id)) {
+ error("Course ID is incorrect");
+ }
+
+ require_login($course->id);
+ add_to_log($course->id, "exercise", "view all", "index.php?id=$course->id", "");
+
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+ $strweek = get_string("week");
+ $strtopic = get_string("topic");
+ $strname = get_string("name");
+ $strtitle = get_string("title", "exercise");
+ $strdeadline = get_string("deadline", "exercise");
+ $strsubmitted = get_string("submitted", "assignment");
+
+ print_header("$course->shortname: $strexercises", "$course->fullname", "$navigation $strexercises", "", "", true, "", navmenu($course));
+
+ if (! $exercises = get_all_instances_in_course("exercise", $course)) {
+ notice("There are no exercises", "../../course/view.php?id=$course->id");
+ die;
+ }
+
+ $timenow = time();
+
+ if ($course->format == "weeks") {
+ $table->head = array ($strweek, $strname, $strtitle, $strsubmitted, $strdeadline);
+ $table->align = array ("CENTER", "LEFT", "LEFT","LEFT", "LEFT");
+ } else if ($course->format == "topics") {
+ $table->head = array ($strtopic, $strname, $strtitle, $strsubmitted, $strdeadline);
+ $table->align = array ("CENTER", "LEFT", "LEFT", "LEFT", "LEFT");
+ } else {
+ $table->head = array ($strname, $strsubmitted, $strdeadline);
+ $table->align = array ("LEFT", "LEFT", "LEFT");
+ }
+
+ foreach ($exercises as $exercise) {
+ if ($submissions = exercise_get_user_submissions($exercise, $USER)) {
+ foreach ($submissions as $submission) {
+ if ($submission->timecreated <= $exercise->deadline) {
+ $submitted = userdate($submission->timecreated);
+ }
+ else {
+ $submitted = "<FONT COLOR=red>".userdate($submission->timecreated)."</FONT>";
+ }
+ $due = userdate($exercise->deadline);
+ $link = "<A HREF=\"view.php?id=$exercise->coursemodule\">$exercise->name</A>";
+ $title = $submission->title;
+ if ($course->format == "weeks" or $course->format == "topics") {
+ $table->data[] = array ($exercise->section, $link, $title, $submitted, $due);
+ }
+ else {
+ $table->data[] = array ($link, $submitted, $due);
+ }
+ }
+ }
+ else {
+ $submitted = get_string("no");
+ $title = '';
+ $due = userdate($exercise->deadline);
+ $link = "<A HREF=\"view.php?id=$exercise->coursemodule\">$exercise->name</A>";
+ if ($course->format == "weeks" or $course->format == "topics") {
+ $table->data[] = array ($exercise->section, $link, $title, $submitted, $due);
+ }
+ else {
+ $table->data[] = array ($link, $submitted, $due);
+ }
+ }
+ }
+ echo "<BR>";
+
+ print_table($table);
+
+ print_footer($course);
+?>
--- /dev/null
+<?PHP // $Id: lib.php,v 1.1 23 Aug 2003
+
+include_once("$CFG->dirroot/files/mimetypes.php");
+
+/*** Constants **********************************/
+
+$EXERCISE_TYPE = array (0 => get_string("notgraded", "exercise"),
+ 1 => get_string("accumulative", "exercise"),
+ 2 => get_string("errorbanded", "exercise"),
+ 3 => get_string("criterion", "exercise"),
+ 4 => get_string("rubric", "exercise") );
+
+$EXERCISE_SCALES = array(
+ 0 => array( 'name' => get_string("scaleyes", "exercise"), 'type' => 'radio', 'size' => 2, 'start' => get_string("yes"), 'end' => get_string("no")),
+ 1 => array( 'name' => get_string("scalepresent", "exercise"), 'type' => 'radio', 'size' => 2, 'start' => get_string("present", "exercise"), 'end' => get_string("absent", "exercise")),
+ 2 => array( 'name' => get_string("scalecorrect", "exercise"), 'type' => 'radio', 'size' => 2, 'start' => get_string("correct", "exercise"), 'end' => get_string("incorrect", "exercise")),
+ 3 => array( 'name' => get_string("scalegood3", "exercise"), 'type' => 'radio', 'size' => 3, 'start' => get_string("good", "exercise"), 'end' => get_string("poor", "exercise")),
+ 4 => array( 'name' => get_string("scaleexcellent4", "exercise"), 'type' => 'radio', 'size' => 4, 'start' => get_string("excellent", "exercise"), 'end' => get_string("verypoor", "exercise")),
+ 5 => array( 'name' => get_string("scaleexcellent5", "exercise"), 'type' => 'radio', 'size' => 5, 'start' => get_string("excellent", "exercise"), 'end' => get_string("verypoor", "exercise")),
+ 6 => array( 'name' => get_string("scaleexcellent7", "exercise"), 'type' => 'radio', 'size' => 7, 'start' => get_string("excellent", "exercise"), 'end' => get_string("verypoor", "exercise")),
+ 7 => array( 'name' => get_string("scale10", "exercise"), 'type' => 'selection', 'size' => 10),
+ 8 => array( 'name' => get_string("scale20", "exercise"), 'type' => 'selection', 'size' => 20),
+ 9 => array( 'name' => get_string("scale100", "exercise"), 'type' => 'selection', 'size' => 100));
+
+$EXERCISE_EWEIGHTS = array( 0 => -4.0, 1 => -2.0, 2 => -1.5, 3 => -1.0, 4 => -0.75, 5 => -0.5, 6 => -0.25,
+ 7 => 0.0, 8 => 0.25, 9 => 0.5, 10 => 0.75, 11=> 1.0, 12 => 1.5, 13=> 2.0, 14 => 4.0);
+
+$EXERCISE_FWEIGHTS = array( 0 => 0, 1 => 0.1, 2 => 0.25, 3 => 0.5, 4 => 0.75, 5 => 1.0, 6 => 1.5,
+ 7 => 2.0, 8 => 3.0, 9 => 5.0, 10 => 7.5, 11=> 10.0);
+
+if (!defined("COMMENTSCALE")) {
+ define("COMMENTSCALE", 20);
+ }
+
+/*** Standard Moodle functions ******************
+function exercise_add_instance($exercise)
+function exercise_choose_from_menu ($options, $name, $selected="", $nothing="choose", $script="", $nothingvalue="0", $return=false) {
+function exercise_cron ()
+function exercise_delete_instance($id)
+function exercise_grades($exerciseid)
+function exercise_print_recent_activity(&$logs, $isteacher=false)
+function exercise_update_instance($exercise)
+function exercise_user_outline($course, $user, $mod, $exercise)
+function exercise_user_complete($course, $user, $mod, $exercise)
+**********************************************/
+
+/*******************************************************************/
+function exercise_add_instance($exercise) {
+// Given an object containing all the necessary data,
+// (defined by the form in mod.html) this function
+// will create a new instance and return the id number
+// of the new instance.
+
+ $exercise->timemodified = time();
+
+ $exercise->deadline = make_timestamp($exercise->deadlineyear,
+ $exercise->deadlinemonth, $exercise->deadlineday, $exercise->deadlinehour,
+ $exercise->deadlineminute);
+
+ return insert_record("exercise", $exercise);
+}
+
+
+/*******************************************************************/
+function exercise_choose_from_menu ($options, $name, $selected="", $nothing="choose", $script="", $nothingvalue="0", $return=false) {
+/// Given an array of value, creates a popup menu to be part of a form
+/// $options["value"]["label"]
+
+ if ($nothing == "choose") {
+ $nothing = get_string("choose")."...";
+ }
+
+ if ($script) {
+ $javascript = "onChange=\"$script\"";
+ } else {
+ $javascript = "";
+ }
+
+ $output = "<SELECT NAME=$name $javascript>\n";
+ if ($nothing) {
+ $output .= " <OPTION VALUE=\"$nothingvalue\"\n";
+ if ($nothingvalue == $selected) {
+ $output .= " SELECTED";
+ }
+ $output .= ">$nothing</OPTION>\n";
+ }
+ if (!empty($options)) {
+ foreach ($options as $value => $label) {
+ $output .= " <OPTION VALUE=\"$value\"";
+ if ($value == $selected) {
+ $output .= " SELECTED";
+ }
+ // stop zero label being replaced by array index value
+ // if ($label) {
+ // $output .= ">$label</OPTION>\n";
+ // } else {
+ // $output .= ">$value</OPTION>\n";
+ // }
+ $output .= ">$label</OPTION>\n";
+
+ }
+ }
+ $output .= "</SELECT>\n";
+
+ if ($return) {
+ return $output;
+ } else {
+ echo $output;
+ }
+}
+
+
+/*******************************************************************/
+function exercise_cron () {
+// Function to be run periodically according to the moodle cron
+// Finds all exercise notifications that have yet to be mailed out, and mails them
+
+ global $CFG, $USER;
+
+ $cutofftime = time() - $CFG->maxeditingtime;
+
+ // look for new assessments
+ if ($assessments = exercise_get_unmailed_assessments($cutofftime)) {
+ $timenow = time();
+
+ foreach ($assessments as $assessment) {
+
+ echo "Processing exercise assessment $assessment->id\n";
+ if (! $submission = get_record("exercise_submissions", "id", "$assessment->submissionid")) {
+ echo "Could not find submission $assessment->submissionid\n";
+ continue;
+ }
+ if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
+ echo "Could not find user $submission->userid\n";
+ continue;
+ }
+ if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
+ echo "Could not find user $assessment->userid\n";
+ continue;
+ }
+ if (! $course = get_record("course", "id", "$assessment->course")) {
+ echo "Could not find course $assessment->course\n";
+ continue;
+ }
+ if (! isstudent($course->id, $submissionowner->id) and !isteacher($course->id, $submissionowner->id)) {
+ continue; // Not an active participant
+ }
+ if (! isstudent($course->id, $assessmentowner->id) and !isteacher($course->id, $assessmentowner->id)) {
+ continue; // Not an active participant
+ }
+ if (! $exercise = get_coursemodule_from_instance("exercise", $assessment->exerciseid, $course->id)) {
+ echo "Could not find course module for exercise id $submission->exercise\n";
+ continue;
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+
+ // it's an assessment, tell the submission owner
+ $USER->lang = $submissionowner->lang;
+ $sendto = $submissionowner;
+ // "Your assignment \"$submission->title\" has been assessed by"
+ $msg = get_string("mail1", "exercise", $submission->title)." $assessmentowner->firstname $assessmentowner->lastname.\n";
+ // "The comments and grade can be seen in the exercise assignment '$exercise->name'
+ $msg .= get_string("mail2", "exercise", $exercise->name)."\n\n";
+
+ $postsubject = "$course->shortname: $strexercises: $exercise->name";
+ $posttext = "$course->shortname -> $strexercises -> $exercise->name\n";
+ $posttext .= "---------------------------------------------------------------------\n";
+ $posttext .= $msg;
+ // "You can see it in your exercise assignment"
+ $posttext .= get_string("mail3", "exercise").":\n";
+ $posttext .= " $CFG->wwwroot/mod/exercise/view.php?a=$exercise->id\n";
+ $posttext .= "---------------------------------------------------------------------\n";
+ if ($sendto->mailformat == 1) { // HTML
+ $posthtml = "<P><FONT FACE=sans-serif>".
+ "<A HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A> ->".
+ "<A HREF=\"$CFG->wwwroot/mod/exercise/index.php?id=$course->id\">$strexercises</A> ->".
+ "<A HREF=\"$CFG->wwwroot/mod/exercise/view.php?a=$exercise->id\">$exercise->name</A></FONT></P>";
+ $posthtml .= "<HR><FONT FACE=sans-serif>";
+ $posthtml .= "<P>$msg</P>";
+ $posthtml .= "<P>".get_string("mail3", "exercise").
+ " <A HREF=\"$CFG->wwwroot/mod/exercise/view.php?a=$exercise->id\">$exercise->name</A>.</P></FONT><HR>";
+ } else {
+ $posthtml = "";
+ }
+
+ if (!$teacher = get_teacher($course->id)) {
+ echo "Error: can not find teacher for course $course->id!\n";
+ }
+
+ if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
+ echo "Error: exercise cron: Could not send out mail for id $submission->id to user $sendto->id ($sendto->email)\n";
+ }
+ if (! set_field("exercise_assessments", "mailed", "1", "id", "$assessment->id")) {
+ echo "Could not update the mailed field for id $assessment->id\n";
+ }
+ }
+ }
+
+ // look for new gradings
+ if ($assessments = exercise_get_unmailed_graded_assessments($cutofftime)) {
+ $timenow = time();
+
+ foreach ($assessments as $assessment) {
+
+ echo "Processing exercise assessment $assessment->id (graded)\n";
+
+ if (! $submission = get_record("exercise_submissions", "id", "$assessment->submissionid")) {
+ echo "Could not find submission $assessment->submissionid\n";
+ continue;
+ }
+
+ if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
+ echo "Could not find user $submission->userid\n";
+ continue;
+ }
+
+ if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
+ echo "Could not find user $assessment->userid\n";
+ continue;
+ }
+
+ if (! $course = get_record("course", "id", "$assessment->course")) {
+ echo "Could not find course $assessment->course\n";
+ continue;
+ }
+
+ if (! isstudent($course->id, $submissionowner->id) and !isteacher($course->id, $submissionowner->id)) {
+ continue; // Not an active participant
+ }
+
+ if (! isstudent($course->id, $assessmentowner->id) and !isteacher($course->id, $assessmentowner->id)) {
+ continue; // Not an active participant
+ }
+
+ if (! $exercise = get_coursemodule_from_instance("exercise", $assessment->exerciseid, $course->id)) {
+ echo "Could not find course module for exercise id $submission->exercise\n";
+ continue;
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+
+ // it's a grading tell the assessment owner
+ $USER->lang = $assessmentowner->lang;
+ $sendto = $assessmentowner;
+ // Your assessment of the assignment \"$submission->title\" has by reviewed
+ $msg = get_string("mail6", "exercise", $submission->title).".\n";
+ // The comments given by the $course->teacher can be seen in the exercise Assignment
+ $msg .= get_string("mail7", "exercise", $course->teacher)." '$exercise->name'.\n\n";
+
+ $postsubject = "$course->shortname: $strexercises: $exercise->name";
+ $posttext = "$course->shortname -> $strexercises -> $exercise->name\n";
+ $posttext .= "---------------------------------------------------------------------\n";
+ $posttext .= $msg;
+ // "You can see it in your exercise assignment"
+ $posttext .= get_string("mail3", "exercise").":\n";
+ $posttext .= " $CFG->wwwroot/mod/exercise/view.php?a=$exercise->id\n";
+ $posttext .= "---------------------------------------------------------------------\n";
+ if ($sendto->mailformat == 1) { // HTML
+ $posthtml = "<P><FONT FACE=sans-serif>".
+ "<A HREF=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</A> ->".
+ "<A HREF=\"$CFG->wwwroot/mod/exercise/index.php?id=$course->id\">$strexercises</A> ->".
+ "<A HREF=\"$CFG->wwwroot/mod/exercise/view.php?a=$exercise->id\">$exercise->name</A></FONT></P>";
+ $posthtml .= "<HR><FONT FACE=sans-serif>";
+ $posthtml .= "<P>$msg</P>";
+ $posthtml .= "<P>".get_string("mail3", "exercise").
+ " <A HREF=\"$CFG->wwwroot/mod/exercise/view.php?a=$exercise->id\">$exercise->name</A>.</P></FONT><HR>";
+ } else {
+ $posthtml = "";
+ }
+
+ if (!$teacher = get_teacher($course->id)) {
+ echo "Error: can not find teacher for course $course->id!\n";
+ }
+
+ if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
+ echo "Error: exercise cron: Could not send out mail for id $submission->id to user $sendto->id ($sendto->email)\n";
+ }
+ if (! set_field("exercise_assessments", "mailed", "1", "id", "$assessment->id")) {
+ echo "Could not update the mailed field for id $assessment->id\n";
+ }
+ }
+ }
+ return true;
+}
+
+
+/*******************************************************************/
+function exercise_delete_instance($id) {
+// Given an ID of an instance of this module,
+// this function will permanently delete the instance
+// and any data that depends on it.
+
+ if (! $exercise = get_record("exercise", "id", "$id")) {
+ return false;
+ }
+
+ // delete all the associated records in the exercise tables, start positive...
+ $result = true;
+
+ if (! delete_records("exercise_grades", "exerciseid", "$exercise->id")) {
+ $result = false;
+ }
+
+ if (! delete_records("exercise_rubrics", "exerciseid", "$exercise->id")) {
+ $result = false;
+ }
+
+ if (! delete_records("exercise_elements", "exerciseid", "$exercise->id")) {
+ $result = false;
+ }
+
+ if (! delete_records("exercise_assessments", "exerciseid", "$exercise->id")) {
+ $result = false;
+ }
+
+ if (! delete_records("exercise_submissions", "exerciseid", "$exercise->id")) {
+ $result = false;
+ }
+
+ if (! delete_records("exercise", "id", "$exercise->id")) {
+ $result = false;
+ }
+
+ return $result;
+}
+
+
+/*******************************************************************/
+function exercise_grades($exerciseid) {
+/// Must return an array of grades, indexed by user, and a max grade.
+global $EXERCISE_FWEIGHTS;
+
+ if (!$exercise = get_record("exercise", "id", $exerciseid)) {
+ error("Exercise record not found");
+ }
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+
+ // calculate scaling factor
+ $scaling = $exercise->grade / (100.0 * ($EXERCISE_FWEIGHTS[$exercise->gradingweight] +
+ $EXERCISE_FWEIGHTS[$exercise->teacherweight]));
+ // how to handle multiple submissions?
+ if ($exercise->usemaximum) {
+ // first get the teacher's grade for the best submission
+ if ($bestgrades = exercise_get_best_submission_grades($exercise)) {
+ foreach ($bestgrades as $bestgrade) {
+ $return->grades[$bestgrade->userid] = $bestgrade->grade *
+ $EXERCISE_FWEIGHTS[$exercise->teacherweight] * $scaling;
+ }
+ }
+ }
+ else { // use mean values
+ if ($meangrades = exercise_get_mean_submission_grades($exercise)) {
+ foreach ($meangrades as $meangrade) {
+ $return->grades[$meangrade->userid] = $meangrade->grade *
+ $EXERCISE_FWEIGHTS[$exercise->teacherweight] * $scaling;
+ }
+ }
+ }
+ // now get the users grading grades
+ if ($assessments = exercise_get_teacher_submission_assessments($exercise)) {
+ foreach ($assessments as $assessment) {
+ // add the grading grade if the student's work has been assessed
+ if (isset($return->grades[$assessment->userid])) {
+ $return->grades[$assessment->userid] += $assessment->gradinggrade *
+ $EXERCISE_FWEIGHTS[$exercise->gradingweight] * $scaling * 100.0 / COMMENTSCALE;
+ }
+ }
+ }
+ $return->maxgrade = get_field("exercise", "grade", "id", "$exerciseid");
+ return $return;
+}
+
+
+/*******************************************************************/
+function exercise_print_recent_activity($course, $isteacher, $timestart) {
+ global $CFG;
+
+ // have a look for new submissions (only show to teachers)
+ $submitcontent = false;
+ if ($isteacher) {
+ if ($logs = exercise_get_submit_logs($course, $timestart)) {
+ // got some, see if any belong to a visible module
+ foreach ($logs as $log) {
+ // Create a temp valid module structure (only need courseid, moduleid)
+ $tempmod->course = $course->id;
+ $tempmod->id = $log->exerciseid;
+ //Obtain the visible property from the instance
+ if (instance_is_visible("exercise",$tempmod)) {
+ $submitcontent = true;
+ break;
+ }
+ }
+ // if we got some "live" ones then output them
+ if ($submitcontent) {
+ $strftimerecent = get_string("strftimerecent");
+ print_headline(get_string("exercisesubmissions", "exercise").":");
+ foreach ($logs as $log) {
+ //Create a temp valid module structure (only need courseid, moduleid)
+ $tempmod->course = $course->id;
+ $tempmod->id = $log->exerciseid;
+ //Obtain the visible property from the instance
+ if (instance_is_visible("exercise",$tempmod)) {
+ $date = userdate($log->time, $strftimerecent);
+ echo "<p><font size=1>$date - $log->firstname $log->lastname<br />";
+ echo "\"<a href=\"$CFG->wwwroot/mod/exercise/$log->url\">";
+ echo "$log->name";
+ echo "</a>\"</font></p>";
+ }
+ }
+ }
+ }
+ }
+
+ // have a look for new assessment gradings for this user
+ $gradecontent = false;
+ if ($logs = exercise_get_grade_logs($course, $timestart)) {
+ // got some, see if any belong to a visible module
+ foreach ($logs as $log) {
+ // Create a temp valid module structure (only need courseid, moduleid)
+ $tempmod->course = $course->id;
+ $tempmod->id = $log->exerciseid;
+ //Obtain the visible property from the instance
+ if (instance_is_visible("exercise",$tempmod)) {
+ $gradecontent = true;
+ break;
+ }
+ }
+ // if we got some "live" ones then output them
+ if ($gradecontent) {
+ $strftimerecent = get_string("strftimerecent");
+ print_headline(get_string("exercisefeedback", "exercise").":");
+ foreach ($logs as $log) {
+ //Create a temp valid module structure (only need courseid, moduleid)
+ $tempmod->course = $course->id;
+ $tempmod->id = $log->exerciseid;
+ //Obtain the visible property from the instance
+ if (instance_is_visible("exercise",$tempmod)) {
+ $date = userdate($log->time, $strftimerecent);
+ echo "<p><font size=1>$date - $log->firstname $log->lastname<br />";
+ echo "\"<a href=\"$CFG->wwwroot/mod/exercise/$log->url\">";
+ echo "$log->name";
+ echo "</a>\"</font></p>";
+ }
+ }
+ }
+ }
+
+ // have a look for new assessments for this user
+ $assesscontent = false;
+ if (!$isteacher) { // teachers only need to see submissions
+ if ($logs = exercise_get_assess_logs($course, $timestart)) {
+ // got some, see if any belong to a visible module
+ foreach ($logs as $log) {
+ // Create a temp valid module structure (only need courseid, moduleid)
+ $tempmod->course = $course->id;
+ $tempmod->id = $log->exerciseid;
+ //Obtain the visible property from the instance
+ if (instance_is_visible("exercise",$tempmod)) {
+ $assesscontent = true;
+ break;
+ }
+ }
+ // if we got some "live" ones then output them
+ if ($assesscontent) {
+ $strftimerecent = get_string("strftimerecent");
+ print_headline(get_string("exerciseassessments", "exercise").":");
+ foreach ($logs as $log) {
+ //Create a temp valid module structure (only need courseid, moduleid)
+ $tempmod->course = $course->id;
+ $tempmod->id = $log->exerciseid;
+ //Obtain the visible property from the instance
+ if (instance_is_visible("exercise",$tempmod)) {
+ $date = userdate($log->time, $strftimerecent);
+ echo "<p><font size=1>$date - $log->firstname $log->lastname<br />";
+ echo "\"<a href=\"$CFG->wwwroot/mod/exercise/$log->url\">";
+ echo "$log->name";
+ echo "</a>\"</font></p>";
+ }
+ }
+ }
+ }
+ }
+ return $submitcontent or $gradecontent or $assesscontent;
+}
+
+
+/*******************************************************************/
+function exercise_update_instance($exercise) {
+// Given an object containing all the necessary data,
+// (defined by the form in mod.html) this function
+// will update an existing instance with new data.
+
+ $exercise->timemodified = time();
+
+ $exercise->deadline = make_timestamp($exercise->deadlineyear,
+ $exercise->deadlinemonth, $exercise->deadlineday, $exercise->deadlinehour,
+ $exercise->deadlineminute);
+
+ $exercise->id = $exercise->instance;
+
+ return update_record("exercise", $exercise);
+}
+
+
+/*******************************************************************/
+function exercise_user_complete($course, $user, $mod, $exercise) {
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ print_simple_box_start();
+ $table->head = array (get_string("submission", "exercise"), get_string("submitted", "exercise"),
+ get_string("assessed", "exercise"), get_string("grade"));
+ $table->width = "100%";
+ $table->align = array ("left", "left", "left", "center");
+ $table->size = array ("*", "*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ foreach ($submissions as $submission) {
+ if ($assessments = exercise_get_assessments($submission)) {
+ // should only be one but we'll loop anyway
+ foreach ($assessments as $assessment) {
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), userdate($submission->timecreated),
+ userdate($assessment->timecreated), $assessment->grade * $exercise->grade / 100.0);
+ }
+ }
+ }
+ print_table($table);
+ print_simple_box_end();
+ } else {
+ print_string("nosubmissions", "exercise");
+ }
+}
+
+
+/*******************************************************************/
+function exercise_user_outline($course, $user, $mod, $exercise) {
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ $result->info = count($submissions)." ".get_string("submissions", "exercise");
+ foreach ($submissions as $submission) { // the first one is the most recent one
+ $result->time = $submission->timecreated;
+ break;
+ }
+ return $result;
+ }
+ return NULL;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+
+/*** Functions for the exercise module ******
+
+function exercise_copy_assessment($assessment, $submission, $withfeedback = false) {
+function exercise_count_all_submissions_for_assessment($exercise, $user) {
+function exercise_count_assessments($submission) {
+function exercise_count_student_submissions($exercise) {
+function exercise_count_teacher_assessments($exercise, $user) {
+function exercise_count_teacher_submissions($exercise) {
+function exercise_count_teacher_submissions_for_assessment($exercise, $user) {
+function exercise_count_unassessed_student_submissions($exercise) {
+function exercise_count_ungraded_assessments_student($exercise) {
+function exercise_count_ungraded_assessments_teacher($exercise) {
+function exercise_count_user_assessments($exercise, $user, $type = "all") { $type is all, student or teacher
+function exercise_count_user_assessments_done($exercise,$user) {
+function exercise_count_user_submissions($exercise, $user) {
+
+function exercise_delete_submitted_files($exercise, $submission) {
+function exercise_delete_user_files($exercise, $user, $exception) {
+
+function exercise_file_area($exercise, $submission) {
+function exercise_file_area_name($exercise, $submission) {
+
+function exercise_get_assess_logs($course, $timestart) {
+function exercise_get_assessments($submission) {
+function exercise_get_best_submission_grades($exercise) {
+function exercise_get_grade_logs($course, $timestart) {
+function exercise_get_mean_submission_grades($exercise) {
+function exercise_get_student_submission($exercise, $user) {
+function exercise_get_student_submissions($exercise) {
+function exercise_get_submission_assessment($submission, $user) {
+function exercise_get_submit_logs($course, $timestart) {
+function exercise_get_teacher_submission_assessments($exercise) {
+function exercise_get_teacher_submissions($exercise) {
+function exercise_get_ungraded_assessments($exercise) {
+function exercise_get_unmailed_assessments($cutofftime) {
+function exercise_get_unmailed_graded_assessments($cutofftime) {
+function exercise_get_user_assessments($exercise, $user) {
+function exercise_get_user_submissions($exercise, $user) {
+
+function exercise_list_all_ungraded_assessments($exercise) {
+function exercise_list_submissions_for_admin($exercise, $order) {
+function exercise_list_teacher_assessments($exercise, $user) {
+function exercise_list_teacher_submissions($exercise, $user, $reassess) {
+function exercise_list_unassessed_student_submissions($exercise, $user) {
+function exercise_list_unassessed_teacher_submissions($exercise, $user) {
+function exercise_list_ungraded_assessments($exercise, $stype) {
+function exercise_list_user_submissions($exercise, $user) {
+
+
+function exercise_print_assessment_form($exercise, $assessment, $allowchanges, $returnto)
+function exercise_print_assessments_by_user_for_admin($exercise, $user) {
+function exercise_print_assessments_for_admin($exercise, $submission) {
+function exercise_print_assignment_info($exercise) {
+function exercise_print_difference($time) {
+function exercise_print_dual_assessment_form($exercise, $assessment, $submission, $returnto)
+function exercise_print_feedback($course, $submission) {
+function exercise_print_league_table($exercise) {
+function exercise_print_submission_assessments($exercise, $submission, $type) {
+function exercise_print_submission_title($exercise, $user) {
+function exercise_print_tabbed_table($table) {
+function exercise_print_time_to_deadline($time) {
+function exercise_print_upload_form($exercise) {
+function exercise_print_user_assessments($exercise, $user) {
+
+function exercise_test_for_resubmission($exercise, $user) {
+function exercise_test_user_assessments($exercise, $user) {
+***************************************/
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_copy_assessment($assessment, $submission, $withfeedback = false) {
+ // adds a copy of the given assessment for the submission specified to the exercise_assessemnts table.
+ // The grades and optionally the comments are added to the exercise_grades table. Returns the new
+ // assessment object
+ global $USER;
+
+ $yearfromnow = time() + 365 * 86400;
+ $newassessment->exerciseid = $assessment->exerciseid;
+ $newassessment->submissionid = $submission->id;
+ $newassessment->userid = $USER->id;
+ $newassessment->timecreated = $yearfromnow;
+ $newassessment->timegraded = 0;
+ $newassessment->grade = $assessment->grade;
+ if ($withfeedback) {
+ $newassessment->generalcomment = addslashes($assessment->generalcomment);
+ $newassessment->teachercomment = addslashes($assessment->teachercomment);
+ }
+ if (!$newassessment->id = insert_record("exercise_assessments", $newassessment)) {
+ error("Copy Assessment: Could not insert exercise assessment!");
+ }
+
+ if ($grades = get_records("exercise_grades", "assessmentid", $assessment->id)) {
+ foreach ($grades as $grade) {
+
+ if (!$withfeedback) {
+ $grade->feedback = '';
+ }
+ else {
+ $grade->feedback = addslashes($grade->feedback);
+ // $grade->feedback = $grade->feedback;
+ }
+ $grade->assessmentid = $newassessment->id;
+ if (!$grade->id = insert_record("exercise_grades", $grade)) {
+ error("Copy Assessment: Could not insert exercise grade!");
+ }
+ }
+ }
+ if ($withfeedback) {
+ // remove the slashes from comments as the new assessment record is used
+ // in assessments and in lib
+ $newassessment->generalcomment = stripslashes($assessment->generalcomment);
+ $newassessment->teachercomment = stripslashes($assessment->teachercomment);
+ }
+
+ return $newassessment;
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_all_submissions_for_assessment($exercise, $user) {
+ // looks at all submissions and deducts the number which has been assessed by this user
+ $n = 0;
+ if ($submissions = get_records_select("exercise_submissions", "exerciseid = $exercise->id AND timecreated > 0")) {
+ $n =count($submissions);
+ foreach ($submissions as $submission) {
+ $n -= count_records("exercise_assessments", "submissionid", $submission->id, "userid", $user->id);
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_assessments($submission) {
+ // Return the (cold) assessments for this submission,
+ global $CFG;
+
+ $timenow = time();
+ return count_records_select("exercise_assessments", "submissionid = $submission->id AND
+ timecreated < ($timenow - $CFG->maxeditingtime");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_student_submissions($exercise) {
+ global $CFG;
+
+ return count_records_sql("SELECT count(*) FROM {$CFG->prefix}exercise_submissions s, {$CFG->prefix}user_students u
+ WHERE u.course = $exercise->course
+ AND s.userid = u.userid
+ AND s.exerciseid = $exercise->id
+ AND timecreated > 0");
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_teacher_assessments($exercise, $user) {
+ // returns the number of assessments made by teachers on user's submissions
+
+ $n = 0;
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ foreach ($submissions as $submission) {
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ // count only teacher assessments
+ if (isteacher($exercise->course, $assessment->userid)) {
+ $n++;
+ }
+ }
+ }
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_teacher_submissions($exercise) {
+
+ return count_records("exercise_submissions", "isexercise", 1, "exerciseid", $exercise->id);
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_teacher_submissions_for_assessment($exercise, $user) {
+
+ $n = 0;
+ if ($submissions = exercise_get_teacher_submissions($exercise)) {
+ $n =count($submissions);
+ foreach ($submissions as $submission) {
+ $n -= count_records("exercise_assessments", "submissionid", $submission->id, "userid", $user->id);
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_unassessed_student_submissions($exercise) {
+// returns the number of students submissions which have not been assessed by a teacher
+ global $CFG;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ $timenow = time();
+ $n = 0;
+ if ($submissions = exercise_get_student_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ // only look at "cold" submissions
+ if ($submission->timecreated < $timenow - $CFG->maxeditingtime) {
+ $teacherassessed = false;
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ // exercise_get_assessments only returns "cold" assessments, look for one made by a teacher
+ if (isteacher($course->id, $assessment->userid)) {
+ $teacherassessed = true;
+ break; // no need to look further
+ }
+ }
+ }
+ if (!$teacherassessed) {
+ $n++;
+ }
+ }
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_ungraded_assessments_student($exercise) {
+ // function returns the number of ungraded assessments by students of STUDENT submissions
+ $n = 0;
+ if ($submissions = exercise_get_student_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ if ($assessment->timegraded == 0) {
+ // ignore teacher assessments
+ if (!isteacher($exercise->course, $assessment->userid)) {
+ $n++;
+ }
+ }
+ }
+ }
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_ungraded_assessments_teacher($exercise) {
+ // function returns the number of ungraded assessments by students of TEACHER submissions
+ global $CFG;
+
+ $timenow = time();
+ $n = 0;
+ if ($submissions = exercise_get_teacher_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ if ($assessment->timegraded == 0) {
+ // ignore teacher assessments
+ if (!isteacher($exercise->course, $assessment->userid)) {
+ // must have created a little time ago
+ if (($timenow - $assessment->timecreated) > $CFG->maxeditingtime) {
+ $n++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_user_assessments($exercise, $user, $stype = "all") {
+ // returns the number of assessments allocated/made by a user, all of them, or just those for the student or teacher submissions
+ // the student's self assessments are included in the count
+ // the maxeditingtime is NOT taken into account here also allocated assessments which have not yet
+ // been done are counted as well
+
+ $n = 0;
+ if ($assessments = exercise_get_user_assessments($exercise, $user)) {
+ foreach ($assessments as $assessment) {
+ switch ($stype) {
+ case "all" :
+ $n++;
+ break;
+ case "student" :
+ $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
+ if (isstudent($exercise->course, $submission->userid)) {
+ $n++;
+ }
+ break;
+ case "teacher" :
+ $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
+ if (isteacher($exercise->course, $submission->userid)) {
+ $n++;
+ }
+ break;
+ }
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_user_assessments_done($exercise, $user) {
+ // returns the number of assessments actually done by a user
+ // the student's self assessments are included in the count
+ // the maxeditingtime is NOT taken into account here
+
+ $n = 0;
+ $timenow = time();
+ if ($assessments = exercise_get_user_assessments($exercise, $user)) {
+ foreach ($assessments as $assessment) {
+ if ($assessment->timecreated < $timenow) {
+ $n++;
+ }
+ }
+ }
+ return $n;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_count_user_submissions($exercise, $user) {
+ // returns the number of submissions make by this user
+ return count_records("exercise_submissions", "exerciseid", $exercise->id, "userid", $user->id);
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_delete_submitted_files($exercise, $submission) {
+// Deletes the files in the exercise area for this submission
+
+ if ($basedir = exercise_file_area($exercise, $submission)) {
+ if ($files = get_directory_list($basedir)) {
+ foreach ($files as $file) {
+ if (unlink("$basedir/$file")) {
+ notify("Existing file '$file' has been deleted!");
+ }
+ else {
+ notify("Attempt to delete file $basedir/$file has failed!");
+ }
+ }
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_delete_user_files($exercise, $user, $exception) {
+// Deletes all the user files in the exercise area for a user
+// EXCEPT for any file named $exception
+
+ if (!$submissions = exercise_get_submissions($exercise, $user)) {
+ notify("No submissions!");
+ return;
+ }
+ foreach ($submissions as $submission) {
+ if ($basedir = exercise_file_area($exercise, $submission)) {
+ if ($files = get_directory_list($basedir)) {
+ foreach ($files as $file) {
+ if ($file != $exception) {
+ unlink("$basedir/$file");
+ notify("Existing file '$file' has been deleted!");
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_file_area($exercise, $submission) {
+ return make_upload_directory( exercise_file_area_name($exercise, $submission) );
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_file_area_name($exercise, $submission) {
+// Creates a directory file name, suitable for make_upload_directory()
+ global $CFG;
+
+ return "$exercise->course/$CFG->moddata/exercise/$submission->id";
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_assess_logs($course, $timestart) {
+ // get the "assess" entries for this user and add the first and last names...
+ global $CFG, $USER;
+
+ $timethen = time() - $CFG->maxeditingtime;
+ return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.exerciseid, e.name
+ FROM {$CFG->prefix}log l,
+ {$CFG->prefix}exercise e,
+ {$CFG->prefix}exercise_submissions s,
+ {$CFG->prefix}exercise_assessments a,
+ {$CFG->prefix}user u
+ WHERE l.time > $timestart AND l.time < $timethen
+ AND l.course = $course->id AND l.module = 'exercise' AND l.action = 'assess'
+ AND a.id = l.info AND s.id = a.submissionid AND s.userid = $USER->id
+ AND u.id = a.userid AND e.id = a.exerciseid");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_assessments($submission) {
+ // Return all assessments for this submission provided they are after the editing time, ordered oldest first, newest last
+ global $CFG;
+
+ $timenow = time();
+ return get_records_select("exercise_assessments", "(submissionid = $submission->id) AND
+ (timecreated < $timenow - $CFG->maxeditingtime)", "timecreated DESC");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_best_submission_grades($exercise) {
+// Returns the grades of students' best submissions
+ global $CFG;
+
+ return get_records_sql("SELECT DISTINCT MAX(a.grade) grade, u.userid FROM {$CFG->prefix}exercise_submissions s,
+ {$CFG->prefix}exercise_assessments a, {$CFG->prefix}user_students u
+ WHERE u.course = $exercise->course
+ AND s.userid = u.userid
+ AND s.exerciseid = $exercise->id
+ AND a.submissionid = s.id
+ GROUP BY u.userid");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_grade_logs($course, $timestart) {
+ // get the "grade" entries for this user and add the first and last names...
+ global $CFG, $USER;
+
+ $timethen = time() - $CFG->maxeditingtime;
+ return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.exerciseid, e.name
+ FROM {$CFG->prefix}log l,
+ {$CFG->prefix}exercise e,
+ {$CFG->prefix}exercise_submissions s,
+ {$CFG->prefix}exercise_assessments a,
+ {$CFG->prefix}user u
+ WHERE l.time > $timestart AND l.time < $timethen
+ AND l.course = $course->id AND l.module = 'exercise' AND l.action = 'grade'
+ AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
+ AND u.id = s.userid AND e.id = a.exerciseid");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_mean_submission_grades($exercise) {
+// Returns the mean grades of students' submissions
+ global $CFG;
+
+ return get_records_sql("SELECT DISTINCT AVG(a.grade) grade, u.userid FROM {$CFG->prefix}exercise_submissions s,
+ {$CFG->prefix}exercise_assessments a, {$CFG->prefix}user_students u
+ WHERE u.course = $exercise->course
+ AND s.userid = u.userid
+ AND s.exerciseid = $exercise->id
+ AND a.submissionid = s.id
+ GROUP BY u.userid");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_student_submission($exercise, $user) {
+// Return a submission for a particular user
+ global $CFG;
+
+ $submission = get_record("exercise_submissions", "exerciseid", $exercise->id, "userid", $user->id);
+ if (!empty($submission->timecreated)) {
+ return $submission;
+ }
+ return NULL;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_student_submissions($exercise, $order = "title") {
+// Return all ENROLLED student submissions
+ global $CFG;
+
+ if ($order == "grade") {
+ // allow for multiple assessments of submissions (coming from different teachers)
+ return get_records_sql("SELECT s.*, AVG(a.grade) grade FROM {$CFG->prefix}exercise_submissions s,
+ {$CFG->prefix}user_students u, {$CFG->prefix}exercise_assessments a
+ WHERE u.course = $exercise->course
+ AND s.userid = u.userid
+ AND s.exerciseid = $exercise->id
+ AND a.submissionid = s.id
+ GROUP BY s.id
+ ORDER BY a.grade DESC");
+ }
+
+ if ($order == "title") {
+ $order = "s.title";
+ }
+ if ($order == "name") {
+ $order = "a.firstname, a.lastname";
+ }
+ return get_records_sql("SELECT s.* FROM {$CFG->prefix}exercise_submissions s, {$CFG->prefix}user_students u,
+ {$CFG->prefix}user a
+ WHERE u.course = $exercise->course
+ AND s.userid = u.userid
+ AND a.id = u.userid
+ AND s.exerciseid = $exercise->id
+ AND s.timecreated > 0
+ ORDER BY $order, timecreated DESC");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_submission_assessment($submission, $user) {
+ // Return the user's assessment for this submission
+ return get_record("exercise_assessments", "submissionid", $submission->id, "userid", $user->id);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_submit_logs($course, $timestart) {
+ // get the "submit" entries and add the first and last names...
+ global $CFG, $USER;
+
+ $timethen = time() - $CFG->maxeditingtime;
+ return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, l.info exerciseid, e.name
+ FROM {$CFG->prefix}log l,
+ {$CFG->prefix}exercise e,
+ {$CFG->prefix}user u
+ WHERE l.time > $timestart AND l.time < $timethen
+ AND l.course = $course->id AND l.module = 'exercise'
+ AND l.action = 'submit'
+ AND e.id = l.info
+ AND u.id = l.userid");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_teacher_submission_assessments($exercise) {
+// Return all assessments on the teacher submissions, order by youngest first, oldest last
+ global $CFG;
+
+ return get_records_sql("SELECT a.* FROM {$CFG->prefix}exercise_submissions s, {$CFG->prefix}exercise_assessments a
+ WHERE s.isexercise = 1
+ AND s.exerciseid = $exercise->id
+ AND a.submissionid = s.id
+ ORDER BY a.timecreated DESC");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_teacher_submissions($exercise) {
+// Return all teacher submissions, ordered by title
+ global $CFG;
+
+ return get_records_sql("SELECT s.* FROM {$CFG->prefix}exercise_submissions s
+ WHERE s.isexercise = 1
+ AND s.exerciseid = $exercise->id
+ ORDER BY s.title");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_ungraded_assessments($exercise) {
+ global $CFG;
+ // Return all assessments which have not been graded or just graded
+ $cutofftime =time() - $CFG->maxeditingtime;
+ return get_records_select("exercise_assessments", "exerciseid = $exercise->id AND (timegraded = 0 OR
+ timegraded > $cutofftime)", "timecreated");
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_ungraded_assessments_student($exercise) {
+ global $CFG;
+ // Return all assessments which have not been graded or just graded of student's submissions
+
+ $cutofftime =time() - $CFG->maxeditingtime;
+ return get_records_sql("SELECT a.* FROM {$CFG->prefix}exercise_submissions s, {$CFG->prefix}user_students u,
+ {$CFG->prefix}exercise_assessments a
+ WHERE u.course = $exercise->course
+ AND s.userid = u.userid
+ AND s.exerciseid = $exercise->id
+ AND a.submissionid = s.id
+ AND (a.timegraded = 0 OR a.timegraded > $cutofftime)
+ AND a.timecreated < $cutofftime
+ ORDER BY a.timecreated ASC");
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_ungraded_assessments_teacher($exercise) {
+ global $CFG;
+ // Return all assessments which have not been graded or just graded of teacher's submissions
+
+ $cutofftime =time() - $CFG->maxeditingtime;
+ return get_records_sql("SELECT a.* FROM {$CFG->prefix}exercise_submissions s, {$CFG->prefix}exercise_assessments a
+ WHERE s.isexercise = 1
+ AND s.exerciseid = $exercise->id
+ AND a.submissionid = s.id
+ AND (a.timegraded = 0 OR a.timegraded > $cutofftime)
+ AND a.timecreated < $cutofftime
+ ORDER BY a.timecreated ASC");
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_unmailed_assessments($cutofftime) {
+ /// Return list of (ungraded) assessments that have not been mailed out
+ global $CFG;
+ return get_records_sql("SELECT a.*, g.course, g.name
+ FROM {$CFG->prefix}exercise_assessments a, {$CFG->prefix}exercise g
+ WHERE a.mailed = 0
+ AND a.timegraded = 0
+ AND a.timecreated < $cutofftime
+ AND g.id = a.exerciseid");
+}
+
+
+function exercise_get_unmailed_graded_assessments($cutofftime) {
+ /// Return list of graded assessments that have not been mailed out
+ global $CFG;
+ return get_records_sql("SELECT a.*, g.course, g.name
+ FROM {$CFG->prefix}exercise_assessments a, {$CFG->prefix}exercise g
+ WHERE a.mailed = 0
+ AND a.timegraded < $cutofftime
+ AND a.timegraded > 0
+ AND g.id = a.exerciseid");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_user_assessments($exercise, $user) {
+ // Return all the user's assessments, newest first, oldest last
+ return get_records_select("exercise_assessments", "exerciseid = $exercise->id AND userid = $user->id",
+ "timecreated DESC");
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_get_user_submissions($exercise, $user) {
+ // return submission of user newest first, oldest last
+ // teachers submit "exercises"
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (isteacher($course->id, $user->id)) {
+ return get_records_select("exercise_submissions ",
+ "exerciseid = $exercise->id AND isexercise = 1", "timecreated DESC" );
+ }
+ return get_records_select("exercise_submissions ",
+ "exerciseid = $exercise->id AND userid = $user->id", "timecreated DESC" );
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_all_ungraded_assessments($exercise) {
+ // lists all the assessments for comment by teacher
+ global $CFG;
+
+ $table->head = array (get_string("title", "exercise"), get_string("timeassessed", "exercise"), get_string("action", "exercise"));
+ $table->align = array ("LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+ $timenow = time();
+
+ if ($assessments = exercise_get_ungraded_assessments($exercise)) {
+ foreach ($assessments as $assessment) {
+ if (!isteacher($exercise->course, $assessment->userid)) {
+ if (($timenow - $assessment->timegraded) < $CFG->maxeditingtime) {
+ $action = "<A HREF=\"assessments.php?action=gradeassessment&a=$exercise->id&aid=$assessment->id\">".
+ get_string("edit", "exercise")."</A>";
+ }
+ else {
+ $action = "<A HREF=\"assessments.php?action=gradeassessment&a=$exercise->id&aid=$assessment->id\">".
+ get_string("gradeassessment", "exercise")."</A>";
+ }
+ $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ userdate($assessment->timecreated), $action);
+ }
+ }
+ if (isset($table->data)) {
+ print_table($table);
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_submissions_for_admin($exercise, $order) {
+ // list the teacher sublmissions first
+ global $CFG, $EXERCISE_FWEIGHTS, $THEME, $USER;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ exercise_print_assignment_info($exercise);
+
+ ?>
+ <form name="weightsform" method="post" action="submissions.php">
+ <INPUT TYPE="hidden" NAME="id" VALUE="<?PHP echo $cm->id ?>">
+ <input type="hidden" name="action" value="saveweights">
+ <CENTER>
+ <?PHP
+
+ // get the final weights from the database
+ $teacherweight = get_field("exercise","teacherweight", "id", $exercise->id);
+ $gradingweight = get_field("exercise","gradingweight", "id", $exercise->id);
+
+ // now show the weights used in the grades
+ print_heading_with_help(get_string("administration"), "administration", "exercise");
+ echo "<TABLE WIDTH=\"50%\" BORDER=\"1\">\n";
+ echo "<TR><td COLSPAN=\"2\" bgcolor=\"$THEME->cellheading2\"><CENTER><B>".
+ get_string("weightsusedforoverallgrade", "exercise")."</B></CENTER></TD></TR>\n";
+ echo "<TR><TD ALIGN=\"right\">".get_string("weightforgradingofassessments", "exercise").":</TD>\n";
+ echo "<TD>";
+ exercise_choose_from_menu($EXERCISE_FWEIGHTS, "gradingweight", $gradingweight, "");
+ echo "</TD></TR>\n";
+ echo "<tr><td align=\"right\">".get_string("weightforteacherassessments", "exercise", $course->teacher).":</td>\n";
+ echo "<TD>";
+ exercise_choose_from_menu($EXERCISE_FWEIGHTS, "teacherweight", $teacherweight, "");
+ echo "</TD></TR>\n";
+ echo "</TABLE>\n";
+ echo "<INPUT TYPE=submit VALUE=\"".get_string("saveweights", "exercise")."\">\n";
+ echo "</CENTER>";
+ echo "</FORM>\n";
+
+ // list any teacher submissions
+ $table->head = array (get_string("title", "exercise"), get_string("submitted", "exercise"), get_string("action", "exercise"));
+ $table->align = array ("left", "left", "left");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ if ($submissions = exercise_get_teacher_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ $action = "<a href=\"submissions.php?action=adminamendtitle&id=$cm->id&sid=$submission->id\">".
+ get_string("amendtitle", "exercise")."</a>";
+ $action .= " | <a href=\"submissions.php?action=adminconfirmdelete&id=$cm->id&sid=$submission->id\">".
+ get_string("delete", "exercise")."</a>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ userdate($submission->timecreated), $action);
+ }
+ print_heading(get_string("studentsubmissions", "exercise", $course->teacher), "center");
+ print_table($table);
+ }
+
+ // list student assessments
+ // Get all the students...
+ if ($users = get_course_students($course->id, "u.firstname, u.lastname")) {
+ $timenow = time();
+ unset($table);
+ $table->head = array(get_string("name"), get_string("title", "exercise"), get_string("action", "exercise"));
+ $table->align = array ("left", "left", "left");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+ foreach ($users as $user) {
+ if ($assessments = exercise_get_user_assessments($exercise, $user)) {
+ $title ='';
+ foreach ($assessments as $assessment) {
+ if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
+ error("exercise_list_submissions_for_admin: Submission record not found!");
+ }
+ $title .= $submission->title;
+ // test for allocated assesments which have not been done
+ if ($assessment->timecreated < $timenow) {
+ $title .= " {".number_format($assessment->grade * $exercise->grade / 100.0, 0)."%";
+ }
+ else { // assessment record created but user has not yet assessed this submission
+ $title .= " {-";
+ }
+ if ($assessment->timegraded) {
+ $title .= "/".number_format($assessment->gradinggrade * $exercise->grade / COMMENTSCALE, 0)."%";
+ }
+ $title .= "} ";
+ if ($realassessments = exercise_count_user_assessments_done($exercise, $user)) {
+ $action = "<a href=\"assessments.php?action=adminlistbystudent&id=$cm->id&userid=$user->id\">".
+ get_string("view", "exercise")." ($realassessments)</a>";
+ }
+ else {
+ $action ="";
+ }
+ }
+ $table->data[] = array("$user->firstname $user->lastname", $title, $action);
+ }
+ }
+ if (isset($table->data)) {
+ print_heading(get_string("studentassessments", "exercise", $course->student));
+ print_table($table);
+ echo "<p align=\"center\">".get_string("noteonstudentassessments", "exercise")."</p>\n";
+ }
+ }
+
+ // now the sudent submissions
+ unset($table);
+ switch ($order) {
+ case "title" :
+ $table->head = array("<a href=\"submissions.php?action=adminlist&id=$cm->id&order=name\">".
+ get_string("submittedby", "exercise")."</a>", get_string("title", "exercise"), get_string("action", "exercise"));
+ break;
+ case "name" :
+ $table->head = array (get_string("submittedby", "exercise"),
+ "<a href=\"submissions.php?action=adminlist&id=$cm->id&order=title\">".
+ get_string("title", "exercise")."</a>", get_string("action", "exercise"));
+ break;
+ }
+ $table->align = array ("left", "left", "left");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ if ($submissions = exercise_get_student_submissions($exercise, $order)) {
+ foreach ($submissions as $submission) {
+ if (!$user = get_record("user", "id", $submission->userid)) {
+ error("exercise_list_submissions_for_admin: failure to get user record");
+ }
+ $action = "<a href=\"submissions.php?action=adminamendtitle&id=$cm->id&sid=$submission->id\">".
+ get_string("amendtitle", "exercise")."</a>";
+ // has teacher already assessed this submission
+ if ($assessment = get_record_select("exercise_assessments", "submissionid = $submission->id
+ AND userid = $USER->id")) {
+ $curtime = time();
+ if (($curtime - $assessment->timecreated) > $CFG->maxeditingtime) {
+ $action .= " | <a href=\"assessments.php?action=assesssubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("reassess", "exercise")."</a>";
+ }
+ else { // there's still time left to edit...
+ $action .= " | <a href=\"assessments.php?action=assesssubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("edit", "exercise")."</a>";
+ }
+ }
+ else { // user has not assessed this submission
+ $action .= " | <a href=\"assessments.php?action=assesssubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("assess", "exercise")."</a>";
+ }
+ if ($nassessments = exercise_count_assessments($submission)) {
+ $action .= " | <a href=\"assessments.php?action=adminlist&id=$cm->id&sid=$submission->id\">".
+ get_string("view", "exercise")." ($nassessments)</a>";
+ }
+ $action .= " | <a href=\"submissions.php?action=adminconfirmdelete&id=$cm->id&sid=$submission->id\">".
+ get_string("delete", "exercise")."</a>";
+ $title = $submission->title;
+ if ($submission->resubmit) {
+ $title .= "*";
+ }
+ $table->data[] = array("$user->firstname $user->lastname", $title.
+ " ".exercise_print_submission_assessments($exercise, $submission), $action);
+ }
+ print_heading(get_string("studentsubmissions", "exercise", $course->student), "center");
+ print_table($table);
+ echo "<center><p>".get_string("resubmitnote", "exercise", $course->student)."</p>\n";
+ echo "<p>".get_string("allgradeshaveamaximumof", "exercise", $exercise->grade)."%</p></center>\n";
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_teacher_assessments($exercise, $user) {
+ global $CFG;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ $table->head = array (get_string("title", "exercise"), get_string("action", "exercise"), get_string("comment", "exercise"));
+ $table->align = array ("LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ // get user's submissions
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ foreach ($submissions as $submission) {
+ // get the assessments
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ if (isteacher($exercise->course, $assessment->userid)) { // assessments by teachers only
+ $action = "<A HREF=\"assessments.php?action=viewassessment&a=$exercise->id&aid=$assessment->id\">".
+ get_string("view", "exercise")."</A>";
+ // has teacher commented on teacher's assessment? shouldn't happen but leave test in
+ if ($assessment->timegraded and ($timenow - $assessment->timegraded > $CFG->maxeditingtime)) {
+ $comment = get_string("gradedbyteacher", "exercise", $course->teacher);
+ }
+ else {
+ $comment = userdate($assessment->timecreated);
+ }
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $comment);
+ }
+ }
+ }
+ }
+ }
+ if (isset($table->data)) {
+ print_table($table);
+ }
+ else {
+ echo "<CENTER>".get_string("noassessmentsdone", "exercise")."</CENTER>\n";
+ }
+ }
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_teacher_submissions($exercise, $user, $reassess = false) {
+ // always allow user to reassess if that flag is true
+ global $CFG;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+
+ $nexercises = 1; // set as a variable (possible future extension)
+ if ($nexercises ==1 ) {
+ $table->head = array ($strexercise, get_string("action", "exercise"), get_string("assessed", "exercise"),
+ get_string("comment", "exercise"));
+ }
+ else { //use plural
+ $table->head = array ($strexercises, get_string("action", "exercise"), get_string("assessed", "exercise"),
+ get_string("comment", "exercise"));
+ }
+ $table->align = array ("LEFT", "LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ // get the number of assessments this user has done (could include placeholder one)
+ $nassessed = count_records_select("exercise_assessments", "exerciseid = $exercise->id
+ AND userid = $user->id");
+ if ($nassessed < $nexercises) {
+ // if user has not assessed enough, set up "future" assessment records for this user for the teacher submissions...
+ // ... first count the number of assessments for each teacher submission...
+ if ($submissions = exercise_get_teacher_submissions($exercise)) {
+ srand ((float)microtime()*1000000); // initialise random number generator
+ foreach ($submissions as $submission) {
+ $n = count_records("exercise_assessments", "submissionid", $submission->id);
+ // ...OK to have zero, we add a small random number to randomise things...
+ $nassessments[$submission->id] = $n + rand(0, 99) / 100;
+ }
+ // ...put the submissions with the lowest number of assessments first...
+ asort($nassessments);
+ reset($nassessments);
+ foreach ($nassessments as $submissionid => $n) { // break out of loop when we allocated enough assessments...
+ $submission = get_record("exercise_submissions", "id", $submissionid);
+ // ... provided the user has NOT already assessed that submission...
+ if (!$assessment = exercise_get_submission_assessment($submission, $user)) {
+ $yearfromnow = time() + 365 * 86400;
+ // ...create one and set timecreated way in the future, this is reset when record is updated
+ $assessment->exerciseid = $exercise->id;
+ $assessment->submissionid = $submission->id;
+ $assessment->userid = $user->id;
+ $assessment->grade = -1; // set impossible grade
+ $assessment->timecreated = $yearfromnow;
+ if (!$assessment->id = insert_record("exercise_assessments", $assessment)) {
+ error("Could not insert exercise assessment!");
+ }
+ $nassessed++;
+ if ($nassessed >= $nexercises) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ // now list user's assessments (but only list those which come from teacher submissions)
+ if ($assessments = exercise_get_user_assessments($exercise, $user)) {
+ $timenow = time();
+ foreach ($assessments as $assessment) {
+ if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
+ error ("exercise_list_teacher_submissions: unable to get submission");
+ }
+ // submission from a teacher, i.e an exercise submission?
+ if ($submission->isexercise) {
+ $comment = '';
+ if ($reassess) { //just show re-assess
+ $action = "<A HREF=\"assessments.php?action=assesssubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("reassess", "exercise")."</A>";
+ }
+ else { // reassess is false - assessment is a "normal state"
+ // user assessment has three states: record created but not assessed (date created in the future);
+ // just assessed but still editable; and "static" (may or may not have been graded by teacher, that
+ // is shown in the comment)
+ if ($assessment->timecreated > $timenow) { // user needs to assess this submission
+ $action = "<A HREF=\"assessments.php?action=assesssubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("assess", "exercise")."</A>";
+ }
+ elseif ($assessment->timecreated > ($timenow - $CFG->maxeditingtime)) { // there's still time left to edit...
+ $action = "<A HREF=\"assessments.php?action=assesssubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("edit", "exercise")."</A>";
+ }
+ else {
+ $action = "<A HREF=\"assessments.php?action=viewassessment&id=$cm->id&aid=$assessment->id\">"
+ .get_string("view", "exercise")."</A>";
+ }
+ }
+ // show the date if in the past (otherwise the user hasn't done the assessment yet
+ $assessmentdate = '';
+ if ($assessment->timecreated < $timenow) {
+ $assessmentdate = userdate($assessment->timecreated);
+ // if user has submitted work, see if teacher has graded assessment
+ if (exercise_count_user_submissions($exercise, $user) > 0) {
+ if ($assessment->timegraded and (($timenow - $assessment->timegraded) > $CFG->maxeditingtime)) {
+ $comment .= get_string("thereisfeedbackfromthe", "exercise", $course->teacher);
+ }
+ else {
+ $comment .= get_string("awaitingfeedbackfromthe", "exercise", $course->teacher);
+ }
+ }
+ }
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $assessmentdate,
+ $comment);
+ }
+ }
+ }
+ print_table($table);
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_unassessed_student_submissions($exercise, $user) {
+ // list the student submissions not assessed by the teacher
+ global $CFG;
+
+ $timenow = time();
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ $table->head = array (get_string("title", "exercise"), get_string("submittedby", "exercise"),
+ get_string("action", "exercise"), get_string("comment", "exercise"));
+ $table->align = array ("LEFT", "LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ if ($submissions = exercise_get_student_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ // only consider "cold" submissions
+ if ($submission->timecreated < $timenow - $CFG->maxeditingtime) {
+ $comment = "";
+ // see if student has already submitted
+ $submissionowner = get_record("user", "id", $submission->userid);
+ if (exercise_count_user_submissions($exercise, $submissionowner) == 1) {
+ // it's the student's first submission, get their assessment
+ if (!$assessments = exercise_get_user_assessments($exercise, $submissionowner)) {
+ error("List Unassessed Student submission: student's assessment record not found");
+ }
+ foreach ($assessments as $assessment) {
+ $studentassessment = $assessment;
+ break; // there should only be one!
+ }
+ // now see if the teacher has already assessed this submission
+ $teacherassessed = false;
+ $warm = false;
+ if ($assessments = get_records("exercise_assessments", "submissionid", $submission->id)) {
+ foreach ($assessments as $assessment) {
+ if (isteacher($course->id, $assessment->userid)) {
+ $teacherassessed = true;
+ if ($assessment->timecreated > $timenow -$CFG->maxeditingtime) {
+ $warm = true;
+ }
+ break; // no need to look further
+ }
+ }
+ }
+ if ($teacherassessed and $warm) {
+ // last chance salon
+ $action = "<A HREF=\"assessments.php?action=teacherassessment&id=$cm->id&aid=$studentassessment->id&sid=$submission->id\">".
+ get_string("edit", "exercise")."</A>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ $submissionowner->firstname." ".$submissionowner->lastname, $action, $comment);
+ }
+ if(!$teacherassessed) {
+ $action = "<A HREF=\"assessments.php?action=teacherassessment&id=$cm->id&aid=$studentassessment->id&sid=$submission->id\">".
+ get_string("assess", "exercise")."</A>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ $submissionowner->firstname." ".$submissionowner->lastname, $action, $comment);
+ }
+ }
+ // this is student's second... submission
+ else {
+ $teacherassessed = false;
+ $warm = false;
+ if ($assessments = get_records("exercise_assessments", "submissionid", $submission->id)) {
+ foreach ($assessments as $assessment) {
+ if (isteacher($course->id, $assessment->userid)) {
+ $teacherassessed = true;
+ if ($assessment->timecreated > $timenow - $CFG->maxeditingtime) {
+ $warm = true;
+ }
+ break; // no need to look further
+ }
+ }
+ }
+ if ($teacherassessed and $warm) {
+ // last chance salon
+ $action = "<A HREF=\"assessments.php?action=assessresubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("edit", "exercise")."</A>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ $submissionowner->firstname." ".$submissionowner->lastname, $action, $comment);
+ }
+ if (!$teacherassessed) {
+ // no teacher's assessment
+ $action = "<A HREF=\"assessments.php?action=assessresubmission&id=$cm->id&sid=$submission->id\">".
+ get_string("assess", "exercise")."</A>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ $submissionowner->firstname." ".$submissionowner->lastname, $action, $comment);
+ }
+ }
+ }
+ }
+ if (isset($table->data)) {
+ print_table($table);
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_unassessed_teacher_submissions($exercise, $user) {
+ // list the teacher submissions not assessed by this user
+ global $CFG;
+
+ $table->head = array (get_string("title", "exercise"), get_string("action", "exercise"), get_string("comment", "exercise"));
+ $table->align = array ("LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ if ($submissions = exercise_get_teacher_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ $comment = "";
+ // see if user already graded this assessment
+ if ($assessment = get_record_select("exercise_assessments", "submissionid = $submission->id
+ AND userid = $user->id")) {
+ $timenow = time();
+ if (($timenow - $assessment->timecreated < $CFG->maxeditingtime)) {
+ // last chance salon
+ $action = "<A HREF=\"assessments.php?action=assesssubmission&a=$exercise->id&sid=$submission->id\">".
+ get_string("edit", "exercise")."</A>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $comment);
+ }
+ }
+ else { // no assessment
+ $action = "<A HREF=\"assessments.php?action=assesssubmission&a=$exercise->id&sid=$submission->id\">".
+ get_string("assess", "exercise")."</A>";
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action, $comment);
+ }
+ }
+ if (isset($table->data)) {
+ print_table($table);
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_ungraded_assessments($exercise, $stype) {
+ global $CFG;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ // lists all the assessments of student submissions for grading by teacher
+ $table->head = array (get_string("title", "exercise"), get_string("submittedby", "exercise"),
+ get_string("assessor", "exercise"), get_string("timeassessed", "exercise"), get_string("action", "exercise"));
+ $table->align = array ("LEFT", "LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+ $timenow = time();
+
+ switch ($stype) {
+ case "student" :
+ $assessments = exercise_get_ungraded_assessments_student($exercise);
+ break;
+ case "teacher" :
+ $assessments = exercise_get_ungraded_assessments_teacher($exercise);
+ break;
+ }
+ if ($assessments) {
+ foreach ($assessments as $assessment) {
+ if (!isteacher($exercise->course, $assessment->userid)) { // don't let teacher grade their own assessments
+ if (($timenow - $assessment->timegraded) < $CFG->maxeditingtime) {
+ $action = "<A HREF=\"assessments.php?action=gradeassessment&id=$cm->id&stype=$stype&aid=$assessment->id\">".
+ get_string("edit", "exercise")."</A>";
+ }
+ else {
+ $action = "<A HREF=\"assessments.php?action=gradeassessment&id=$cm->id&stype=$stype&aid=$assessment->id\">".
+ get_string("grade", "exercise")."</A>";
+ }
+ $submission = get_record("exercise_submissions", "id", $assessment->submissionid);
+ $submissionowner = get_record("user", "id", $submission->userid);
+ $assessor = get_record("user", "id", $assessment->userid);
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission),
+ $submissionowner->firstname." ".$submissionowner->lastname,
+ $assessor->firstname." ".$assessor->lastname, userdate($assessment->timecreated), $action);
+ }
+ }
+ if (isset($table->data)) {
+ print_table($table);
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_list_user_submissions($exercise, $user) {
+ global $CFG;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ $timenow = time();
+ $table->head = array (get_string("title", "exercise"), get_string("action", "exercise"),
+ get_string("submitted", "assignment"), get_string("comment", "exercise"));
+ $table->align = array ("LEFT", "LEFT", "LEFT", "LEFT");
+ $table->size = array ("*", "*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ foreach ($submissions as $submission) {
+ $action = '';
+ $comment = '';
+ if (isstudent($course->id, $user->id)) {
+ $comment = get_string("awaitingassessmentbythe", "exercise", $course->teacher);
+ }
+ // allow user to delete submission if it's warm
+ if ($submission->timecreated > $timenow - $CFG->maxeditingtime) {
+ $action = "<a href=\"submissions.php?action=userconfirmdelete&id=$cm->id&sid=$submission->id\">".
+ get_string("delete", "exercise")."</a>";
+ }
+ // get the teacher assessments (could be more than one, if unlikely, when multiple teachers)
+ if ($assessments = get_records_select("exercise_assessments", "exerciseid = $exercise->id AND
+ submissionid = $submission->id")) {
+ foreach ($assessments as $assessment) {
+ // make sure it's real
+ if ($assessment->timecreated < $timenow - $CFG->maxeditingtime) { // it's cold
+ if ($action) {
+ $action .= " | ";
+ }
+ $action .= "<a href=\"assessments.php?action=viewassessment&id=$cm->id&aid=$assessment->id\">".
+ get_string("viewassessment", "exercise")."</a>";;
+ $comment = get_string("assessmentmadebythe", "exercise", $course->teacher);
+ }
+ }
+ }
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), $action,
+ userdate($submission->timecreated), $comment);
+ }
+ print_table($table);
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_assessment_form($exercise, $assessment = false, $allowchanges = false, $returnto = '') {
+ // prints several variants of the assessment form
+ global $CFG, $THEME, $USER, $EXERCISE_SCALES, $EXERCISE_EWEIGHTS;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ $timenow = time();
+
+ if ($assessment) {
+
+ if (!$submission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
+ error ("exercise_print_assessment_form: Submission record not found");
+ }
+
+ if (isteacher($course->id)) {
+ // show the teacher the exercise: requires getting the student's assessment(s) and finding the assessment which
+ // comes from a teacher submission
+ $exercisefound = false;
+ if (!$submissionowner = get_record("user", "id", $submission->userid)) {
+ error ("exercise_print_assessment_form: User record not found");
+ }
+ if ($initialassessments = exercise_get_user_assessments($exercise, $submissionowner)) {
+ // should only be one but we'll loop anyway
+ foreach($initialassessments as $initialassessment) {
+ if (!$teachersubmission = get_record("exercise_submissions", "id", $initialassessment->submissionid)) {
+ error ("exercise_print_assessment_form: Teacher Submission record not found");
+ }
+ if ($teachersubmission->isexercise) {
+ $exercisefound = true;
+ break;
+ }
+ }
+ }
+ if ($exercisefound) {
+ print_heading(get_string("theexerciseandthesubmissionby", "exercise",
+ "$submissionowner->firstname $submissionowner->lastname"));
+ echo "<CENTER><TABLE BORDER=\"1\" WIDTH=\"30%\"><TR>
+ <TD ALIGN=CENTER BGCOLOR=\"$THEME->cellcontent\">\n";
+ echo exercise_print_submission_title($exercise, $teachersubmission);
+ echo "</TD></TR></TABLE><BR CLEAR=ALL>\n";
+ }
+ }
+ else {
+ // it's a student, print instructions if it's their own assessment
+ if ($assessment->userid == $USER->id) {
+ print_heading_with_help(get_string("pleaseusethisform", "exercise"), "grading", "exercise");
+ }
+ }
+
+ echo "<CENTER><TABLE BORDER=\"1\" WIDTH=\"30%\"><TR>
+ <TD ALIGN=CENTER BGCOLOR=\"$THEME->cellcontent\">\n";
+ echo exercise_print_submission_title($exercise, $submission);
+ echo "</TD></TR></TABLE><BR CLEAR=ALL>\n";
+
+ // only show the grade if grading strategy > 0 and the grade is positive
+ if ($exercise->gradingstrategy and $assessment->grade >= 0) { \r
+ echo "<CENTER><B>".get_string("thegradeis", "exercise").": ".
+ number_format($assessment->grade * $exercise->grade / 100.0, 2)."% (".
+ get_string("maximumgrade")." ".number_format($exercise->grade, 0)."%)</B></CENTER><BR CLEAR=ALL>\n";
+ }
+ }
+
+ // now print the grading form with the teacher's comments if any
+ // FORM is needed for Mozilla browsers, else radio bttons are not checked
+ ?>
+ <form name="assessmentform" method="post" action="assessments.php">
+ <INPUT TYPE="hidden" NAME="id" VALUE="<?PHP echo $cm->id ?>">
+ <input type="hidden" name="aid" value="<?PHP echo $assessment->id ?>">
+ <input type="hidden" name="action" value="updateassessment">
+ <input type="hidden" name="resubmit" value="0">
+ <input type="hidden" name="returnto" value="<?PHP echo $returnto ?>">
+ <?PHP
+ if ($assessment) {
+ if (!$assessmentowner = get_record("user", "id", $assessment->userid)) {
+ error("Exercise_print_assessment_form: could not find user record");
+ }
+ if ($assessmentowner->id == $USER->id) {
+ $formtitle = get_string("yourassessment", "exercise");
+ }
+ else {
+ $formtitle = get_string("assessmentby", "exercise", "$assessmentowner->firstname $assessmentowner->lastname");
+ }
+ }
+ else {
+ $formtitle = get_string("assessmentform", "exercise");
+ }
+ echo "<center><table cellpadding=\"2\" border=\"1\">\n";
+ echo "<tr valign=top>\n";\r
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"><center><b>$formtitle</b></center></td>\n";\r
+ echo "</tr>\n";
+
+ // get the assignment elements...
+ if (!$elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC")) {
+ print_string("noteonassignmentelements", "exercise");
+ }
+ else {
+ foreach ($elementsraw as $element) {
+ $elements[] = $element; // to renumber index 0,1,2...
+ }
+ }
+
+ if ($assessment) {
+ // get any previous grades...
+ if ($gradesraw = get_records_select("exercise_grades", "assessmentid = $assessment->id", "elementno")) {
+ foreach ($gradesraw as $grade) {
+ $grades[] = $grade; // to renumber index 0,1,2...
+ }
+ }
+ }
+ else {
+ // setup dummy grades array
+ for($i = 0; $i < count($elementsraw); $i++) { // gives a suitable sized loop
+ $grades[$i]->feedback = get_string("yourfeedbackgoeshere", "exercise");
+ $grades[$i]->grade = 0;
+ }
+ }
+
+ // determine what sort of grading
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ // now print the form
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";\r
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";\r
+ echo " <TD>\n";
+ if ($allowchanges) {\r
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }\r
+ echo " </TD>\n";\r
+ echo "</TR>\n";\r
+ echo "<TR valign=top>\n";\r
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo "</TR>\n";
+ }
+ break;
+
+ case 1: // accumulative grading
+ // now print the form
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";\r
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "<P align=right><FONT size=1>Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</FONT>\n";
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("grade"). ":</B></P></TD>\n";
+ echo " <TD valign=\"top\">\n";
+
+ // get the appropriate scale
+ $scalenumber=$elements[$i]->scale;
+ $SCALE = (object)$EXERCISE_SCALES[$scalenumber];
+ switch ($SCALE->type) {
+ case 'radio' :
+ // show selections highest first
+ echo "<CENTER><B>$SCALE->start</B> ";
+ for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
+ $checked = false;
+ if (isset($grades[$i]->grade)) {
+ if ($j == $grades[$i]->grade) {
+ $checked = true;
+ }
+ }
+ else { // there's no previous grade so check the lowest option
+ if ($j == 0) {
+ $checked = true;
+ }
+ }
+ if ($checked) {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\" CHECKED> \n";
+ }
+ else {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\"> \n";
+ }
+ }
+ echo " <B>$SCALE->end</B></CENTER>\n";
+ break;
+ case 'selection' :
+ unset($numbers);
+ for ($j = $SCALE->size; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$i]->grade)) {
+ choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[$i]", 0, "");
+ }
+ break;
+
+ echo " </TD>\n";
+ echo "</TR>\n";
+ }
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";\r
+ echo " <TD>\n";
+ if ($allowchanges) {\r
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }\r
+ echo " </TD>\n";\r
+ echo "</TR>\n";\r
+ echo "<TR valign=top>\n";\r
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo "</TR>\n";
+ }
+ break;
+
+ case 2: // error banded grading
+ // now run through the elements
+ $error = 0;
+ for ($i=0; $i < count($elements) - 1; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";\r
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "<P align=right><FONT size=1>Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</FONT>\n";
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("grade"). ":</B></P></TD>\n";
+ echo " <TD valign=\"top\">\n";
+
+ // get the appropriate scale - yes/no scale (0)
+ $SCALE = (object) $EXERCISE_SCALES[0];
+ switch ($SCALE->type) {
+ case 'radio' :
+ // show selections highest first
+ echo "<CENTER><B>$SCALE->start</B> ";
+ for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
+ $checked = false;
+ if (isset($grades[$i]->grade)) {
+ if ($j == $grades[$i]->grade) {
+ $checked = true;
+ }
+ }
+ else { // there's no previous grade so check the lowest option
+ if ($j == 0) {
+ $checked = true;
+ }
+ }
+ if ($checked) {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\" CHECKED> \n";
+ }
+ else {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\"> \n";
+ }
+ }
+ echo " <B>$SCALE->end</B></CENTER>\n";
+ break;
+ case 'selection' :
+ unset($numbers);
+ for ($j = $SCALE->size; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$i]->grade)) {
+ choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[$i]", 0, "");
+ }
+ break;
+ }
+
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";\r
+ echo " <TD>\n";
+ if ($allowchanges) {\r
+ echo " <textarea name=\"feedback[$i]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ if (isset($grades[$i]->feedback)) {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ }\r
+ echo " </TD>\n";\r
+ echo "</TR>\n";\r
+ echo "<TR valign=top>\n";\r
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo "</TR>\n";
+ if (empty($grades[$i]->grade)) {
+ $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
+ }
+ }
+ // print the number of negative elements
+ // echo "<TR><TD>".get_string("numberofnegativeitems", "exercise")."</TD><TD>$negativecount</TD></TR>\n";\r
+ // echo "<TR valign=top>\n";\r
+ // echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo "</TABLE></CENTER>\n";
+ // now print the grade table
+ echo "<P><CENTER><B>".get_string("gradetable","exercise")."</B></CENTER>\n";
+ echo "<CENTER><TABLE cellpadding=5 border=1><TR><TD ALIGN=\"CENTER\">".
+ get_string("numberofnegativeresponses", "exercise");
+ echo "</TD><TD>". get_string("suggestedgrade", "exercise")."</TD></TR>\n";
+ for ($i=0; $i<=$exercise->nelements; $i++) {
+ if ($i == intval($error + 0.5)) {
+ echo "<TR><TD ALIGN=\"CENTER\"><IMG SRC=\"../../pix/t/right.gif\"> $i</TD><TD ALIGN=\"CENTER\">{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ else {
+ echo "<TR><TD ALIGN=\"CENTER\">$i</TD><TD ALIGN=\"CENTER\">{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ }
+ echo "</TABLE></CENTER>\n";
+ echo "<P><CENTER><TABLE cellpadding=5 border=1><TR><TD align=\"right\"><b>".
+ get_string("optionaladjustment", "exercise").":</b></TD><TD>\n";
+ unset($numbers);
+ for ($j = 20; $j >= -20; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$exercise->nelements]->grade)) {
+ choose_from_menu($numbers, "grade[$exercise->nelements]", $grades[$exercise->nelements]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[$exercise->nelements]", 0, "");
+ }
+ echo "</TD></TR>\n";
+ break;
+
+ case 3: // criteria grading
+ echo "<TR valign=top>\n";\r
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>". get_string("criterion","exercise")."</B></TD>\n";\r
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>".get_string("select", "exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>".get_string("suggestedgrade", "exercise")."</B></TD>\n";
+ // find which criteria has been selected (saved in the zero element), if any
+ if (isset($grades[0]->grade)) {
+ $selection = $grades[0]->grade;
+ }
+ else {
+ $selection = 0;
+ }
+ // now run through the elements
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";\r
+ echo " <TD>$iplus1</TD><TD>".text_to_html($elements[$i]->description)."</TD>\n";
+ if ($selection == $i) {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[0]\" VALUE=\"$i\" CHECKED></TD>\n";
+ }
+ else {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[0]\" VALUE=\"$i\"></TD>\n";
+ }
+ echo "<TD align=center>{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ echo "</TABLE></CENTER>\n";
+ echo "<P><CENTER><TABLE cellpadding=5 border=1><TR><TD align=\"right\"><b>".
+ get_string("optionaladjustment", "exercise")."</b></TD><TD>\n";
+ unset($numbers);
+ for ($j = 20; $j >= -20; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[1]->grade)) {
+ choose_from_menu($numbers, "grade[1]", $grades[1]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[1]", 0, "");
+ }
+ echo "</TD></TR>\n";
+ break;
+
+ case 4: // rubric grading
+ // now run through the elements...
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=\"top\">\n";\r
+ echo "<TD align=\"right\"><b>".get_string("element", "exercise")." $iplus1:</b></TD>\n";
+ echo "<TD>".text_to_html($elements[$i]->description).
+ "<P align=\"right\"><font size=\"1\">Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font></TD></tr>\n";
+ echo "<TR valign=\"top\">\n";\r
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\" align=\"center\"><B>".get_string("select", "exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>". get_string("criterion","exercise")."</B></TD></tr>\n";\r
+ if (isset($grades[$i])) {
+ $selection = $grades[$i]->grade;
+ } else {
+ $selection = 0;
+ }
+ // ...and the rubrics
+ if ($rubricsraw = get_records_select("exercise_rubrics", "exerciseid = $exercise->id AND
+ elementno = $i", "rubricno ASC")) {
+ unset($rubrics);
+ foreach ($rubricsraw as $rubic) {
+ $rubrics[] = $rubic; // to renumber index 0,1,2...
+ }
+ for ($j=0; $j<5; $j++) {
+ if (empty($rubrics[$j]->description)) {
+ break; // out of inner for loop
+ }
+ echo "<TR valign=top>\n";\r
+ if ($selection == $j) {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\" CHECKED></TD>\n";
+ }else {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\"></TD>\n";
+ }
+ echo "<TD>".text_to_html($rubrics[$j]->description)."</TD>\n";
+ }
+ echo "<TR valign=top>\n";\r
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";\r
+ echo " <TD>\n";
+ if ($allowchanges) {\r
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }\r
+ echo " </td>\n";\r
+ echo "</tr>\n";\r
+ echo "<tr valign=\"top\">\n";\r
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo "</tr>\n";
+ }
+ }
+ break;
+ } // end of outer switch
+
+ // now get the general comment (present in all types)
+ echo "<tr valign=\"top\">\n";
+ switch ($exercise->gradingstrategy) {
+ case 0:
+ case 1:
+ case 4 : // no grading, accumulative and rubic\r
+ echo " <td align=\"right\"><P><B>". get_string("generalcomment", "exercise").":</B></P></TD>\n";
+ break;
+ default :
+ echo " <td align=\"right\"><P><B>". get_string("reasonforadjustment", "exercise").":</B></P></TD>\n";
+ }\r
+ echo " <td>\n";\r
+ if ($allowchanges) {
+ echo " <textarea name=\"generalcomment\" rows=5 cols=75 wrap=\"virtual\">\n";
+ if (isset($assessment->generalcomment)) {
+ echo $assessment->generalcomment;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ if ($assessment) {
+ if (isset($assessment->generalcomment)) {
+ echo text_to_html($assessment->generalcomment);
+ }
+ }
+ else {
+ print_string("yourfeedbackgoeshere", "exercise");
+ }
+ }\r
+ echo " </td>\n";\r
+ echo "</tr>\n";\r
+ echo "<tr valign=\"top\">\n";\r
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </TD>\n";\r
+ echo "</tr>\n";
+
+ $timenow = time();
+ // the teacher's comment on the assessment
+ // always allow the teacher to change their comment and grade if it's not their assessment!
+ if (isteacher($course->id) and ($assessment->userid != $USER->id)) {
+ echo "<tr><td align=\"right\"><b>".get_string("gradeforstudentsassessment", "exercise", $course->student).
+ "</td><td>\n";
+ // set up coment scale
+ for ($i=COMMENTSCALE; $i>=0; $i--) {
+ $num[$i] = $i;
+ }
+ choose_from_menu($num, "gradinggrade", $assessment->gradinggrade, "");
+ echo "</td></tr>\n";
+ echo "<tr valign=\"top\">\n";
+ echo " <td align=\"right\"><p><b>". get_string("teacherscomment", "exercise").":</b></p></td>\n";
+ echo " <td>\n";
+ echo "<textarea name=\"teachercomment\" rows=\"5\" cols=\"75\" wrap=\"virtual\">\n";
+ if (isset($assessment->teachercomment)) {
+ echo $assessment->teachercomment;
+ }
+ echo "</textarea>\n";
+ echo " </td>\n";
+ echo "</tr>\n";
+ }
+ elseif ($assessment->timegraded and ($assessment->timegraded < ($timenow - $CFG->maxeditingtime))) {
+ // now show the teacher's comment (but not the grade) to the student if available...
+ echo "<tr valign=top>\n";\r
+ echo " <td align=\"right\"><p><b>". get_string("teacherscomment", "exercise").":</b></p></td>\n";\r
+ echo " <td>\n";\r
+ echo text_to_html($assessment->teachercomment);
+ echo " </td>\n";\r
+ echo "</tr>\n";
+ echo "<tr valign=\"top\">\n";\r
+ echo "<td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </td>\n";\r
+ echo "</tr>\n";
+ }
+
+ // ...and close the table, show buttons if needed...
+ echo "</table><br />\n";
+ if ($assessment and $allowchanges) {
+ if (isteacher($course->id)) {
+ // ...show two buttons...to resubmit or not to resubmit
+ echo "<input type=\"button\" value=\"".get_string("studentnotallowed", "exercise", $course->student)."\"
+ onclick=\"document.assessmentform.submit();\">\n";
+ echo "<input type=\"button\" value=\"".get_string("studentallowedtoresubmit", "exercise", $course->student)."\"
+ onclick=\"document.assessmentform.resubmit.value='1';document.assessmentform.submit();\">\n";
+ }
+ else {
+ // ... show save button
+ echo "<input type=\"submit\" value=\"".get_string("savemyassessment", "exercise")."\">\n";
+ }
+ }
+ echo "</center></form>\n";
+ }\r
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_assessments_by_user_for_admin($exercise, $user) {
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if ($assessments =exercise_get_user_assessments($exercise, $user)) {
+ foreach ($assessments as $assessment) {
+ echo "<p><center><b>".get_string("assessmentby", "exercise", $user->firstname." ".$user->lastname)."</b></center></p>\n";
+ exercise_print_assessment_form($exercise, $assessment);
+ echo "<p align=\"right\"><a href=\"assessments.php?action=adminconfirmdelete&id=$cm->id&aid=$assessment->id\">".
+ get_string("delete", "exercise")."</a></p><hr>\n";
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_assessments_for_admin($exercise, $submission) {
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if ($assessments =exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ if (!$user = get_record("user", "id", $assessment->userid)) {
+ error (" exercise_print_assessments_for_admin: unable to get user record");
+ }
+ echo "<p><center><b>".get_string("assessmentby", "exercise", $user->firstname." ".$user->lastname)."</b></center></p>\n";
+ exercise_print_assessment_form($exercise, $assessment);
+ echo "<p align=\"right\"><a href=\"assessments.php?action=adminconfirmdelete&id=$cm->id&aid=$assessment->id\">".
+ get_string("delete", "exercise")."</a></p><hr>\n";
+ }
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_assignment_info($exercise) {
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+ // print standard assignment heading
+ $strdifference = format_time($exercise->deadline - time());
+ if (($exercise->deadline - time()) < 0) {
+ $strdifference = "<font color=\"red\">$strdifference</font>";
+ }
+ $strduedate = userdate($exercise->deadline)." ($strdifference)";
+ print_simple_box_start("center");
+ print_heading($exercise->name, "center");
+ print_simple_box_start("center");
+ echo "<b>".get_string("duedate", "exercise")."</b>: $strduedate<br />";
+ echo "<b>".get_string("maximumgrade")."</b>: $exercise->grade<br />";
+ echo "<b>".get_string("handlingofmultiplesubmissions", "exercise")."</b>:";
+ if ($exercise->usemaximum) {
+ echo get_string("usemaximum", "exercise")."<br />\n";
+ }
+ else {
+ echo get_string("usemean", "exercise")."<br />\n";
+ }
+ echo "<b>".get_string("detailsofassessment", "exercise")."</b>:
+ <a href=\"assessments.php?id=$cm->id&action=displaygradingform\">".
+ get_string("specimenassessmentform", "exercise")."</a><br />";
+ print_simple_box_end();
+ print_simple_box_end();
+ echo "<br />";
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_difference($time) {
+ if ($time < 0) {
+ $timetext = get_string("late", "assignment", format_time($time));
+ return " (<FONT COLOR=RED>$timetext</FONT>)";
+ } else {
+ $timetext = get_string("early", "assignment", format_time($time));
+ return " ($timetext)";
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_dual_assessment_form($exercise, $assessment, $submission, $returnto = '') {
+ // prints the user's assessment and a blank form for the user's submission (for teachers only)
+ global $CFG, $THEME, $USER, $EXERCISE_SCALES, $EXERCISE_EWEIGHTS;
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ $timenow = time();
+
+ if(!$submissionowner = get_record("user", "id", $submission->userid)) {
+ error("Print dual assessment form: User record not found");
+ }
+
+ echo "<CENTER><TABLE BORDER=\"1\" WIDTH=\"30%\"><TR>
+ <TD ALIGN=CENTER BGCOLOR=\"$THEME->cellcontent\">\n";
+ if (!$teachersubmission = get_record("exercise_submissions", "id", $assessment->submissionid)) {
+ error ("exercise_print_assessment_form: Submission record not found");
+ }
+ echo exercise_print_submission_title($exercise, $teachersubmission);
+ echo "</TD></TR></TABLE><BR CLEAR=ALL>\n";
+
+ print_heading_with_help(get_string("pleasegradetheassessment", "exercise",
+ "$submissionowner->firstname $submissionowner->lastname"), "gradinggrade", "exercise");
+
+ echo "<CENTER><TABLE BORDER=\"1\" WIDTH=\"30%\"><TR>
+ <TD ALIGN=CENTER BGCOLOR=\"$THEME->cellcontent\">\n";
+ echo exercise_print_submission_title($exercise, $submission);
+ echo "</TD></TR></TABLE></center><BR CLEAR=ALL>\n";
+
+ // only show the grade if grading strategy > 0 and the grade is positive
+ if ($exercise->gradingstrategy and $assessment->grade >= 0) {
+ echo "<CENTER><B>".get_string("thegradeis", "exercise").": ".
+ number_format($assessment->grade * $exercise->grade / 100.0, 2)."% (".
+ get_string("maximumgrade")." ".number_format($exercise->grade, 0)."%)</B></CENTER><BR CLEAR=ALL>\n";
+ }
+
+ // now print the student's assessment form with the teacher's comments if any
+ // in this (first) form only allow teachers to change their comment and the grading grade
+ // the other "active" elements in thie form are suffixed with "_0" to stop conflicts with the teacher's
+ // assessment form
+ $allowchanges = false;
+
+ // FORM is needed for Mozilla browsers, else radio bttons are not checked
+ ?>
+ <form name="assessmentform" method="post" action="assessments.php">
+ <INPUT TYPE="hidden" NAME="id" VALUE="<?PHP echo $cm->id ?>">
+ <input type="hidden" name="aid" value="<?PHP echo $assessment->id ?>">
+ <input type="hidden" name="sid" value="<?PHP echo $submission->id ?>">
+ <input type="hidden" name="action" value="updatedualassessment">
+ <input type="hidden" name="resubmit" value="0">
+ <input type="hidden" name="returnto" value="<?PHP echo $returnto ?>">
+ <?PHP
+ if (!$assessmentowner = get_record("user", "id", $assessment->userid)) {
+ error("Exercise_print_dual_assessment_form: could not find user record");
+ }
+ echo "<center><table cellpadding=\"2\" border=\"1\">\n";
+ echo "<tr valign=top>\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"><center><B>".get_string("assessmentby",
+ "exercise", "$assessmentowner->firstname $assessmentowner->lastname")."</b></center></td>\n";
+ echo "</tr>\n";
+
+ // get the assignment elements...
+ if (!$elementsraw = get_records("exercise_elements", "exerciseid", $exercise->id, "elementno ASC")) {
+ print_string("noteonassignmentelements", "exercise");
+ }
+ else {
+ foreach ($elementsraw as $element) {
+ $elements[] = $element; // to renumber index 0,1,2...
+ }
+ }
+
+ // get any previous grades...
+ if ($gradesraw = get_records_select("exercise_grades", "assessmentid = $assessment->id", "elementno")) {
+ foreach ($gradesraw as $grade) {
+ $grades[] = $grade; // to renumber index 0,1,2...
+ }
+ }
+
+ // determine what sort of grading
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ // now print the form
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 1: // accumulative grading
+ // now print the form
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "<P align=right><FONT size=1>Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</FONT>\n";
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("grade"). ":</B></P></TD>\n";
+ echo " <TD valign=\"top\">\n";
+
+ // get the appropriate scale
+ $scalenumber=$elements[$i]->scale;
+ $SCALE = (object)$EXERCISE_SCALES[$scalenumber];
+ switch ($SCALE->type) {
+ case 'radio' :
+ // show selections highest first
+ echo "<CENTER><B>$SCALE->start</B> ";
+ for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
+ $checked = false;
+ if (isset($grades[$i]->grade)) {
+ if ($j == $grades[$i]->grade) {
+ $checked = true;
+ }
+ }
+ else { // there's no previous grade so check the lowest option
+ if ($j == 0) {
+ $checked = true;
+ }
+ }
+ if ($checked) {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade_0[$i]\" VALUE=\"$j\" CHECKED> \n";
+ }
+ else {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade_0[$i]\" VALUE=\"$j\"> \n";
+ }
+ }
+ echo " <B>$SCALE->end</B></CENTER>\n";
+ break;
+ case 'selection' :
+ unset($numbers);
+ for ($j = $SCALE->size; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$i]->grade)) {
+ choose_from_menu($numbers, "grade2_0[$i]", $grades[$i]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade2_0[$i]", 0, "");
+ }
+ break;
+
+ echo " </TD>\n";
+ echo "</TR>\n";
+ }
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 2: // error banded grading
+ // now run through the elements
+ $error = 0;
+ for ($i=0; $i < count($elements) - 1; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "<P align=right><FONT size=1>Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</FONT>\n";
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("grade"). ":</B></P></TD>\n";
+ echo " <TD valign=\"top\">\n";
+
+ // get the appropriate scale - yes/no scale (0)
+ $SCALE = (object) $EXERCISE_SCALES[0];
+ switch ($SCALE->type) {
+ case 'radio' :
+ // show selections highest first
+ echo "<CENTER><B>$SCALE->start</B> ";
+ for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
+ $checked = false;
+ if (isset($grades[$i]->grade)) {
+ if ($j == $grades[$i]->grade) {
+ $checked = true;
+ }
+ }
+ else { // there's no previous grade so check the lowest option
+ if ($j == 0) {
+ $checked = true;
+ }
+ }
+ if ($checked) {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade_0[$i]\" VALUE=\"$j\" CHECKED> \n";
+ }
+ else {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade_0[$i]\" VALUE=\"$j\"> \n";
+ }
+ }
+ echo " <B>$SCALE->end</B></CENTER>\n";
+ break;
+ case 'selection' :
+ unset($numbers);
+ for ($j = $SCALE->size; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$i]->grade)) {
+ choose_from_menu($numbers, "grade_0[$i]", $grades[$i]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade_0[$i]", 0, "");
+ }
+ break;
+ }
+
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[$i]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ if (isset($grades[$i]->feedback)) {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ }
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ if (empty($grades[$i]->grade)) {
+ $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
+ }
+ }
+ // print the number of negative elements
+ // echo "<TR><TD>".get_string("numberofnegativeitems", "exercise")."</TD><TD>$negativecount</TD></TR>\n";
+ // echo "<TR valign=top>\n";
+ // echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TABLE></CENTER>\n";
+ // now print the grade table
+ echo "<P><CENTER><B>".get_string("gradetable","exercise")."</B></CENTER>\n";
+ echo "<CENTER><TABLE cellpadding=5 border=1><TR><TD ALIGN=\"CENTER\">".
+ get_string("numberofnegativeresponses", "exercise");
+ echo "</TD><TD>". get_string("suggestedgrade", "exercise")."</TD></TR>\n";
+ for ($i=0; $i<=$exercise->nelements; $i++) {
+ if ($i == intval($error + 0.5)) {
+ echo "<TR><TD ALIGN=\"CENTER\"><IMG SRC=\"../../pix/t/right.gif\"> $i</TD><TD ALIGN=\"CENTER\">{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ else {
+ echo "<TR><TD ALIGN=\"CENTER\">$i</TD><TD ALIGN=\"CENTER\">{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ }
+ echo "</TABLE></CENTER>\n";
+ echo "<P><CENTER><TABLE cellpadding=5 border=1><TR><TD align=\"right\"><b>".
+ get_string("optionaladjustment", "exercise")."</b></TD><TD>\n";
+ unset($numbers);
+ for ($j = 20; $j >= -20; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$exercise->nelements]->grade)) {
+ choose_from_menu($numbers, "grade_0[$exercise->nelements]", $grades[$exercise->nelements]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade_0[$exercise->nelements]", 0, "");
+ }
+ echo "</TD></TR>\n";
+ break;
+
+ case 3: // criteria grading
+ echo "<TR valign=top>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>". get_string("criterion","exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>".get_string("select", "exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>".get_string("suggestedgrade", "exercise")."</B></TD>\n";
+ // find which criteria has been selected (saved in the zero element), if any
+ if (isset($grades[0]->grade)) {
+ $selection = $grades[0]->grade;
+ }
+ else {
+ $selection = 0;
+ }
+ // now run through the elements
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD>$iplus1</TD><TD>".text_to_html($elements[$i]->description)."</TD>\n";
+ if ($selection == $i) {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade_0[0]\" VALUE=\"$i\" CHECKED></TD>\n";
+ }
+ else {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade_0[0]\" VALUE=\"$i\"></TD>\n";
+ }
+ echo "<TD align=center>{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ echo "</TABLE></CENTER>\n";
+ echo "<P><CENTER><TABLE cellpadding=5 border=1><TR><TD align=\"right\"><b>".
+ get_string("optionaladjustment", "exercise")."</b></TD><TD>\n";
+ unset($numbers);
+ for ($j = 20; $j >= -20; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[1]->grade)) {
+ choose_from_menu($numbers, "grade_0[1]", $grades[1]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[1]", 0, "");
+ }
+ echo "</TD></TR>\n";
+ break;
+
+ case 4: // rubric grading
+ // now run through the elements...
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=\"top\">\n";
+ echo "<TD align=\"right\"><b>".get_string("element", "exercise")." $iplus1:</b></TD>\n";
+ echo "<TD>".text_to_html($elements[$i]->description).
+ "<P align=\"right\"><font size=\"1\">Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font></TD></tr>\n";
+ echo "<TR valign=\"top\">\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\" align=\"center\"><B>".get_string("select", "exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>". get_string("criterion","exercise")."</B></TD></tr>\n";
+ if (isset($grades[$i])) {
+ $selection = $grades[$i]->grade;
+ } else {
+ $selection = 0;
+ }
+ // ...and the rubrics
+ if ($rubricsraw = get_records_select("exercise_rubrics", "exerciseid = $exercise->id AND
+ elementno = $i", "rubricno ASC")) {
+ unset($rubrics);
+ foreach ($rubricsraw as $rubic) {
+ $rubrics[] = $rubic; // to renumber index 0,1,2...
+ }
+ for ($j=0; $j<5; $j++) {
+ if (empty($rubrics[$j]->description)) {
+ break; // out of inner for loop
+ }
+ echo "<TR valign=top>\n";
+ if ($selection == $j) {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade_0[$i]\" VALUE=\"$j\" CHECKED></TD>\n";
+ }else {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade_0[$i]\" VALUE=\"$j\"></TD>\n";
+ }
+ echo "<TD>".text_to_html($rubrics[$j]->description)."</TD>\n";
+ }
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ echo " </td>\n";
+ echo "</tr>\n";
+ echo "<tr valign=\"top\">\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</tr>\n";
+ }
+ }
+ break;
+ } // end of outer switch
+
+ // now get the general comment (present in all types)
+ echo "<tr valign=\"top\">\n";
+ switch ($exercise->gradingstrategy) {
+ case 0:
+ case 1:
+ case 4 : // no grading, accumulative and rubic
+ echo " <td align=\"right\"><P><B>". get_string("generalcomment", "exercise").":</B></P></TD>\n";
+ break;
+ default :
+ echo " <td align=\"right\"><P><B>". get_string("reasonforadjustment", "exercise").":</B></P></TD>\n";
+ }
+ echo " <td>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"generalcomment\" rows=5 cols=75 wrap=\"virtual\">\n";
+ if (isset($assessment->generalcomment)) {
+ echo $assessment->generalcomment;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ if ($assessment) {
+ if (isset($assessment->generalcomment)) {
+ echo text_to_html($assessment->generalcomment);
+ }
+ }
+ else {
+ print_string("yourfeedbackgoeshere", "exercise");
+ }
+ }
+ echo " </td>\n";
+ echo "</tr>\n";
+
+ // the teacher's comment on the assessment
+ // always allow the teacher to change/add their comment and grade if it's not their assessment!
+ if (isteacher($course->id) and ($assessment->userid != $USER->id)) {
+ echo "<tr valign=\"top\">\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".
+ get_string("pleasegradetheassessment", "exercise", "$submissionowner->firstname $submissionowner->lastname").
+ "</b></td>\n";
+ echo "</tr>\n";
+ echo "<tr><td align=\"right\"><b>".get_string("gradeforstudentsassessment", "exercise", $course->student).
+ "</td><td>\n";
+ // set up coment scale
+ for ($i=COMMENTSCALE; $i>=0; $i--) {
+ $num[$i] = $i;
+ }
+ choose_from_menu($num, "gradinggrade", $assessment->gradinggrade, "");
+ echo "</td></tr>\n";
+ echo "<tr valign=\"top\">\n";
+ echo " <td align=\"right\"><p><b>". get_string("teacherscomment", "exercise").":</b></p></td>\n";
+ echo " <td>\n";
+ echo "<textarea name=\"teachercomment\" rows=\"5\" cols=\"75\" wrap=\"virtual\">\n";
+ if (isset($assessment->teachercomment)) {
+ echo $assessment->teachercomment;
+ }
+ echo "</textarea>\n";
+ echo " </td>\n";
+ echo "</tr>\n";
+ }
+ elseif ($assessment->timegraded and (($timenow - $assessment->timegraded) > $CFG->maxeditingtime)) {
+ // now show the teacher's comment (but not the grade) to the student if available...
+ echo "<tr valign=\"top\">\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</tr>\n";
+ echo "<tr valign=top>\n";
+ echo " <td align=\"right\"><p><b>". get_string("teacherscomment", "exercise", $course->teacher).":</b></p></td>\n";
+ echo " <td>\n";
+ echo text_to_html($assessment->teachercomment);
+ echo " </td>\n";
+ echo "</tr>\n";
+ echo "<tr valign=\"top\">\n";
+ echo "<td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </td>\n";
+ echo "</tr>\n";
+ }
+ // ...and close the table
+ echo "</table><br /><hr>\n";
+
+ // ****************************second form******************************************
+ // now print a normal assessment form based on the student's assessment for this submission
+ // and allow the teacher to grade and add comments
+ $studentassessment = $assessment;
+ $allowchanges = true;
+
+ print_heading_with_help(get_string("nowpleasemakeyourownassessment", "exercise",
+ "$submissionowner->firstname $submissionowner->lastname"), "grading", "exercise");
+
+ // is there an existing assessment for the submission
+ if (!$assessment = exercise_get_submission_assessment($submission, $USER)) {
+ // copy student's assessment without the comments for the student's submission
+ $assessment = exercise_copy_assessment($studentassessment, $submission);
+ }
+
+ // only show the grade if grading strategy > 0 and the grade is positive
+ if ($exercise->gradingstrategy and $assessment->grade >= 0) {
+ echo "<CENTER><B>".get_string("thegradeis", "exercise").": ".
+ number_format($assessment->grade * $exercise->grade / 100.0, 2)."% (".
+ get_string("maximumgrade")." ".number_format($exercise->grade, 0)."%)</B></CENTER><BR CLEAR=ALL>\n";
+ }
+
+ echo "<center><table cellpadding=\"2\" border=\"1\">\n";
+ echo "<tr valign=top>\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"><center><b>".get_string("yourassessment", "exercise").
+ "</b></center></td>\n";
+ echo "</tr>\n";
+
+
+ unset($grades);
+ // get any previous grades...
+ if ($gradesraw = get_records_select("exercise_grades", "assessmentid = $assessment->id", "elementno")) {
+ foreach ($gradesraw as $grade) {
+ $grades[] = $grade; // to renumber index 0,1,2...
+ }
+ }
+
+ // determine what sort of grading
+ switch ($exercise->gradingstrategy) {
+ case 0: // no grading
+ // now print the form
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 1: // accumulative grading
+ // now print the form
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "<P align=right><FONT size=1>Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</FONT>\n";
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("grade"). ":</B></P></TD>\n";
+ echo " <TD valign=\"top\">\n";
+
+ // get the appropriate scale
+ $scalenumber=$elements[$i]->scale;
+ $SCALE = (object)$EXERCISE_SCALES[$scalenumber];
+ switch ($SCALE->type) {
+ case 'radio' :
+ // show selections highest first
+ echo "<CENTER><B>$SCALE->start</B> ";
+ for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
+ $checked = false;
+ if (isset($grades[$i]->grade)) {
+ if ($j == $grades[$i]->grade) {
+ $checked = true;
+ }
+ }
+ else { // there's no previous grade so check the lowest option
+ if ($j == 0) {
+ $checked = true;
+ }
+ }
+ if ($checked) {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\" CHECKED> \n";
+ }
+ else {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\"> \n";
+ }
+ }
+ echo " <B>$SCALE->end</B></CENTER>\n";
+ break;
+ case 'selection' :
+ unset($numbers);
+ for ($j = $SCALE->size; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$i]->grade)) {
+ choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[$i]", 0, "");
+ }
+ break;
+
+ echo " </TD>\n";
+ echo "</TR>\n";
+ }
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ }
+ break;
+
+ case 2: // error banded grading
+ // now run through the elements
+ $error = 0;
+ for ($i=0; $i < count($elements) - 1; $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("element","exercise")." $iplus1:</B></P></TD>\n";
+ echo " <TD>".text_to_html($elements[$i]->description);
+ echo "<P align=right><FONT size=1>Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</FONT>\n";
+ echo "</TD></TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("grade"). ":</B></P></TD>\n";
+ echo " <TD valign=\"top\">\n";
+
+ // get the appropriate scale - yes/no scale (0)
+ $SCALE = (object) $EXERCISE_SCALES[0];
+ switch ($SCALE->type) {
+ case 'radio' :
+ // show selections highest first
+ echo "<CENTER><B>$SCALE->start</B> ";
+ for ($j = $SCALE->size - 1; $j >= 0 ; $j--) {
+ $checked = false;
+ if (isset($grades[$i]->grade)) {
+ if ($j == $grades[$i]->grade) {
+ $checked = true;
+ }
+ }
+ else { // there's no previous grade so check the lowest option
+ if ($j == 0) {
+ $checked = true;
+ }
+ }
+ if ($checked) {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\" CHECKED> \n";
+ }
+ else {
+ echo " <INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\"> \n";
+ }
+ }
+ echo " <B>$SCALE->end</B></CENTER>\n";
+ break;
+ case 'selection' :
+ unset($numbers);
+ for ($j = $SCALE->size; $j >= 0; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$i]->grade)) {
+ choose_from_menu($numbers, "grade[$i]", $grades[$i]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[$i]", 0, "");
+ }
+ break;
+ }
+
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[$i]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ if (isset($grades[$i]->feedback)) {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ }
+ echo " </TD>\n";
+ echo "</TR>\n";
+ echo "<TR valign=top>\n";
+ echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TR>\n";
+ if (empty($grades[$i]->grade)) {
+ $error += $EXERCISE_EWEIGHTS[$elements[$i]->weight];
+ }
+ }
+ // print the number of negative elements
+ // echo "<TR><TD>".get_string("numberofnegativeitems", "exercise")."</TD><TD>$negativecount</TD></TR>\n";
+ // echo "<TR valign=top>\n";
+ // echo " <TD COLSPAN=2 BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</TABLE></CENTER>\n";
+ // now print the grade table
+ echo "<P><CENTER><B>".get_string("gradetable","exercise")."</B></CENTER>\n";
+ echo "<CENTER><TABLE cellpadding=5 border=1><TR><TD ALIGN=\"CENTER\">".
+ get_string("numberofnegativeresponses", "exercise");
+ echo "</TD><TD>". get_string("suggestedgrade", "exercise")."</TD></TR>\n";
+ for ($i=0; $i<=$exercise->nelements; $i++) {
+ if ($i == intval($error + 0.5)) {
+ echo "<TR><TD ALIGN=\"CENTER\"><IMG SRC=\"../../pix/t/right.gif\"> $i</TD><TD ALIGN=\"CENTER\">{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ else {
+ echo "<TR><TD ALIGN=\"CENTER\">$i</TD><TD ALIGN=\"CENTER\">{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ }
+ echo "</TABLE></CENTER>\n";
+ echo "<P><CENTER><TABLE cellpadding=5 border=1><TR><TD align=\"right\"><b>".
+ get_string("optionaladjustment", "exercise")."</b></TD><TD>\n";
+ unset($numbers);
+ for ($j = 20; $j >= -20; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[$exercise->nelements]->grade)) {
+ choose_from_menu($numbers, "grade[$exercise->nelements]", $grades[$exercise->nelements]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[$exercise->nelements]", 0, "");
+ }
+ echo "</TD></TR>\n";
+ break;
+
+ case 3: // criteria grading
+ echo "<TR valign=top>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"> </TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>". get_string("criterion","exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>".get_string("select", "exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>".get_string("suggestedgrade", "exercise")."</B></TD>\n";
+ // find which criteria has been selected (saved in the zero element), if any
+ if (isset($grades[0]->grade)) {
+ $selection = $grades[0]->grade;
+ }
+ else {
+ $selection = 0;
+ }
+ // now run through the elements
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=top>\n";
+ echo " <TD>$iplus1</TD><TD>".text_to_html($elements[$i]->description)."</TD>\n";
+ if ($selection == $i) {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[0]\" VALUE=\"$i\" CHECKED></TD>\n";
+ }
+ else {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[0]\" VALUE=\"$i\"></TD>\n";
+ }
+ echo "<TD align=center>{$elements[$i]->maxscore}</TD></TR>\n";
+ }
+ echo "</TABLE></CENTER>\n";
+ echo "<P><CENTER><TABLE cellpadding=5 border=1><TR><TD align=\"right\"><b>".
+ get_string("optionaladjustment", "exercise")."</b></TD><TD>\n";
+ unset($numbers);
+ for ($j = 20; $j >= -20; $j--) {
+ $numbers[$j] = $j;
+ }
+ if (isset($grades[1]->grade)) {
+ choose_from_menu($numbers, "grade[1]", $grades[1]->grade, "");
+ }
+ else {
+ choose_from_menu($numbers, "grade[1]", 0, "");
+ }
+ echo "</TD></TR>\n";
+ break;
+
+ case 4: // rubric grading
+ // now run through the elements...
+ for ($i=0; $i < count($elements); $i++) {
+ $iplus1 = $i+1;
+ echo "<TR valign=\"top\">\n";
+ echo "<TD align=\"right\"><b>".get_string("element", "exercise")." $iplus1:</b></TD>\n";
+ echo "<TD>".text_to_html($elements[$i]->description).
+ "<P align=\"right\"><font size=\"1\">Weight: "
+ .number_format($EXERCISE_EWEIGHTS[$elements[$i]->weight], 2)."</font></TD></tr>\n";
+ echo "<TR valign=\"top\">\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\" align=\"center\"><B>".get_string("select", "exercise")."</B></TD>\n";
+ echo " <TD BGCOLOR=\"$THEME->cellheading2\"><B>". get_string("criterion","exercise")."</B></TD></tr>\n";
+ if (isset($grades[$i])) {
+ $selection = $grades[$i]->grade;
+ } else {
+ $selection = 0;
+ }
+ // ...and the rubrics
+ if ($rubricsraw = get_records_select("exercise_rubrics", "exerciseid = $exercise->id AND
+ elementno = $i", "rubricno ASC")) {
+ unset($rubrics);
+ foreach ($rubricsraw as $rubic) {
+ $rubrics[] = $rubic; // to renumber index 0,1,2...
+ }
+ for ($j=0; $j<5; $j++) {
+ if (empty($rubrics[$j]->description)) {
+ break; // out of inner for loop
+ }
+ echo "<TR valign=top>\n";
+ if ($selection == $j) {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\" CHECKED></TD>\n";
+ }else {
+ echo " <TD align=center><INPUT TYPE=\"RADIO\" NAME=\"grade[$i]\" VALUE=\"$j\"></TD>\n";
+ }
+ echo "<TD>".text_to_html($rubrics[$j]->description)."</TD>\n";
+ }
+ echo "<TR valign=top>\n";
+ echo " <TD align=right><P><B>". get_string("feedback").":</B></P></TD>\n";
+ echo " <TD>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"feedback[]\" rows=3 cols=75 wrap=\"virtual\">\n";
+ if (isset($grades[$i]->feedback)) {
+ echo $grades[$i]->feedback;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ echo text_to_html($grades[$i]->feedback);
+ }
+ echo " </td>\n";
+ echo "</tr>\n";
+ echo "<tr valign=\"top\">\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</tr>\n";
+ }
+ }
+ break;
+ } // end of outer switch
+
+ // now get the general comment (present in all types)
+ echo "<tr valign=\"top\">\n";
+ switch ($exercise->gradingstrategy) {
+ case 0:
+ case 1:
+ case 4 : // no grading, accumulative and rubic
+ echo " <td align=\"right\"><P><B>". get_string("generalcomment", "exercise").":</B></P></TD>\n";
+ break;
+ default :
+ echo " <td align=\"right\"><P><B>". get_string("reasonforadjustment", "exercise").":</B></P></TD>\n";
+ }
+ echo " <td>\n";
+ if ($allowchanges) {
+ echo " <textarea name=\"generalcomment\" rows=5 cols=75 wrap=\"virtual\">\n";
+ if (isset($assessment->generalcomment)) {
+ echo $assessment->generalcomment;
+ }
+ echo "</textarea>\n";
+ }
+ else {
+ if ($assessment) {
+ if (isset($assessment->generalcomment)) {
+ echo text_to_html($assessment->generalcomment);
+ }
+ }
+ else {
+ print_string("yourfeedbackgoeshere", "exercise");
+ }
+ }
+ echo " </td>\n";
+ echo "</tr>\n";
+ echo "<tr valign=\"top\">\n";
+ echo " <td colspan=\"2\" bgcolor=\"$THEME->cellheading2\"> </TD>\n";
+ echo "</tr>\n";
+
+ // ...and close the table and show two buttons...to resubmit or not to resubmit
+ echo "</table>\n";
+ echo "<br /><input type=\"button\" value=\"".get_string("studentnotallowed", "exercise", $course->student)."\"
+ onclick=\"document.assessmentform.submit();\">\n";
+ echo "<input type=\"button\" value=\"".get_string("studentallowedtoresubmit", "exercise", $course->student)."\"
+ onclick=\"document.assessmentform.resubmit.value='1';document.assessmentform.submit();\">\n";
+ echo "</center></form>\n";
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_feedback($course, $submission) {
+ global $CFG, $THEME, $RATING;
+
+ if (! $teacher = get_record("user", "id", $submission->teacher)) {
+ error("Weird exercise error");
+ }
+
+ echo "\n<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=1 ALIGN=CENTER><TR><TD BGCOLOR=#888888>";
+ echo "\n<TABLE BORDER=0 CELLPADDING=3 CELLSPACING=0 VALIGN=TOP>";
+
+ echo "\n<TR>";
+ echo "\n<TD ROWSPAN=3 BGCOLOR=\"$THEME->body\" WIDTH=35 VALIGN=TOP>";
+ print_user_picture($teacher->id, $course->id, $teacher->picture);
+ echo "</TD>";
+ echo "<TD NOWRAP WIDTH=100% BGCOLOR=\"$THEME->cellheading\">$teacher->firstname $teacher->lastname";
+ echo " <FONT SIZE=2><I>".userdate($submission->timemarked)."</I>";
+ echo "</TR>";
+
+ echo "\n<TR><TD WIDTH=100% BGCOLOR=\"$THEME->cellcontent\">";
+
+ echo "<P ALIGN=RIGHT><FONT SIZE=-1><I>";
+ if ($submission->grade) {
+ echo get_string("grade").": $submission->grade";
+ } else {
+ echo get_string("nograde");
+ }
+ echo "</I></FONT></P>";
+
+ echo text_to_html($submission->assessorcomment);
+ echo "</TD></TR></TABLE>";
+ echo "</TD></TR></TABLE>";
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_league_table($exercise) {
+ // print an order table of (student) submissions in grade order, only print the student's best submission when
+ // there are multiple submissions
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Print league table: Course is misconfigured");
+ }
+ $table->head = array (get_string("title", "exercise"), get_string("name"), get_string("grade"));
+ $table->align = array ("left", "left", "center");
+ $table->size = array ("*", "*", "*");
+ $table->cellpadding = 2;
+ $table->cellspacing = 0;
+
+ if ($submissions = exercise_get_student_submissions($exercise, "grade")) {
+ foreach ($submissions as $submission) {
+ if (empty($done[$submission->userid])) {
+ if (!$user = get_record("user", "id", $submission->userid)) {
+ error("Print league table: user not found");
+ }
+ $table->data[] = array(exercise_print_submission_title($exercise, $submission), $user->firstname." ".
+ $user->lastname, number_format($submission->grade * $exercise->grade / 100.0, 1)) ;
+ $done[$submission->userid] = 'ok';
+ }
+ }
+ print_heading(get_string("leaguetable", "exercise"));
+ print_table($table);
+ echo "<br />".get_string("allgradeshaveamaximumof", "exercise", $exercise->grade)."%<br />\n";
+ }
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_submission_assessments($exercise, $submission) {
+ // Returns a list of grades for this submission
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ $str = '';
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) {
+ if (isteacher($exercise->course, $assessment->userid)) {
+ $str .= "[".number_format($assessment->grade * $exercise->grade / 100.0, 0)."%] ";
+ }
+ else { // assessment by student - shouldn't happen!
+ $str .= "{".number_format($assessment->grade * $exercise->grade / 100.0, 0)."%} ";
+ }
+ }
+ }
+ if (!$str) {
+ $str = " "; // be kind to Mozilla browsers!
+ }
+ return $str;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_submission_title($exercise, $submission) {
+ global $CFG;
+
+ if (!$submission->timecreated) { // a "no submission"
+ return $submission->title;
+ }
+
+ $filearea = exercise_file_area_name($exercise, $submission);
+ if ($basedir = exercise_file_area($exercise, $submission)) {
+ if (list($file) = get_directory_list($basedir)) {
+ $icon = mimeinfo("icon", $file);
+ if ($CFG->slasharguments) {
+ $ffurl = "file.php/$filearea/$file";
+ } else {
+ $ffurl = "file.php?file=/$filearea/$file";
+ }
+ return "<IMG SRC=\"$CFG->wwwroot/files/pix/$icon\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"File\">".
+ " <A TARGET=\"uploadedfile\" HREF=\"$CFG->wwwroot/$ffurl\">$submission->title</A>";
+ }
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_tabbed_heading($tabs) {
+// Prints a tabbed heading where one of the tabs highlighted.
+// $tabs is an object with several properties.
+// $tabs->names is an array of tab names
+// $tabs->urls is an array of links
+// $tabs->align is an array of column alignments (defaults to "center")
+// $tabs->size is an array of column sizes
+// $tabs->wrap is an array of "nowrap"s or nothing
+// $tabs->highlight is an index (zero based) of "active" heading .
+// $tabs->width is an percentage of the page (defualts to 80%)
+// $tabs->cellpadding padding on each cell (defaults to 5)
+
+ global $CFG, $THEME;
+
+ if (isset($tabs->names)) {
+ foreach ($tabs->names as $key => $name) {
+ if (!empty($tabs->urls[$key])) {
+ $url =$tabs->urls[$key];
+ if ($tabs->highlight == $key) {
+ $tabcontents[$key] = "<b>$name</b>";
+ } else {
+ $tabcontents[$key] = "<a class= \"dimmed\" href=\"$url\"><b>$name</b></a>";
+ }
+ } else {
+ $tabcontents[$key] = "<b>$name</b>";
+ }
+ }
+ }
+
+ if (empty($tabs->width)) {
+ $tabs->width = "80%";
+ }
+
+ if (empty($tabs->cellpadding)) {
+ $tabs->cellpadding = "5";
+ }
+
+ // print_simple_box_start("center", "$table->width", "#ffffff", 0);
+ echo "<table width=\"$tabs-width\" border=\"0\" valign=\"top\" align=\"center\" ";
+ echo " cellpadding=\"$tabs->cellpadding\" cellspacing=\"0\" class=\"generaltable\">\n";
+
+ if (!empty($tabs->names)) {
+ echo "<tr>";
+ echo "<td class=\"generaltablecell\">".
+ "<img width=\"10\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\"></td>\n";
+ foreach ($tabcontents as $key => $tab) {
+ if (isset($align[$key])) {
+ $alignment = "align=\"$align[$key]\"";
+ } else {
+ $alignment = "align=\"center\"";
+ }
+ if (isset($size[$key])) {
+ $width = "width=\"$size[$key]\"";
+ } else {
+ $width = "";
+ }
+ if (isset($wrap[$key])) {
+ $wrapping = "no wrap";
+ } else {
+ $wrapping = "";
+ }
+ if ($key == $tabs->highlight) {
+ echo "<td valign=top $alignment $width $wrapping bgcolor=\"$THEME->cellheading2\">$tab</td>\n";
+ } else {
+ echo "<td valign=top $alignment $width $wrapping bgcolor=\"$THEME->body\">$tab</td>\n";
+ }
+ echo "<td class=\"generaltablecell\">".
+ "<img width=\"10\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\"></td>\n";
+ }
+ echo "</tr>\n";
+ } else {
+ echo "<tr><td>No names specified</td></tr>\n";
+ }
+ // bottom stripe
+ $ncells = count($tabs->names)*2 +1;
+ $height = 2;
+ echo "<tr><td colspan=\"$ncells\" bgcolor=\"$THEME->cellheading2\">".
+ "<img height=\"$height\" src=\"$CFG->wwwroot/pix/spacer.gif\" alt=\"\"></td></tr>\n";
+ echo "</table>\n";
+ // print_simple_box_end();
+
+ return true;
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_time_to_deadline($time) {
+ if ($time < 0) {
+ $timetext = get_string("afterdeadline", "exercise", format_time($time));
+ return " (<FONT COLOR=RED>$timetext</FONT>)";
+ } else {
+ $timetext = get_string("beforedeadline", "exercise", format_time($time));
+ return " ($timetext)";
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_upload_form($exercise) {
+
+ if (! $course = get_record("course", "id", $exercise->course)) {
+ error("Course is misconfigured");
+ }
+ if (! $cm = get_coursemodule_from_instance("exercise", $exercise->id, $course->id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ echo "<DIV ALIGN=CENTER>";
+ echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"POST\" ACTION=upload.php>";
+ echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$exercise->maxbytes\">";
+ echo " <INPUT TYPE=hidden NAME=id VALUE=\"$cm->id\">";
+ echo "<b>".get_string("title", "exercise")."</b>: <INPUT NAME=\"title\" TYPE=\"text\" SIZE=\"60\" MAXSIZE=\"100\"><BR><BR>\n";
+ echo " <INPUT NAME=\"newfile\" TYPE=\"file\" size=\"50\">";
+ echo " <INPUT TYPE=submit NAME=save VALUE=\"".get_string("uploadthisfile")."\">";
+ echo "</FORM>";
+ echo "</DIV>";
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_print_user_assessments($exercise, $user) {
+ // Returns the number of assessments and a hyperlinked list of grading grades for the assessments made by this user
+
+ if ($assessments = exercise_get_user_assessments($exercise, $user)) {
+ $n = count($assessments);
+ $str = "$n (";
+ foreach ($assessments as $assessment) {
+ if ($assessment->timegraded) {
+ $gradingscaled = intval($assessment->gradinggrade * $exercise->grade / COMMENTSCALE);
+ $str .= "<A HREF=\"assessments.php?action=viewassessment&a=$exercise->id&aid=$assessment->id\">";
+ $str .= "$gradingscaled</A> ";
+ }
+ else {
+ $str .= "<A HREF=\"assessments.php?action=viewassessment&a=$exercise->id&aid=$assessment->id\">";
+ $str .= "-</A> ";
+ }
+ }
+ $str .= ")";
+ }
+ else {
+ $str ="0";
+ }
+ return $str;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_test_for_resubmission($exercise, $user) {
+ // see if any of the user's submissions have the resubmit flag set
+ $result = false;
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ foreach ($submissions as $submission) {
+ if ($submission->resubmit) {
+ $result =true;
+ break;
+ }
+ }
+ }
+ return $result;
+ }
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+function exercise_test_user_assessments($exercise, $user) {
+ // see if user has assessed one of teacher's exercises/submissions...
+ global $CFG;
+
+ $result = false;
+ $timenow =time();
+ if ($submissions = exercise_get_teacher_submissions($exercise)) {
+ foreach ($submissions as $submission) {
+ if ($assessment = exercise_get_submission_assessment($submission, $user)) {
+ // ...the date stamp on the assessment should be in the past
+ if ($assessment->timecreated < $timenow) {
+ $result = true;
+ break;
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+?>
--- /dev/null
+<?php
+ require("$CFG->dirroot/mod/exercise/lib.php"); // for parameter arrays
+ // set the defaults...
+ if ($usehtmleditor = can_use_richtext_editor()) {
+ $defaultformat = FORMAT_HTML;
+ $onsubmit = "onsubmit=\"copyrichtext(document.form.description);\"";
+ } else {
+ $defaultformat = FORMAT_MOODLE;
+ $onsubmit = "";
+ }
+ // ...and fill the form if needed
+ if (empty($form->name)) {
+ $form->name = "";
+ }
+ if (empty($form->gradingstrategy)) {
+ $form->gradingstrategy = 1;
+ }
+ if (empty($form->usemaximum)) {
+ $form->usemaximum = 0;
+ }
+ if (!isset($form->grade)) {
+ $form->grade = 100;
+ }
+ if (!isset($form->nelements)) {
+ $form->nelements = 1;
+ }
+ if (empty($form->maxbytes)) {
+ $form->maxbytes = "";
+ }
+ if (empty($form->deadline)) {
+ $form->deadline = "";
+ }
+?>
+
+<form name="form" method="post" <?php echo $onsubmit ?> action="mod.php">
+<table cellpadding=5>
+<tr valign=top>
+ <td align=right width=\"50%\"><P><B><?php print_string("title", "exercise") ?>:</B></P></TD>
+ <td width=\"50%\">
+ <input type="text" name="name" size=60 value="<?php p($form->name) ?>">
+ </td>
+</tr>
+<tr valign=top>
+ <td align=right><P><B><?php print_string("description", "exercise") ?>:</B></P></TD>
+ <td>
+ <?php
+ echo get_string("descriptionofexercise", "exercise", $course->students);
+ ?>
+ </td>
+</tr>
+
+<tr valign=top>
+ <td align=right><P><B><?php print_string("maximumgrade") ?>:</B></P></TD>
+ <td>
+ <?php
+ for ($i=100; $i>=0; $i--) {
+ $grades[$i] = $i;
+ }
+ choose_from_menu($grades, "grade", "$form->grade", "");
+ helpbutton("grade", get_string("maximumgrade", "exercise"), "exercise");
+ ?>
+ </td>
+</tr>
+
+<tr valign=top>
+ <td align=right><P><B><?php print_string("gradingstrategy", "exercise") ?>:</B></P></TD>
+ <td>
+ <?php
+ choose_from_menu($EXERCISE_TYPE, "gradingstrategy", $form->gradingstrategy, "");
+ helpbutton("gradingstrategy", get_string("gradingstrategy", "exercise"), "exercise");
+ ?>
+ </td>
+</tr>
+
+<tr>
+ <td align=right><P><B><?php print_string("handlingofmultiplesubmissions", "exercise") ?>:</B></P></TD>
+ <td>
+ <?php
+ $options[0] = get_string("usemean", "exercise"); $options[1] = get_string("usemaximum", "exercise");
+ choose_from_menu($options, "usemaximum", $form->usemaximum, "");
+ helpbutton("usemax", get_string("handlingofmultiplesubmissions", "exercise"), "exercise");
+ ?>
+ </td>
+</tr>
+
+<tr valign=top>
+ <td align=right><P><B><?php print_string("numberofassessmentelements", "exercise") ?>:</B></P></TD>
+ <td valign="middle">
+ <?php
+ for ($i=20; $i>=0; $i--) {
+ $numbers[$i] = $i;
+ }
+ choose_from_menu($numbers, "nelements", "$form->nelements", "");
+ helpbutton("nelements", get_string("numberofassessmentelements", "exercise"), "exercise");
+ ?>
+ </td>
+</tr>
+
+<tr valign=top>
+ <td align=right><P><B><?php print_string("maximumsize", "exercise") ?>:</B></P></TD>
+ <td>
+ <?php
+ $sizelist = array("10Kb", "50Kb", "100Kb", "500Kb", "1Mb", "2Mb", "5Mb", "10Mb", "20Mb", "50Mb");
+ $maxsize = get_max_upload_file_size();
+ $sizeinlist = false;
+ foreach ($sizelist as $size) {
+ $sizebytes = get_real_size($size);
+ if ($sizebytes < $maxsize) {
+ $filesize[$sizebytes] = $size;
+ }
+ if ($form->maxbytes == $sizebytes) {
+ $sizeinlist = true;
+ }
+ }
+ $filesize[$maxsize] = display_size($maxsize);
+ if (!$sizeinlist) {
+ $form->maxbytes = get_real_size("500K");
+ }
+ ksort($filesize, SORT_NUMERIC);
+ choose_from_menu($filesize, "maxbytes", "$form->maxbytes", "");
+ ?>
+ </td>
+</tr>
+
+<tr valign=top>
+ <td align=right><P><B><?php print_string("deadline", "exercise") ?>:</B></td>
+ <td><?php
+ print_date_selector("deadlineday", "deadlinemonth", "deadlineyear", $form->deadline);
+ echo " - ";
+ print_time_selector("deadlinehour", "deadlineminute", $form->deadline);
+ ?></td>
+</tr>
+
+</table>
+<BR>
+<CENTER>
+<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="submit" value="<?php print_string("savechanges") ?>">
+<input type="submit" name=cancel value="<?php print_string("cancel") ?>">
+<p>
+<p><?PHP notify(get_string("noteonassessmentelements", "exercise")); ?>
+
+</CENTER>
+</FORM>
+
+<?php
+ if ($usehtmleditor) {
+ print_richedit_javascript("form", "description", "no");
+ }
+?>
+
--- /dev/null
+<?PHP //$Id$
+ //This php script contains all the stuff to backup/restore
+ //exercise mods
+
+ //This is the "graphical" structure of the exercise mod:
+ //
+ // exercise
+ // (CL,pk->id)
+ // |
+ // |
+ // |
+ // |------------------------------|---------------------------------------------|
+ // | |
+ // | |
+ // | exercise_submissions
+ // | (UL,pk->id,fk->exerciseid,files)
+ // | |
+ // | |
+ // | |
+ // | |---------------------| |------------------------------| |
+ // | | | | | |
+ // exercise_elements exercise_grades exercise_assessments
+ // (CL,pk->id,fk->exerciseid) (UL,pk->id,fk->assessmentid) (UL,pk->id,fk->submissionid)
+ // | ( fk->elementno )
+ // |
+ // |
+ // exercise_rubrics
+ // (CL,pk->id,fk->elementno)
+ //
+ // Meaning: pk->primary key field of the table
+ // fk->foreign key to link with parent
+ // nt->nested field (recursive data)
+ // CL->course level info
+ // UL->user level info
+ // files->table may have files)
+ //
+ //-----------------------------------------------------------
+
+ //This function executes all the restore procedure about this mod
+ function exercise_restore_mods($mod,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //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;
+ //traverse_xmlize($info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //Now, build the exercise record structure
+ $exercise->course = $restore->course_id;
+ $exercise->name = backup_todb($info['MOD']['#']['NAME']['0']['#']);
+ $exercise->nelements = backup_todb($info['MOD']['#']['NELEMENTS']['0']['#']);
+ $exercise->phase = backup_todb($info['MOD']['#']['PHASE']['0']['#']);
+ $exercise->gradingstrategy = backup_todb($info['MOD']['#']['GRADINGSTRATEGY']['0']['#']);
+ $exercise->usemaximum = backup_todb($info['MOD']['#']['USEMAXIMUM']['0']['#']);
+ $exercise->anonymous = backup_todb($info['MOD']['#']['ANONYMOUS']['0']['#']);
+ $exercise->maxbytes = backup_todb($info['MOD']['#']['MAXBYTES']['0']['#']);
+ $exercise->deadline = backup_todb($info['MOD']['#']['DEADLINE']['0']['#']);
+ $exercise->grade = backup_todb($info['MOD']['#']['GRADE']['0']['#']);
+ $exercise->timemodified = backup_todb($info['MOD']['#']['TIMEMODIFIED']['0']['#']);
+ $exercise->teacherweight = backup_todb($info['MOD']['#']['TEACHERWEIGHT']['0']['#']);
+ $exercise->gradingweight = backup_todb($info['MOD']['#']['GRADINGWEIGHT']['0']['#']);
+ $exercise->showleaguetable = backup_todb($info['MOD']['#']['SHOWLEAGUETABLE']['0']['#']);
+
+ //The structure is equal to the db, so insert the exercise
+ $newid = insert_record ("exercise",$exercise);
+
+ //Do some output
+ echo "<ul><li>".get_string("modulename","exercise")." \"".$exercise->name."\"<br>";
+ backup_flush(300);
+
+ if ($newid) {
+ //We have the newid, update backup_ids
+ backup_putid($restore->backup_unique_code,$mod->modtype,
+ $mod->id, $newid);
+ //We have to restore the exercise_elements table now (course level table)
+ $status = exercise_elements_restore_mods($newid,$info,$restore);
+ //Now check if want to restore user data and do it.
+ if ($restore->mods['exercise']->userinfo) {
+ //Restore exercise_submissions
+ $status = exercise_submissions_restore_mods ($mod->id, $newid,$info,$restore);
+ }
+ } else {
+ $status = false;
+ }
+
+ //Finalize ul
+ echo "</ul>";
+
+ } else {
+ $status = false;
+ }
+
+ return $status;
+ }
+
+ //This function restores the exercise_elements
+ function exercise_elements_restore_mods($exercise_id,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the exercise_elements array
+ $elements = $info['MOD']['#']['ELEMENTS']['0']['#']['ELEMENT'];
+
+ //Iterate over exercise_elements
+ for($i = 0; $i < sizeof($elements); $i++) {
+ $ele_info = $elements[$i];
+ //traverse_xmlize($ele_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //Now, build the exercise_ELEMENTS record structure
+ $element->exerciseid = $exercise_id;
+ $element->elementno = backup_todb($ele_info['#']['ELEMENTNO']['0']['#']);
+ $element->description = backup_todb($ele_info['#']['DESCRIPTION']['0']['#']);
+ $element->scale = backup_todb($ele_info['#']['SCALE']['0']['#']);
+ $element->maxscore = backup_todb($ele_info['#']['MAXSCORE']['0']['#']);
+ $element->weight = backup_todb($ele_info['#']['WEIGHT']['0']['#']);
+
+ //The structure is equal to the db, so insert the exercise_elements
+ $newid = insert_record ("exercise_elements",$element);
+
+ //Do some output
+ if (($i+1) % 10 == 0) {
+ echo ".";
+ if (($i+1) % 200 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+
+ if ($newid) {
+ //We have to restore the exercise_rubrics table now (course level table)
+ $status = exercise_rubrics_restore_mods($exercise_id,$element->elementno,$ele_info,$restore);
+ } else {
+ $status = false;
+ }
+ }
+
+ return $status;
+ }
+
+
+ //This function restores the exercise_rubrics
+ function exercise_rubrics_restore_mods($exercise_id,$elementno,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the exercise_rubrics array
+ $rubrics = $info['#']['RUBRICS']['0']['#']['RUBRIC'];
+
+ //Iterate over exercise_rubrics
+ for($i = 0; $i < sizeof($rubrics); $i++) {
+ $rub_info = $rubrics[$i];
+ //traverse_xmlize($rub_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //Now, build the exercise_RUBRICS record structure
+ $rubric->exerciseid = $exercise_id;
+ $rubric->elementno = $elementno;
+ $rubric->rubricno = backup_todb($rub_info['#']['RUBRICNO']['0']['#']);
+ $rubric->description = backup_todb($rub_info['#']['DESCRIPTION']['0']['#']);
+
+ //The structure is equal to the db, so insert the exercise_rubrics
+ $newid = insert_record ("exercise_rubrics",$rubric);
+
+ //Do some output
+ if (($i+1) % 10 == 0) {
+ echo ".";
+ if (($i+1) % 200 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+
+ if (!$newid) {
+ $status = false;
+ }
+ }
+ return $status;
+ }
+
+
+ //This function restores the exercise_submissions
+ function exercise_submissions_restore_mods($old_exercise_id, $new_exercise_id,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the submissions array
+ $submissions = $info['MOD']['#']['SUBMISSIONS']['0']['#']['SUBMISSION'];
+
+ //Iterate over submissions
+ for($i = 0; $i < sizeof($submissions); $i++) {
+ $sub_info = $submissions[$i];
+ //traverse_xmlize($sub_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //We'll need this later!!
+ $oldid = backup_todb($sub_info['#']['ID']['0']['#']);
+ $olduserid = backup_todb($sub_info['#']['USERID']['0']['#']);
+
+ //Now, build the exercise_SUBMISSIONS record structure
+ $submission->exerciseid = $new_exercise_id;
+ $submission->userid = backup_todb($sub_info['#']['USERID']['0']['#']);
+ $submission->title = backup_todb($sub_info['#']['TITLE']['0']['#']);
+ $submission->timecreated = backup_todb($sub_info['#']['TIMECREATED']['0']['#']);
+ $submission->resubmit = backup_todb($sub_info['#']['RESUBMIT']['0']['#']);
+ $submission->mailed = backup_todb($sub_info['#']['MAILED']['0']['#']);
+ $submission->isexercise = backup_todb($sub_info['#']['ISEXERCISE']['0']['#']);
+
+ //We have to recode the userid field
+ $user = backup_getid($restore->backup_unique_code,"user",$olduserid);
+ if ($user) {
+ $submission->userid = $user->new_id;
+ }
+
+ //The structure is equal to the db, so insert the exercise_submission
+ $newid = insert_record ("exercise_submissions",$submission);
+
+ //Do some output
+ if (($i+1) % 50 == 0) {
+ echo ".";
+ if (($i+1) % 1000 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+
+ if ($newid) {
+ //We have the newid, update backup_ids
+ backup_putid($restore->backup_unique_code,"exercise_submissions",$oldid,
+ $newid);
+
+ //Now copy moddata associated files
+ $status = exercise_restore_files ($oldid, $newid,$restore);
+ //Now we need to restore exercise_assessments (user level table)
+ if ($status) {
+ $status = exercise_assessments_restore_mods ($new_exercise_id, $newid,$sub_info,$restore);
+ }
+ } else {
+ $status = false;
+ }
+ }
+
+ return $status;
+ }
+
+ //This function restores the exercise_assessments
+ function exercise_assessments_restore_mods($new_exercise_id, $new_submission_id,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the assessments array
+ $assessments = $info['#']['ASSESSMENTS']['0']['#']['ASSESSMENT'];
+
+ //Iterate over assessments
+ for($i = 0; $i < sizeof($assessments); $i++) {
+ $ass_info = $assessments[$i];
+ //traverse_xmlize($ass_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //We'll need this later!!
+ $oldid = backup_todb($ass_info['#']['ID']['0']['#']);
+ $olduserid = backup_todb($ass_info['#']['USERID']['0']['#']);
+
+ //Now, build the exercise_ASSESSMENTS record structure
+ $assessment->exerciseid = $new_exercise_id;
+ $assessment->submissionid = $new_submission_id;
+ $assessment->userid = backup_todb($ass_info['#']['USERID']['0']['#']);
+ $assessment->timecreated = backup_todb($ass_info['#']['TIMECREATED']['0']['#']);
+ $assessment->timegraded = backup_todb($ass_info['#']['TIMEGRADED']['0']['#']);
+ $assessment->grade = backup_todb($ass_info['#']['GRADE']['0']['#']);
+ $assessment->gradinggrade = backup_todb($ass_info['#']['GRADINGGRADE']['0']['#']);
+ $assessment->mailed = backup_todb($ass_info['#']['MAILED']['0']['#']);
+ $assessment->generalcomment = backup_todb($ass_info['#']['GENERALCOMMENT']['0']['#']);
+ $assessment->teachercomment = backup_todb($ass_info['#']['TEACHERCOMMENT']['0']['#']);
+
+ //We have to recode the userid field
+ $user = backup_getid($restore->backup_unique_code,"user",$olduserid);
+ if ($user) {
+ $assessment->userid = $user->new_id;
+ }
+
+ //The structure is equal to the db, so insert the exercise_assessment
+ $newid = insert_record ("exercise_assessments",$assessment);
+
+ //Do some output
+ if (($i+1) % 50 == 0) {
+ echo ".";
+ if (($i+1) % 1000 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+
+ if ($newid) {
+ //We have the newid, update backup_ids
+ backup_putid($restore->backup_unique_code,"exercise_assessments",$oldid,
+ $newid);
+
+ //Now we need to restore exercise_grades (user level table)
+ if ($status) {
+ $status = exercise_grades_restore_mods ($new_exercise_id, $newid,$ass_info,$restore);
+ }
+ } else {
+ $status = false;
+ }
+ }
+
+ return $status;
+ }
+
+ //This function restores the exercise_grades
+ function exercise_grades_restore_mods($new_exercise_id, $new_assessment_id,$info,$restore) {
+
+ global $CFG;
+
+ $status = true;
+
+ //Get the grades array
+ $grades = $info['#']['GRADES']['0']['#']['GRADE'];
+
+ //Iterate over grades
+ for($i = 0; $i < sizeof($grades); $i++) {
+ $gra_info = $grades[$i];
+ //traverse_xmlize($gra_info); //Debug
+ //print_object ($GLOBALS['traverse_array']); //Debug
+ //$GLOBALS['traverse_array']=""; //Debug
+
+ //Now, build the exercise_GRADES record structure
+ $grade->exerciseid = $new_exercise_id;
+ $grade->assessmentid = $new_assessment_id;
+ $grade->elementno = backup_todb($gra_info['#']['ELEMENTNO']['0']['#']);
+ $grade->feedback = backup_todb($gra_info['#']['FEEDBACK']['0']['#']);
+ $grade->grade = backup_todb($gra_info['#']['GRADE_VALUE']['0']['#']);
+
+ //The structure is equal to the db, so insert the exercise_grade
+ $newid = insert_record ("exercise_grades",$grade);
+
+ //Do some output
+ if (($i+1) % 50 == 0) {
+ echo ".";
+ if (($i+1) % 1000 == 0) {
+ echo "<br>";
+ }
+ backup_flush(300);
+ }
+
+ if (!$newid) {
+ $status = false;
+ }
+ }
+
+ return $status;
+ }
+
+ //This function copies the exercise related info from backup temp dir to course moddata folder,
+ //creating it if needed and recoding everything (submission_id)
+ function exercise_restore_files ($oldsubmiss, $newsubmiss, $restore) {
+
+ global $CFG;
+
+ $status = true;
+ $todo = false;
+ $moddata_path = "";
+ $exercise_path = "";
+ $temp_path = "";
+
+ //First, we check to "course_id" exists and create is as necessary
+ //in CFG->dataroot
+ $dest_dir = $CFG->dataroot."/".$restore->course_id;
+ $status = check_dir_exists($dest_dir,true);
+
+ //Now, locate course's moddata directory
+ $moddata_path = $CFG->dataroot."/".$restore->course_id."/".$CFG->moddata;
+
+ //Check it exists and create it
+ $status = check_dir_exists($moddata_path,true);
+
+ //Now, locate exercise directory
+ if ($status) {
+ $exercise_path = $moddata_path."/exercise";
+ //Check it exists and create it
+ $status = check_dir_exists($exercise_path,true);
+ }
+
+ //Now locate the temp dir we are gong to restore
+ if ($status) {
+ $temp_path = $CFG->dataroot."/temp/backup/".$restore->backup_unique_code.
+ "/moddata/exercise/".$oldsubmiss;
+ //Check it exists
+ if (is_dir($temp_path)) {
+ $todo = true;
+ }
+ }
+
+ //If todo, we create the neccesary dirs in course moddata/exercise
+ if ($status and $todo) {
+ //First this exercise id
+ $this_exercise_path = $exercise_path."/".$newsubmiss;
+ $status = check_dir_exists($this_exercise_path,true);
+ //And now, copy temp_path to this_exercise_path
+ $status = backup_copy_file($temp_path, $this_exercise_path);
+ }
+
+ return $status;
+ }
+?>
--- /dev/null
+<?PHP // $Id: submissions.php,v 1.0 22 Aug 2003
+
+/*************************************************
+ ACTIONS handled are:
+
+ adminamendtitle
+ adminconfirmdelete
+ admindelete
+ adminlist
+ displayfinalgrades (teachers only)
+ listforassessmentstudent
+ listforassessmentteacher
+ saveweights
+ userconfirmdelete
+ userdelete
+
+
+************************************************/
+
+ require("../../config.php");
+ require("lib.php");
+ require("version.php");
+
+ require_variable($id); // Course Module ID
+
+ // get some essential stuff...
+ if (! $cm = get_record("course_modules", "id", $id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if (! $course = get_record("course", "id", $cm->course)) {
+ error("Course is misconfigured");
+ }
+
+ if (! $exercise = get_record("exercise", "id", $cm->instance)) {
+ error("Course module is incorrect");
+ }
+
+ require_login($course->id);
+
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+ $strsubmissions = get_string("submissions", "exercise");
+
+ // ... print the header and...
+ print_header("$course->shortname: $exercise->name", "$course->fullname",
+ "$navigation <A HREF=index.php?id=$course->id>$strexercises</A> ->
+ <A HREF=\"view.php?id=$cm->id\">$exercise->name</A> -> $strsubmissions",
+ "", "", true);
+
+ //...get the action!
+ require_variable($action);
+
+
+ /******************* admin amend title ************************************/
+ if ($action == 'adminamendtitle' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_GET['sid'])) {
+ error("Admin Amend Title: submission id missing");
+ }
+
+ $submission = get_record("exercise_submissions", "id", $_GET['sid']);
+ print_heading(get_string("amendtitle", "exercise"));
+ ?>
+ <form name="amendtitleform" action="submissions.php" method="post">
+ <input type="hidden" name="action" value="adminupdatetitle">
+ <input type="hidden" name="id" value="<?PHP echo $cm->id ?>">
+ <input type="hidden" name="sid" value="<?PHP echo $_REQUEST['sid'] ?>">
+ <center>
+ <table celpadding="5" border="1">
+ <?PHP
+
+ // now get the comment
+ echo "<tr valign=\"top\">\n";\r
+ echo " <td align=\"right\"><P><B>". get_string("title", "exercise").":</b></p></td>\n";\r
+ echo " <td>\n";\r
+ echo " <input type=\"text\" name=\"title\" size=\"60\" maxlength=\"100\" value=\"$submission->title\">\n";
+ echo " </td></tr></table>\n";
+ echo "<input type=submit VALUE=\"".get_string("amendtitle", "exercise")."\">\n";
+ echo "</center></form>\n";
+
+ }
+
+
+ /******************* admin confirm delete ************************************/
+ elseif ($action == 'adminconfirmdelete' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_GET['sid'])) {
+ error("Admin confirm delete: submission id missing");
+ }
+
+ notice_yesno(get_string("confirmdeletionofthisitem","exercise", get_string("submission", "exercise")),
+ "submissions.php?action=admindelete&id=$cm->id&sid=$_GET[sid]", "submissions.php?id=$cm->id&action=adminlist");
+ }
+
+
+ /******************* admin delete ************************************/
+ elseif ($action == 'admindelete' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_GET['sid'])) {
+ error("Admin delete: submission id missing");
+ }
+
+ if (!$submission = get_record("exercise_submissions", "id", $_GET['sid'])) {
+ error("Admin delete: can not get submission record");
+ }
+ print_string("deleting", "exercise");
+ // first get any assessments...
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach($assessments as $assessment) {
+ // ...and all the associated records...
+ delete_records("exercise_grades", "assessmentid", $assessment->id);
+ echo ".";
+ }
+ // ...now delete the assessments...
+ delete_records("exercise_assessments", "submissionid", $submission->id);
+ }
+ // ...and the submission record...
+ delete_records("exercise_submissions", "id", $submission->id);
+ // ..and finally the submitted file
+ exercise_delete_submitted_files($exercise, $submission);
+
+ print_continue("submissions.php?id=$cm->id&action=adminlist");
+ }
+
+
+ /******************* list all submissions ************************************/
+ elseif ($action == 'adminlist' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_GET['order'])) {
+ $order = "name";
+ }
+ else {
+ $order = $_GET['order'];
+ }
+
+ echo "<p><small>Exercise Version-> $module->version</small></p>";
+ exercise_list_submissions_for_admin($exercise, $order);
+ print_continue("view.php?id=$cm->id");
+
+ }
+
+
+ /******************* admin update title ************************************/
+ elseif ($action == 'adminupdatetitle' ) {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+ if (empty($_POST['sid'])) {
+ error("Admin Update Title: submission id missing");
+ }
+
+ if (set_field("exercise_submissions", "title", $_POST['title'], "id", $_POST['sid'])) {
+ print_heading(get_string("amendtitle", "exercise")." ".get_string("ok"));
+ }
+ print_continue("submissions.php?id=$cm->id&action=adminlist");
+ }
+
+
+ /*************** display final grades (by teacher) ***************************/
+ elseif ($action == 'displayfinalgrades') {
+ // Get all the students
+ if (!$users = get_course_students($course->id, "u.firstname, u.lastname")) {
+ print_heading(get_string("nostudentsyet"));
+ print_footer($course);
+ exit;
+ }
+
+ // get the final weights from the database
+ $teacherweight = get_field("exercise","teacherweight", "id", $exercise->id);
+ $gradingweight = get_field("exercise","gradingweight", "id", $exercise->id);
+ // show the final grades as stored in the tables...
+ print_heading_with_help(get_string("displayoffinalgrades", "exercise"), "finalgrades", "exercise");
+ echo "<center><table border=\"1\" width=\"90%\"><tr>\n";
+ echo "<td bgcolor=\"$THEME->cellheading2\"><b>".$course->student."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\"><b>".get_string("submission", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".get_string("gradeforassessment", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".get_string("gradeforsubmission", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".get_string("overallgrade", "exercise")."</b></td></TR>\n";
+ // now the weights
+ echo "<tr><td bgcolor=\"$THEME->cellheading2\"><b>".get_string("weights", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\"><b> </b></td>\n";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>$EXERCISE_FWEIGHTS[$gradingweight]</b></td>\n";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>$EXERCISE_FWEIGHTS[$teacherweight]</b></td>\n";
+ echo "<td bgcolor=\"$THEME->cellheading2\"><b> </b></td></tr>\n";
+ foreach ($users as $user) {
+ // first get user's own assessment reord, it should contain their grading grade
+ if ($ownassessments = exercise_get_user_assessments($exercise, $user)) {
+ foreach ($ownassessments as $ownassessment) {
+ break; // there should only be one
+ }
+ }
+ else {
+ $ownassessment->gradinggrade = 0;
+ }
+ if ($submissions = exercise_get_user_submissions($exercise, $user)) {
+ foreach ($submissions as $submission) {
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) { // (normally there should only be one
+ echo "<tr><td>$user->firstname $user->lastname</td>\n";
+ echo "<td>".exercise_print_submission_title($exercise, $submission)."</td>\n";
+ echo "<td align=\"center\">".number_format($ownassessment->gradinggrade * $exercise->grade / COMMENTSCALE, 1)."</td>";
+ echo "<td align=\"center\">".number_format($assessment->grade * $exercise->grade / 100.0, 1)."</td>";
+ echo "<td align=\"center\">". number_format(((($assessment->grade * $EXERCISE_FWEIGHTS[$teacherweight]
+ / 100.0) + ($ownassessment->gradinggrade * $EXERCISE_FWEIGHTS[$gradingweight]
+ / COMMENTSCALE )) * $exercise->grade) /
+ ($EXERCISE_FWEIGHTS[$teacherweight] + $EXERCISE_FWEIGHTS[$gradingweight]), 1).
+ "</td></tr>\n";
+ }
+ }
+ }
+ }
+ }
+ echo "</table><br clear=\"all\">\n";
+ exercise_print_league_table($exercise);
+ echo "<br \>".get_string("allgradeshaveamaximumof", "exercise", $exercise->grade)."%\n";
+ print_continue("view.php?id=$cm->id");
+ }\r
+
+
+ /******************* list for assessment student (submissions) ************************************/
+ elseif ($action == 'listforassessmentstudent' ) {
+ if (!$users = get_course_students($course->id)) {
+ print_heading(get_string("nostudentsyet"));
+ print_footer($course);
+ exit;
+ }
+ exercise_list_unassessed_student_submissions($exercise, $USER);
+ print_continue("view.php?id=$cm->id");
+
+ }
+
+
+ /******************* list for assessment teacher (submissions) ************************************/
+ elseif ($action == 'listforassessmentteacher' ) {
+ if (!$users = get_course_students($course->id)) {
+ print_heading(get_string("nostudentsyet"));
+ print_footer($course);
+ exit;
+ }
+ exercise_list_unassessed_teacher_submissions($exercise, $USER);
+ print_continue("view.php?id=$cm->id");
+
+ }
+
+
+ /*************** save weights (by teacher) ***************************/
+ elseif ($action == 'saveweights') {
+
+ $form = (object)$_POST;
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ // save the weights from the form...
+ if (isset($form->teacherweight)) {
+ $teacherweight = $form->teacherweight;
+ // ...and save them
+ set_field("exercise", "teacherweight", $teacherweight, "id", "$exercise->id");
+ }
+
+ if (isset($form->gradingweight)) {
+ $gradingweight = $form->gradingweight;
+ // ...and save them
+ set_field("exercise", "gradingweight", $gradingweight, "id", "$exercise->id");
+ }
+
+ redirect("submissions.php?id=$cm->id&action=adminlist", get_string("weightssaved", "exercise"));
+ }
+
+
+ /******************* user confirm delete ************************************/
+ elseif ($action == 'userconfirmdelete' ) {
+
+ if (empty($_GET['sid'])) {
+ error("User Confirm Delete: submission id missing");
+ }
+
+ notice_yesno(get_string("confirmdeletionofthisitem","exercise", get_string("submission", "exercise")),
+ "submissions.php?action=userdelete&id=$cm->id&sid=$_GET[sid]", "view.php?id=$cm->id");
+ }
+
+
+ /******************* user delete ************************************/
+ elseif ($action == 'userdelete' ) {
+
+ if (empty($_GET['sid'])) {
+ error("User Delete: submission id missing");
+ }
+
+ if (!$submission = get_record("exercise_submissions", "id", $_GET['sid'])) {
+ error("User Delete: can not get submission record");
+ }
+ print_string("deleting", "exercise");
+ // first get any assessments...
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach($assessments as $assessment) {
+ // ...and all the associated records...
+ delete_records("exercise_grades", "assessmentid", $assessment->id);
+ echo ".";
+ }
+ // ...now delete the assessments...
+ delete_records("exercise_assessments", "submissionid", $submission->id);
+ }
+ // ...and the submission record...
+ delete_records("exercise_submissions", "id", $submission->id);
+ // ..and finally the submitted file
+ exercise_delete_submitted_files($exercise, $submission);
+
+ print_continue("view.php?id=$cm->id");
+ }
+
+
+ /*************** no man's land **************************************/\r
+ else {\r
+ error("Fatal Error: Unknown Action: ".$action."\n");\r
+ }\r
+
+ print_footer($course);
+
+?>
+
--- /dev/null
+To Do
+=====
+
+PostgreSQL schema
+
+Use a better method to measure bias in peer grades, probably based on the
+ percentage difference rather the relative difference used at present.
+
+Add time-agreed test to calculation of final grades.
+
+Comments are seen by a third party, is this standard Moodle behaviour?
+
+Cron function should email something to the assessor when an assessment is
+ agreed.
+
+Add a league table of submissions in the final phase for students.
+
+---
+
+Self assessments may need special handling, remove duplication in student
+ view - Done
+
+Add student names to assessments and submissions for teachers - Done
+
+
+Ray Kingdon
+28 July 2003
+
+
--- /dev/null
+<?PHP // $Id: upload.php, v1.0 30th April 2003
+
+ require("../../config.php");
+ require("lib.php");
+
+ require_variable($id); // course module ID
+
+ $newfile = $HTTP_POST_FILES["newfile"];
+
+ // get some esential stuff...
+ if (! $cm = get_record("course_modules", "id", $id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if (! $course = get_record("course", "id", $cm->course)) {
+ error("Course is misconfigured");
+ }
+
+ if (! $exercise = get_record("exercise", "id", $cm->instance)) {
+ error("Course module is incorrect");
+ }
+
+ require_login($course->id);
+
+ add_to_log($course->id, "exercise", "submit", "view.php?id=$cm->id", "$exercise->id");
+
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+ $strupload = get_string("upload");
+
+ print_header("$course->shortname: $exercise->name : $strupload", "$course->fullname",
+ "$navigation <A HREF=index.php?id=$course->id>$strexercises</A> ->
+ <A HREF=\"view.php?id=$cm->id\">$exercise->name</A> -> $strupload",
+ "", "", true);
+ if (!$title = $_POST['title']) {
+ notify(get_string("notitlegiven", "exercise") );
+ }
+ else {
+ if (is_uploaded_file($newfile['tmp_name']) and $newfile['size'] > 0) {
+ if ($newfile['size'] > $exercise->maxbytes) {
+ notify(get_string("uploadfiletoobig", "assignment", $exercise->maxbytes));
+ }
+ else {
+ $newfile_name = clean_filename($newfile['name']);
+ if ($newfile_name) {
+ $newsubmission->exerciseid = $exercise->id;
+ if (isteacher($course->id)) {
+ // it's an exercise submission, flag it as such
+ $newsubmission->userid = 0;
+ $newsubmission->isexercise = 1; // it'sa description of an exercise
+ }
+ else {
+ $newsubmission->userid = $USER->id;
+ }
+ $newsubmission->title = $title;
+ $newsubmission->timecreated = time();
+ if (!$newsubmission->id = insert_record("exercise_submissions", $newsubmission)) {
+ error("exercise upload: Failure to create new submission record!");
+ }
+ if (! $dir = exercise_file_area($exercise, $newsubmission)) {
+ error("Sorry, an error in the system prevents you from uploading files: contact your teacher or system administrator");
+ }
+ if (move_uploaded_file($newfile['tmp_name'], "$dir/$newfile_name")) {
+ print_heading(get_string("uploadsuccess", "assignment", $newfile_name) );
+ }
+ else {
+ notify(get_string("uploaderror", "assignment") );
+ }
+ // clear resubmit flags
+ if (!set_field("exercise_submissions", "resubmit", 0, "exerciseid", $exercise->id, "userid", $USER->id)) {
+ error("Exercise Upload: unable to reset resubmit flag");
+ }
+ }
+ else {
+ notify(get_string("uploadbadname", "assignment") );
+ }
+ }
+ }
+ else {
+ notify(get_string("uploadnofilefound", "assignment") );
+ }
+ }
+ print_continue("view.php?id=$cm->id");
+
+ print_footer($course);
+
+?>
--- /dev/null
+<?PHP // $Id$
+
+////////////////////////////////////////////////////////////////////////////////
+// Code fragment to define the module version etc.
+// This fragment is called by /admin/index.php
+////////////////////////////////////////////////////////////////////////////////
+
+$module->version = 2003100400;
+$module->cron = 60;
+
+?>
--- /dev/null
+<?PHP // $Id: view.php, v1.1 23 Aug 2003
+
+/*************************************************
+ ACTIONS handled are:
+
+ closeexercise( for teachers)
+ displayfinalgrade (for students)
+ makeleaguetableavailable (for teachers)
+ notavailable (for students)
+ openexercise (for teachers)
+ setupassignment (for teachers)
+ studentsview
+ submitassignment
+ teachersview
+
+************************************************/
+
+ require("../../config.php");
+ require("lib.php");
+
+ require_variable($id); // Course Module ID
+
+ // get some esential stuff...
+ if (! $cm = get_record("course_modules", "id", $id)) {
+ error("Course Module ID was incorrect");
+ }
+
+ if (! $course = get_record("course", "id", $cm->course)) {
+ error("Course is misconfigured");
+ }
+
+ if (! $exercise = get_record("exercise", "id", $cm->instance)) {
+ error("Course module is incorrect");
+ }
+
+ require_login($course->id);
+
+ // ...log activity...
+ add_to_log($course->id, "exercise", "view", "view.php?id=$cm->id", "$exercise->id");
+
+ if ($course->category) {
+ $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+ }
+
+ $strexercises = get_string("modulenameplural", "exercise");
+ $strexercise = get_string("modulename", "exercise");
+
+ // ...display header...
+ print_header("$course->shortname: $exercise->name", "$course->fullname",
+ "$navigation <A HREF=index.php?id=$course->id>$strexercises</A> -> $exercise->name",
+ "", "", true, update_module_button($cm->id, $course->id, $strexercise), navmenu($course, $cm));
+
+ // ...and if necessary set default action
+
+ optional_variable($action);
+ if (isteacher($course->id)) {
+ if (empty($action)) { // no action specified, either go straight to elements page else the admin page
+ // has the assignment any elements
+ if (count_records("exercise_elements", "exerciseid", $exercise->id)) {
+ $action = "teachersview";
+ }
+ else {
+ redirect("assessments.php?action=editelements&id=$cm->id");
+ }
+ }
+ }
+ elseif (!isguest()) { // it's a student then
+ if (!$cm->visible) {
+ notice(get_string("activityiscurrentlyhidden"));
+ }
+ switch ($exercise->phase) {
+ case 0 :
+ case 1 : $action = 'notavailable'; break;
+ case 2 : $action = 'studentsview'; break;
+ case 3 : $action = 'notavailable'; break;
+ case 4 : $action = 'displayfinalgrade';
+ }
+ }
+ else { // it's a guest, oh no!
+ $action = 'notavailable';
+ }
+
+
+ /*********************** close exercise for student assessments and submissions (move to phase 3) (for teachers)**/
+ if ($action == 'closeexercise') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ // move tp phase 3
+ set_field("exercise", "phase", 3, "id", "$exercise->id");
+ redirect("view.php?id=$cm->id", get_string("movingtophase", "exercise", 3));
+ }
+
+
+ /******************* display final grade (for students) ************************************/
+ elseif ($action == 'displayfinalgrade' ) {
+
+ // get the final weights from the database
+ $teacherweight = get_field("exercise","teacherweight", "id", $exercise->id);
+ $gradingweight = get_field("exercise","gradingweight", "id", $exercise->id);
+
+ // show the final grades as stored in the tables...
+ print_heading_with_help(get_string("displayoffinalgrades", "exercise"), "finalgrades", "exercise");
+ if ($submissions = exercise_get_user_submissions($exercise, $USER)) { // any submissions from user?
+ echo "<center><table border=\"1\" width=\"90%\"><tr>";
+ echo "<td bgcolor=\"$THEME->cellheading2\"><b>".get_string("submissions", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".get_string("gradeforassessment", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".get_string("gradeforsubmission", "exercise", $course->teacher)."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>".get_string("overallgrade", "exercise")."</b></td></TR>\n";
+ // now the weights
+ echo "<TR><td bgcolor=\"$THEME->cellheading2\"><b>".get_string("weights", "exercise")."</b></td>";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>$EXERCISE_FWEIGHTS[$gradingweight]</b></td>\n";
+ echo "<td bgcolor=\"$THEME->cellheading2\" align=\"center\"><b>$EXERCISE_FWEIGHTS[$teacherweight]</b></td>\n";
+ echo "<td bgcolor=\"$THEME->cellheading2\"><b> </b></td></TR>\n";
+ // first get user's own assessment reord, it should contain their grading grade
+ if ($ownassessments = exercise_get_user_assessments($exercise, $USER)) {
+ foreach ($ownassessments as $ownassessment) {
+ break; // there should only be one
+ }
+ }
+ else {
+ $ownassessment->gradinggrade = 0;
+ }
+ foreach ($submissions as $submission) {
+ if ($assessments = exercise_get_assessments($submission)) {
+ foreach ($assessments as $assessment) { // (normally there should only be one
+ echo "<TR><td>".exercise_print_submission_title($exercise, $submission)."</td>\n";
+ echo "<td align=\"center\">".number_format($ownassessment->gradinggrade * $exercise->grade / COMMENTSCALE, 1)."</td>";
+ echo "<td align=\"center\">".number_format($assessment->grade * $exercise->grade / 100.0, 1)."</td>";
+ echo "<td align=\"center\">". number_format(((($assessment->grade * $EXERCISE_FWEIGHTS[$teacherweight]
+ / 100.0) + ($ownassessment->gradinggrade * $EXERCISE_FWEIGHTS[$gradingweight]
+ / COMMENTSCALE )) * $exercise->grade) /
+ ($EXERCISE_FWEIGHTS[$teacherweight] + $EXERCISE_FWEIGHTS[$gradingweight]), 1).
+ "</td></TR>\n";
+ }
+ }
+ }
+ }
+ echo "</TABLE><BR CLEAR=ALL>\n";
+ exercise_print_league_table($exercise);
+ }\r
+
+
+ /*********************** make final grades available (for teachers only)**************/
+ elseif ($action == 'makeleaguetableavailable') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ set_field("exercise", "phase", 4, "id", "$exercise->id");
+ redirect("view.php?id=$cm->id", get_string("movingtophase", "exercise", 4));
+ add_to_log($course->id, "exercise", "display grades", "view.php?a=$exercise->id", "$exercise->id");
+ }
+
+
+ /*********************** assignment not available (for students)***********************/
+ elseif ($action == 'notavailable') {
+ print_heading(get_string("notavailable", "exercise"));
+ }
+
+
+ /*********************** open exercise for student assessments and submissions (move to phase 2) (for teachers)**/
+ elseif ($action == 'openexercise') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ // move to phase 2, check that teacher has made enough submissions
+ if (exercise_count_teacher_submissions($exercise) == 0) {
+ redirect("view.php?id=$cm->id", get_string("noexercisedescriptionssubmitted", "exercise"));
+ }
+ else {
+ set_field("exercise", "phase", 2, "id", "$exercise->id");
+ redirect("view.php?id=$cm->id", get_string("movingtophase", "exercise", 2));
+ add_to_log($course->id, "exercise", "open", "view.php?id=$cm->id", "$exercise->id");
+ }
+ }
+
+
+ /*********************** set up assignment (move back to phase 1) (for teachers)***********************/
+ elseif ($action == 'setupassignment') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ set_field("exercise", "phase", 1, "id", "$exercise->id");
+ redirect("view.php?id=$cm->id", get_string("movingtophase", "exercise", 1));
+ }
+
+
+ /*********************** student's view could be in 1 of 4 stages ***********************/
+ elseif ($action == 'studentsview') {
+ exercise_print_assignment_info($exercise);
+ // in Stage 1 - the student must make an assessment (linked to the teacher's exercise/submission
+ if (!exercise_test_user_assessments($exercise, $USER)) {
+ print_heading(get_string("pleaseviewtheexercise", "exercise", $course->teacher));
+ exercise_list_teacher_submissions($exercise, $USER);
+ }
+ // in stage 2? - submit own first attempt
+ else {
+ // show assessment the teacher's examples, there may be feedback from teacher
+ if (exercise_count_user_submissions($exercise, $USER) == 0) {
+ print_heading(get_string("atthisstageyou", "exercise", $course->teacher));
+ exercise_list_teacher_submissions($exercise, $USER, true); // true = allow re-assessing
+ // print upload form
+ print_heading(get_string("pleasesubmityourwork", "exercise").":");
+ exercise_print_upload_form($exercise);
+ }
+ // in stage 3? - awaiting grading of assessment and assessment of work by teacher, may resubmit if allowed
+ else {
+ print_heading(get_string("yourassessment", "exercise"));
+ exercise_list_teacher_submissions($exercise, $USER);
+ echo "<hr size=\"1\" noshade>";
+ print_heading(get_string("yoursubmission", "exercise"));
+ exercise_list_user_submissions($exercise, $USER);
+ if (exercise_test_for_resubmission($exercise, $USER)) {
+ // if resubmission requested print upload form
+ echo "<hr size=\"1\" noshade>";
+ print_heading(get_string("pleasesubmityourwork", "exercise").":");
+ exercise_print_upload_form($exercise);
+ echo "<hr size=\"1\" noshade>";
+ }
+ }
+ }
+ }
+
+
+ /*********************** submission of assignment by teacher only***********************/
+ elseif ($action == 'submitassignment') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ exercise_print_assignment_info($exercise);
+
+ // list previous submissions from this user
+ exercise_list_user_submissions($exercise, $USER);
+
+ echo "<HR SIZE=1 NOSHADE>";
+
+ // print upload form
+ print_heading(get_string("submitexercisedescription", "exercise").":");
+ exercise_print_upload_form($exercise);
+ }
+
+
+ /****************** teacher's view - display admin page (current phase options) ************/
+ elseif ($action == 'teachersview') {
+
+ if (!isteacher($course->id)) {
+ error("Only teachers can look at this page");
+ }
+
+ print_heading_with_help(get_string("managingassignment", "exercise"), "managing", "exercise");
+
+ exercise_print_assignment_info($exercise);
+ $tabs->names = array("1. ".get_string("phase1", "exercise"),
+ "2. ".get_string("phase2", "exercise", $course->student),
+ "3. ".get_string("phase3", "exercise", $course->student),
+ "4. ".get_string("phase4", "exercise"));
+ $tabs->urls = array("view.php?id=$cm->id&action=setupassignment",
+ "view.php?id=$cm->id&action=openexercise",
+ "view.php?id=$cm->id&action=closeexercise",
+ "view.php?id=$cm->id&action=makeleaguetableavailable");
+ if ($exercise->phase) { // phase 1 or more
+ $tabs->highlight = $exercise->phase - 1;
+ } else {
+ $tabs->highlight = 0; // phase is zero
+ }
+ exercise_print_tabbed_heading($tabs);
+
+ echo "<center>\n";
+ switch ($exercise->phase) {
+ case 0:
+ case 1: // set up assignment
+ echo "<p><b><a href=\"assessments.php?id=$cm->id&action=editelements\">".
+ get_string("amendassessmentelements", "exercise")."</a></b> \n";
+ helpbutton("elements", get_string("amendassessmentelements", "exercise"), "exercise");
+ echo "<p><b><a href=\"view.php?id=$cm->id&action=submitassignment\">".
+ get_string("submitexercisedescription", "exercise")."</a></b> \n";
+ helpbutton("submissionofdescriptions", get_string("submitexercisedescription", "exercise"), "exercise");
+ break;
+
+ case 2: // submissions and assessments
+ // just show student submissions link, the (self) assessments are show above the assessment form for
+ // the submissions
+ echo "<p><b><a href=\"submissions.php?id=$cm->id&action=listforassessmentstudent\">".
+ get_string("studentsubmissionsforassessment", "exercise",
+ exercise_count_unassessed_student_submissions($exercise))."</a></b> \n";
+ helpbutton("gradingsubmissions", get_string("studentsubmissionsforassessment", "exercise"), "exercise");
+ break;
+
+ case 3: // finish assessing
+ // same as phase 2
+ echo "<p><b><a href=\"submissions.php?id=$cm->id&action=listforassessmentstudent\">".
+ get_string("studentsubmissionsforassessment", "exercise",
+ exercise_count_unassessed_student_submissions($exercise))."</a></b> \n";
+ helpbutton("gradingsubmissions", get_string("studentsubmissionsforassessment", "exercise"), "exercise");
+ break;
+
+ case 4: // show final grades
+ print_heading("<A HREF=\"submissions.php?id=$cm->id&action=displayfinalgrades\">".
+ get_string("displayoffinalgrades", "exercise")."</A>");
+ }
+ print_heading("<A HREF=\"submissions.php?id=$cm->id&action=adminlist\">".
+ get_string("administration")."</A>");
+ }
+
+
+ /*************** no man's land **************************************/\r
+ else {\r
+ error("Fatal Error: Unknown Action: ".$action."\n");\r
+ }\r
+
+ print_footer($course);
+
+?>