[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/assign/ -> lib.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * This file contains the moodle hooks for the assign module.
  19   *
  20   * It delegates most functions to the assignment class.
  21   *
  22   * @package   mod_assign
  23   * @copyright 2012 NetSpot {@link http://www.netspot.com.au}
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  /**
  29   * Adds an assignment instance
  30   *
  31   * This is done by calling the add_instance() method of the assignment type class
  32   * @param stdClass $data
  33   * @param mod_assign_mod_form $form
  34   * @return int The instance id of the new assignment
  35   */
  36  function assign_add_instance(stdClass $data, mod_assign_mod_form $form = null) {
  37      global $CFG;
  38      require_once($CFG->dirroot . '/mod/assign/locallib.php');
  39  
  40      $assignment = new assign(context_module::instance($data->coursemodule), null, null);
  41      return $assignment->add_instance($data, true);
  42  }
  43  
  44  /**
  45   * delete an assignment instance
  46   * @param int $id
  47   * @return bool
  48   */
  49  function assign_delete_instance($id) {
  50      global $CFG;
  51      require_once($CFG->dirroot . '/mod/assign/locallib.php');
  52      $cm = get_coursemodule_from_instance('assign', $id, 0, false, MUST_EXIST);
  53      $context = context_module::instance($cm->id);
  54  
  55      $assignment = new assign($context, null, null);
  56      return $assignment->delete_instance();
  57  }
  58  
  59  /**
  60   * This function is used by the reset_course_userdata function in moodlelib.
  61   * This function will remove all assignment submissions and feedbacks in the database
  62   * and clean up any related data.
  63   *
  64   * @param stdClass $data the data submitted from the reset course.
  65   * @return array
  66   */
  67  function assign_reset_userdata($data) {
  68      global $CFG, $DB;
  69      require_once($CFG->dirroot . '/mod/assign/locallib.php');
  70  
  71      $status = array();
  72      $params = array('courseid'=>$data->courseid);
  73      $sql = "SELECT a.id FROM {assign} a WHERE a.course=:courseid";
  74      $course = $DB->get_record('course', array('id'=>$data->courseid), '*', MUST_EXIST);
  75      if ($assigns = $DB->get_records_sql($sql, $params)) {
  76          foreach ($assigns as $assign) {
  77              $cm = get_coursemodule_from_instance('assign',
  78                                                   $assign->id,
  79                                                   $data->courseid,
  80                                                   false,
  81                                                   MUST_EXIST);
  82              $context = context_module::instance($cm->id);
  83              $assignment = new assign($context, $cm, $course);
  84              $status = array_merge($status, $assignment->reset_userdata($data));
  85          }
  86      }
  87      return $status;
  88  }
  89  
  90  /**
  91   * This standard function will check all instances of this module
  92   * and make sure there are up-to-date events created for each of them.
  93   * If courseid = 0, then every assignment event in the site is checked, else
  94   * only assignment events belonging to the course specified are checked.
  95   *
  96   * @param int $courseid
  97   * @return bool
  98   */
  99  function assign_refresh_events($courseid = 0) {
 100      global $CFG, $DB;
 101      require_once($CFG->dirroot . '/mod/assign/locallib.php');
 102  
 103      if ($courseid) {
 104          // Make sure that the course id is numeric.
 105          if (!is_numeric($courseid)) {
 106              return false;
 107          }
 108          if (!$assigns = $DB->get_records('assign', array('course' => $courseid))) {
 109              return false;
 110          }
 111          // Get course from courseid parameter.
 112          if (!$course = $DB->get_record('course', array('id' => $courseid), '*')) {
 113              return false;
 114          }
 115      } else {
 116          if (!$assigns = $DB->get_records('assign')) {
 117              return false;
 118          }
 119      }
 120      foreach ($assigns as $assign) {
 121          // Use assignment's course column if courseid parameter is not given.
 122          if (!$courseid) {
 123              $courseid = $assign->course;
 124              if (!$course = $DB->get_record('course', array('id' => $courseid), '*')) {
 125                  continue;
 126              }
 127          }
 128          if (!$cm = get_coursemodule_from_instance('assign', $assign->id, $courseid, false)) {
 129              continue;
 130          }
 131          $context = context_module::instance($cm->id);
 132          $assignment = new assign($context, $cm, $course);
 133          $assignment->update_calendar($cm->id);
 134      }
 135  
 136      return true;
 137  }
 138  
 139  /**
 140   * Removes all grades from gradebook
 141   *
 142   * @param int $courseid The ID of the course to reset
 143   * @param string $type Optional type of assignment to limit the reset to a particular assignment type
 144   */
 145  function assign_reset_gradebook($courseid, $type='') {
 146      global $CFG, $DB;
 147  
 148      $params = array('moduletype'=>'assign', 'courseid'=>$courseid);
 149      $sql = 'SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid
 150              FROM {assign} a, {course_modules} cm, {modules} m
 151              WHERE m.name=:moduletype AND m.id=cm.module AND cm.instance=a.id AND a.course=:courseid';
 152  
 153      if ($assignments = $DB->get_records_sql($sql, $params)) {
 154          foreach ($assignments as $assignment) {
 155              assign_grade_item_update($assignment, 'reset');
 156          }
 157      }
 158  }
 159  
 160  /**
 161   * Implementation of the function for printing the form elements that control
 162   * whether the course reset functionality affects the assignment.
 163   * @param moodleform $mform form passed by reference
 164   */
 165  function assign_reset_course_form_definition(&$mform) {
 166      $mform->addElement('header', 'assignheader', get_string('modulenameplural', 'assign'));
 167      $name = get_string('deleteallsubmissions', 'assign');
 168      $mform->addElement('advcheckbox', 'reset_assign_submissions', $name);
 169  }
 170  
 171  /**
 172   * Course reset form defaults.
 173   * @param  object $course
 174   * @return array
 175   */
 176  function assign_reset_course_form_defaults($course) {
 177      return array('reset_assign_submissions'=>1);
 178  }
 179  
 180  /**
 181   * Update an assignment instance
 182   *
 183   * This is done by calling the update_instance() method of the assignment type class
 184   * @param stdClass $data
 185   * @param stdClass $form - unused
 186   * @return object
 187   */
 188  function assign_update_instance(stdClass $data, $form) {
 189      global $CFG;
 190      require_once($CFG->dirroot . '/mod/assign/locallib.php');
 191      $context = context_module::instance($data->coursemodule);
 192      $assignment = new assign($context, null, null);
 193      return $assignment->update_instance($data);
 194  }
 195  
 196  /**
 197   * Return the list if Moodle features this module supports
 198   *
 199   * @param string $feature FEATURE_xx constant for requested feature
 200   * @return mixed True if module supports feature, null if doesn't know
 201   */
 202  function assign_supports($feature) {
 203      switch($feature) {
 204          case FEATURE_GROUPS:
 205              return true;
 206          case FEATURE_GROUPINGS:
 207              return true;
 208          case FEATURE_MOD_INTRO:
 209              return true;
 210          case FEATURE_COMPLETION_TRACKS_VIEWS:
 211              return true;
 212          case FEATURE_COMPLETION_HAS_RULES:
 213              return true;
 214          case FEATURE_GRADE_HAS_GRADE:
 215              return true;
 216          case FEATURE_GRADE_OUTCOMES:
 217              return true;
 218          case FEATURE_BACKUP_MOODLE2:
 219              return true;
 220          case FEATURE_SHOW_DESCRIPTION:
 221              return true;
 222          case FEATURE_ADVANCED_GRADING:
 223              return true;
 224          case FEATURE_PLAGIARISM:
 225              return true;
 226  
 227          default:
 228              return null;
 229      }
 230  }
 231  
 232  /**
 233   * Lists all gradable areas for the advanced grading methods gramework
 234   *
 235   * @return array('string'=>'string') An array with area names as keys and descriptions as values
 236   */
 237  function assign_grading_areas_list() {
 238      return array('submissions'=>get_string('submissions', 'assign'));
 239  }
 240  
 241  
 242  /**
 243   * extend an assigment navigation settings
 244   *
 245   * @param settings_navigation $settings
 246   * @param navigation_node $navref
 247   * @return void
 248   */
 249  function assign_extend_settings_navigation(settings_navigation $settings, navigation_node $navref) {
 250      global $PAGE, $DB;
 251  
 252      $cm = $PAGE->cm;
 253      if (!$cm) {
 254          return;
 255      }
 256  
 257      $context = $cm->context;
 258      $course = $PAGE->course;
 259  
 260      if (!$course) {
 261          return;
 262      }
 263  
 264      // Link to gradebook.
 265      if (has_capability('gradereport/grader:view', $cm->context) &&
 266              has_capability('moodle/grade:viewall', $cm->context)) {
 267          $link = new moodle_url('/grade/report/grader/index.php', array('id' => $course->id));
 268          $linkname = get_string('viewgradebook', 'assign');
 269          $node = $navref->add($linkname, $link, navigation_node::TYPE_SETTING);
 270      }
 271  
 272      // Link to download all submissions.
 273      if (has_any_capability(array('mod/assign:grade', 'mod/assign:viewgrades'), $context)) {
 274          $link = new moodle_url('/mod/assign/view.php', array('id' => $cm->id, 'action'=>'grading'));
 275          $node = $navref->add(get_string('viewgrading', 'assign'), $link, navigation_node::TYPE_SETTING);
 276  
 277          $link = new moodle_url('/mod/assign/view.php', array('id' => $cm->id, 'action'=>'downloadall'));
 278          $node = $navref->add(get_string('downloadall', 'assign'), $link, navigation_node::TYPE_SETTING);
 279      }
 280  
 281      if (has_capability('mod/assign:revealidentities', $context)) {
 282          $dbparams = array('id'=>$cm->instance);
 283          $assignment = $DB->get_record('assign', $dbparams, 'blindmarking, revealidentities');
 284  
 285          if ($assignment && $assignment->blindmarking && !$assignment->revealidentities) {
 286              $urlparams = array('id' => $cm->id, 'action'=>'revealidentities');
 287              $url = new moodle_url('/mod/assign/view.php', $urlparams);
 288              $linkname = get_string('revealidentities', 'assign');
 289              $node = $navref->add($linkname, $url, navigation_node::TYPE_SETTING);
 290          }
 291      }
 292  }
 293  
 294  /**
 295   * Add a get_coursemodule_info function in case any assignment type wants to add 'extra' information
 296   * for the course (see resource).
 297   *
 298   * Given a course_module object, this function returns any "extra" information that may be needed
 299   * when printing this activity in a course listing.  See get_array_of_activities() in course/lib.php.
 300   *
 301   * @param stdClass $coursemodule The coursemodule object (record).
 302   * @return cached_cm_info An object on information that the courses
 303   *                        will know about (most noticeably, an icon).
 304   */
 305  function assign_get_coursemodule_info($coursemodule) {
 306      global $CFG, $DB;
 307  
 308      $dbparams = array('id'=>$coursemodule->instance);
 309      $fields = 'id, name, alwaysshowdescription, allowsubmissionsfromdate, intro, introformat';
 310      if (! $assignment = $DB->get_record('assign', $dbparams, $fields)) {
 311          return false;
 312      }
 313  
 314      $result = new cached_cm_info();
 315      $result->name = $assignment->name;
 316      if ($coursemodule->showdescription) {
 317          if ($assignment->alwaysshowdescription || time() > $assignment->allowsubmissionsfromdate) {
 318              // Convert intro to html. Do not filter cached version, filters run at display time.
 319              $result->content = format_module_intro('assign', $assignment, $coursemodule->id, false);
 320          }
 321      }
 322      return $result;
 323  }
 324  
 325  /**
 326   * Return a list of page types
 327   * @param string $pagetype current page type
 328   * @param stdClass $parentcontext Block's parent context
 329   * @param stdClass $currentcontext Current context of block
 330   */
 331  function assign_page_type_list($pagetype, $parentcontext, $currentcontext) {
 332      $modulepagetype = array(
 333          'mod-assign-*' => get_string('page-mod-assign-x', 'assign'),
 334          'mod-assign-view' => get_string('page-mod-assign-view', 'assign'),
 335      );
 336      return $modulepagetype;
 337  }
 338  
 339  /**
 340   * Print an overview of all assignments
 341   * for the courses.
 342   *
 343   * @param mixed $courses The list of courses to print the overview for
 344   * @param array $htmlarray The array of html to return
 345   *
 346   * @return true
 347   */
 348  function assign_print_overview($courses, &$htmlarray) {
 349      global $CFG, $DB;
 350  
 351      if (empty($courses) || !is_array($courses) || count($courses) == 0) {
 352          return true;
 353      }
 354  
 355      if (!$assignments = get_all_instances_in_courses('assign', $courses)) {
 356          return true;
 357      }
 358  
 359      $assignmentids = array();
 360  
 361      // Do assignment_base::isopen() here without loading the whole thing for speed.
 362      foreach ($assignments as $key => $assignment) {
 363          $time = time();
 364          $isopen = false;
 365          if ($assignment->duedate) {
 366              $duedate = false;
 367              if ($assignment->cutoffdate) {
 368                  $duedate = $assignment->cutoffdate;
 369              }
 370              if ($duedate) {
 371                  $isopen = ($assignment->allowsubmissionsfromdate <= $time && $time <= $duedate);
 372              } else {
 373                  $isopen = ($assignment->allowsubmissionsfromdate <= $time);
 374              }
 375          }
 376          if ($isopen) {
 377              $assignmentids[] = $assignment->id;
 378          }
 379      }
 380  
 381      if (empty($assignmentids)) {
 382          // No assignments to look at - we're done.
 383          return true;
 384      }
 385  
 386      // Definitely something to print, now include the constants we need.
 387      require_once($CFG->dirroot . '/mod/assign/locallib.php');
 388  
 389      $strduedate = get_string('duedate', 'assign');
 390      $strcutoffdate = get_string('nosubmissionsacceptedafter', 'assign');
 391      $strnolatesubmissions = get_string('nolatesubmissions', 'assign');
 392      $strduedateno = get_string('duedateno', 'assign');
 393      $strassignment = get_string('modulename', 'assign');
 394  
 395      // We do all possible database work here *outside* of the loop to ensure this scales.
 396      list($sqlassignmentids, $assignmentidparams) = $DB->get_in_or_equal($assignmentids);
 397  
 398      $mysubmissions = null;
 399      $unmarkedsubmissions = null;
 400  
 401      foreach ($assignments as $assignment) {
 402  
 403          // Do not show assignments that are not open.
 404          if (!in_array($assignment->id, $assignmentids)) {
 405              continue;
 406          }
 407  
 408          $context = context_module::instance($assignment->coursemodule);
 409  
 410          // Does the submission status of the assignment require notification?
 411          if (has_capability('mod/assign:submit', $context)) {
 412              // Does the submission status of the assignment require notification?
 413              $submitdetails = assign_get_mysubmission_details_for_print_overview($mysubmissions, $sqlassignmentids,
 414                      $assignmentidparams, $assignment);
 415          } else {
 416              $submitdetails = false;
 417          }
 418  
 419          if (has_capability('mod/assign:grade', $context)) {
 420              // Does the grading status of the assignment require notification ?
 421              $gradedetails = assign_get_grade_details_for_print_overview($unmarkedsubmissions, $sqlassignmentids,
 422                      $assignmentidparams, $assignment, $context);
 423          } else {
 424              $gradedetails = false;
 425          }
 426  
 427          if (empty($submitdetails) && empty($gradedetails)) {
 428              // There is no need to display this assignment as there is nothing to notify.
 429              continue;
 430          }
 431  
 432          $dimmedclass = '';
 433          if (!$assignment->visible) {
 434              $dimmedclass = ' class="dimmed"';
 435          }
 436          $href = $CFG->wwwroot . '/mod/assign/view.php?id=' . $assignment->coursemodule;
 437          $basestr = '<div class="assign overview">' .
 438                 '<div class="name">' .
 439                 $strassignment . ': '.
 440                 '<a ' . $dimmedclass .
 441                     'title="' . $strassignment . '" ' .
 442                     'href="' . $href . '">' .
 443                 format_string($assignment->name) .
 444                 '</a></div>';
 445          if ($assignment->duedate) {
 446              $userdate = userdate($assignment->duedate);
 447              $basestr .= '<div class="info">' . $strduedate . ': ' . $userdate . '</div>';
 448          } else {
 449              $basestr .= '<div class="info">' . $strduedateno . '</div>';
 450          }
 451          if ($assignment->cutoffdate) {
 452              if ($assignment->cutoffdate == $assignment->duedate) {
 453                  $basestr .= '<div class="info">' . $strnolatesubmissions . '</div>';
 454              } else {
 455                  $userdate = userdate($assignment->cutoffdate);
 456                  $basestr .= '<div class="info">' . $strcutoffdate . ': ' . $userdate . '</div>';
 457              }
 458          }
 459  
 460          // Show only relevant information.
 461          if (!empty($submitdetails)) {
 462              $basestr .= $submitdetails;
 463          }
 464  
 465          if (!empty($gradedetails)) {
 466              $basestr .= $gradedetails;
 467          }
 468          $basestr .= '</div>';
 469  
 470          if (empty($htmlarray[$assignment->course]['assign'])) {
 471              $htmlarray[$assignment->course]['assign'] = $basestr;
 472          } else {
 473              $htmlarray[$assignment->course]['assign'] .= $basestr;
 474          }
 475      }
 476      return true;
 477  }
 478  
 479  /**
 480   * This api generates html to be displayed to students in print overview section, related to their submission status of the given
 481   * assignment.
 482   *
 483   * @param array $mysubmissions list of submissions of current user indexed by assignment id.
 484   * @param string $sqlassignmentids sql clause used to filter open assignments.
 485   * @param array $assignmentidparams sql params used to filter open assignments.
 486   * @param stdClass $assignment current assignment
 487   *
 488   * @return bool|string html to display , false if nothing needs to be displayed.
 489   * @throws coding_exception
 490   */
 491  function assign_get_mysubmission_details_for_print_overview(&$mysubmissions, $sqlassignmentids, $assignmentidparams,
 492                                                              $assignment) {
 493      global $USER, $DB;
 494  
 495      if ($assignment->nosubmissions) {
 496          // Offline assignment. No need to display alerts for offline assignments.
 497          return false;
 498      }
 499  
 500      $strnotsubmittedyet = get_string('notsubmittedyet', 'assign');
 501  
 502      if (!isset($mysubmissions)) {
 503  
 504          // Get all user submissions, indexed by assignment id.
 505          $dbparams = array_merge(array($USER->id), $assignmentidparams, array($USER->id));
 506          $mysubmissions = $DB->get_records_sql('SELECT a.id AS assignment,
 507                                                        a.nosubmissions AS nosubmissions,
 508                                                        g.timemodified AS timemarked,
 509                                                        g.grader AS grader,
 510                                                        g.grade AS grade,
 511                                                        s.status AS status
 512                                                   FROM {assign} a, {assign_submission} s
 513                                              LEFT JOIN {assign_grades} g ON
 514                                                        g.assignment = s.assignment AND
 515                                                        g.userid = ? AND
 516                                                        g.attemptnumber = s.attemptnumber
 517                                                  WHERE a.id ' . $sqlassignmentids . ' AND
 518                                                        s.latest = 1 AND
 519                                                        s.assignment = a.id AND
 520                                                        s.userid = ?', $dbparams);
 521      }
 522  
 523      $submitdetails = '';
 524      $submitdetails .= '<div class="details">';
 525      $submitdetails .= get_string('mysubmission', 'assign');
 526      $submission = false;
 527  
 528      if (isset($mysubmissions[$assignment->id])) {
 529          $submission = $mysubmissions[$assignment->id];
 530      }
 531  
 532      if ($submission && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
 533          // A valid submission already exists, no need to notify students about this.
 534          return false;
 535      }
 536  
 537      // We need to show details only if a valid submission doesn't exist.
 538      if (!$submission ||
 539          !$submission->status ||
 540          $submission->status == ASSIGN_SUBMISSION_STATUS_DRAFT ||
 541          $submission->status == ASSIGN_SUBMISSION_STATUS_NEW
 542      ) {
 543          $submitdetails .= $strnotsubmittedyet;
 544      } else {
 545          $submitdetails .= get_string('submissionstatus_' . $submission->status, 'assign');
 546      }
 547      if ($assignment->markingworkflow) {
 548          $workflowstate = $DB->get_field('assign_user_flags', 'workflowstate', array('assignment' =>
 549                  $assignment->id, 'userid' => $USER->id));
 550          if ($workflowstate) {
 551              $gradingstatus = 'markingworkflowstate' . $workflowstate;
 552          } else {
 553              $gradingstatus = 'markingworkflowstate' . ASSIGN_MARKING_WORKFLOW_STATE_NOTMARKED;
 554          }
 555      } else if (!empty($submission->grade) && $submission->grade !== null && $submission->grade >= 0) {
 556          $gradingstatus = ASSIGN_GRADING_STATUS_GRADED;
 557      } else {
 558          $gradingstatus = ASSIGN_GRADING_STATUS_NOT_GRADED;
 559      }
 560      $submitdetails .= ', ' . get_string($gradingstatus, 'assign');
 561      $submitdetails .= '</div>';
 562      return $submitdetails;
 563  }
 564  
 565  /**
 566   * This api generates html to be displayed to teachers in print overview section, related to the grading status of the given
 567   * assignment's submissions.
 568   *
 569   * @param array $unmarkedsubmissions list of submissions of that are currently unmarked indexed by assignment id.
 570   * @param string $sqlassignmentids sql clause used to filter open assignments.
 571   * @param array $assignmentidparams sql params used to filter open assignments.
 572   * @param stdClass $assignment current assignment
 573   * @param context $context context of the assignment.
 574   *
 575   * @return bool|string html to display , false if nothing needs to be displayed.
 576   * @throws coding_exception
 577   */
 578  function assign_get_grade_details_for_print_overview(&$unmarkedsubmissions, $sqlassignmentids, $assignmentidparams,
 579                                                       $assignment, $context) {
 580      global $DB;
 581      if (!isset($unmarkedsubmissions)) {
 582          // Build up and array of unmarked submissions indexed by assignment id/ userid
 583          // for use where the user has grading rights on assignment.
 584          $dbparams = array_merge(array(ASSIGN_SUBMISSION_STATUS_SUBMITTED), $assignmentidparams);
 585          $rs = $DB->get_recordset_sql('SELECT s.assignment as assignment,
 586                                               s.userid as userid,
 587                                               s.id as id,
 588                                               s.status as status,
 589                                               g.timemodified as timegraded
 590                                          FROM {assign_submission} s
 591                                     LEFT JOIN {assign_grades} g ON
 592                                               s.userid = g.userid AND
 593                                               s.assignment = g.assignment AND
 594                                               g.attemptnumber = s.attemptnumber
 595                                         WHERE
 596                                               ( g.timemodified is NULL OR
 597                                               s.timemodified > g.timemodified OR
 598                                               g.grade IS NULL ) AND
 599                                               s.timemodified IS NOT NULL AND
 600                                               s.status = ? AND
 601                                               s.latest = 1 AND
 602                                               s.assignment ' . $sqlassignmentids, $dbparams);
 603  
 604          $unmarkedsubmissions = array();
 605          foreach ($rs as $rd) {
 606              $unmarkedsubmissions[$rd->assignment][$rd->userid] = $rd->id;
 607          }
 608          $rs->close();
 609      }
 610  
 611      // Count how many people can submit.
 612      $submissions = 0;
 613      if ($students = get_enrolled_users($context, 'mod/assign:view', 0, 'u.id')) {
 614          foreach ($students as $student) {
 615              if (isset($unmarkedsubmissions[$assignment->id][$student->id])) {
 616                  $submissions++;
 617              }
 618          }
 619      }
 620  
 621      if ($submissions) {
 622          $urlparams = array('id' => $assignment->coursemodule, 'action' => 'grading');
 623          $url = new moodle_url('/mod/assign/view.php', $urlparams);
 624          $gradedetails = '<div class="details">' .
 625                  '<a href="' . $url . '">' .
 626                  get_string('submissionsnotgraded', 'assign', $submissions) .
 627                  '</a></div>';
 628          return $gradedetails;
 629      } else {
 630          return false;
 631      }
 632  
 633  }
 634  
 635  /**
 636   * Print recent activity from all assignments in a given course
 637   *
 638   * This is used by the recent activity block
 639   * @param mixed $course the course to print activity for
 640   * @param bool $viewfullnames boolean to determine whether to show full names or not
 641   * @param int $timestart the time the rendering started
 642   * @return bool true if activity was printed, false otherwise.
 643   */
 644  function assign_print_recent_activity($course, $viewfullnames, $timestart) {
 645      global $CFG, $USER, $DB, $OUTPUT;
 646      require_once($CFG->dirroot . '/mod/assign/locallib.php');
 647  
 648      // Do not use log table if possible, it may be huge.
 649  
 650      $dbparams = array($timestart, $course->id, 'assign', ASSIGN_SUBMISSION_STATUS_SUBMITTED);
 651      $namefields = user_picture::fields('u', null, 'userid');
 652      if (!$submissions = $DB->get_records_sql("SELECT asb.id, asb.timemodified, cm.id AS cmid,
 653                                                       $namefields
 654                                                  FROM {assign_submission} asb
 655                                                       JOIN {assign} a      ON a.id = asb.assignment
 656                                                       JOIN {course_modules} cm ON cm.instance = a.id
 657                                                       JOIN {modules} md        ON md.id = cm.module
 658                                                       JOIN {user} u            ON u.id = asb.userid
 659                                                 WHERE asb.timemodified > ? AND
 660                                                       asb.latest = 1 AND
 661                                                       a.course = ? AND
 662                                                       md.name = ? AND
 663                                                       asb.status = ?
 664                                              ORDER BY asb.timemodified ASC", $dbparams)) {
 665           return false;
 666      }
 667  
 668      $modinfo = get_fast_modinfo($course);
 669      $show    = array();
 670      $grader  = array();
 671  
 672      $showrecentsubmissions = get_config('assign', 'showrecentsubmissions');
 673  
 674      foreach ($submissions as $submission) {
 675          if (!array_key_exists($submission->cmid, $modinfo->get_cms())) {
 676              continue;
 677          }
 678          $cm = $modinfo->get_cm($submission->cmid);
 679          if (!$cm->uservisible) {
 680              continue;
 681          }
 682          if ($submission->userid == $USER->id) {
 683              $show[] = $submission;
 684              continue;
 685          }
 686  
 687          $context = context_module::instance($submission->cmid);
 688          // The act of submitting of assignment may be considered private -
 689          // only graders will see it if specified.
 690          if (empty($showrecentsubmissions)) {
 691              if (!array_key_exists($cm->id, $grader)) {
 692                  $grader[$cm->id] = has_capability('moodle/grade:viewall', $context);
 693              }
 694              if (!$grader[$cm->id]) {
 695                  continue;
 696              }
 697          }
 698  
 699          $groupmode = groups_get_activity_groupmode($cm, $course);
 700  
 701          if ($groupmode == SEPARATEGROUPS &&
 702                  !has_capability('moodle/site:accessallgroups',  $context)) {
 703              if (isguestuser()) {
 704                  // Shortcut - guest user does not belong into any group.
 705                  continue;
 706              }
 707  
 708              // This will be slow - show only users that share group with me in this cm.
 709              if (!$modinfo->get_groups($cm->groupingid)) {
 710                  continue;
 711              }
 712              $usersgroups =  groups_get_all_groups($course->id, $submission->userid, $cm->groupingid);
 713              if (is_array($usersgroups)) {
 714                  $usersgroups = array_keys($usersgroups);
 715                  $intersect = array_intersect($usersgroups, $modinfo->get_groups($cm->groupingid));
 716                  if (empty($intersect)) {
 717                      continue;
 718                  }
 719              }
 720          }
 721          $show[] = $submission;
 722      }
 723  
 724      if (empty($show)) {
 725          return false;
 726      }
 727  
 728      echo $OUTPUT->heading(get_string('newsubmissions', 'assign').':', 3);
 729  
 730      foreach ($show as $submission) {
 731          $cm = $modinfo->get_cm($submission->cmid);
 732          $context = context_module::instance($submission->cmid);
 733          $assign = new assign($context, $cm, $cm->course);
 734          $link = $CFG->wwwroot.'/mod/assign/view.php?id='.$cm->id;
 735          // Obscure first and last name if blind marking enabled.
 736          if ($assign->is_blind_marking()) {
 737              $submission->firstname = get_string('participant', 'mod_assign');
 738              $submission->lastname = $assign->get_uniqueid_for_user($submission->userid);
 739          }
 740          print_recent_activity_note($submission->timemodified,
 741                                     $submission,
 742                                     $cm->name,
 743                                     $link,
 744                                     false,
 745                                     $viewfullnames);
 746      }
 747  
 748      return true;
 749  }
 750  
 751  /**
 752   * Returns all assignments since a given time.
 753   *
 754   * @param array $activities The activity information is returned in this array
 755   * @param int $index The current index in the activities array
 756   * @param int $timestart The earliest activity to show
 757   * @param int $courseid Limit the search to this course
 758   * @param int $cmid The course module id
 759   * @param int $userid Optional user id
 760   * @param int $groupid Optional group id
 761   * @return void
 762   */
 763  function assign_get_recent_mod_activity(&$activities,
 764                                          &$index,
 765                                          $timestart,
 766                                          $courseid,
 767                                          $cmid,
 768                                          $userid=0,
 769                                          $groupid=0) {
 770      global $CFG, $COURSE, $USER, $DB;
 771  
 772      require_once($CFG->dirroot . '/mod/assign/locallib.php');
 773  
 774      if ($COURSE->id == $courseid) {
 775          $course = $COURSE;
 776      } else {
 777          $course = $DB->get_record('course', array('id'=>$courseid));
 778      }
 779  
 780      $modinfo = get_fast_modinfo($course);
 781  
 782      $cm = $modinfo->get_cm($cmid);
 783      $params = array();
 784      if ($userid) {
 785          $userselect = 'AND u.id = :userid';
 786          $params['userid'] = $userid;
 787      } else {
 788          $userselect = '';
 789      }
 790  
 791      if ($groupid) {
 792          $groupselect = 'AND gm.groupid = :groupid';
 793          $groupjoin   = 'JOIN {groups_members} gm ON  gm.userid=u.id';
 794          $params['groupid'] = $groupid;
 795      } else {
 796          $groupselect = '';
 797          $groupjoin   = '';
 798      }
 799  
 800      $params['cminstance'] = $cm->instance;
 801      $params['timestart'] = $timestart;
 802      $params['submitted'] = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
 803  
 804      $userfields = user_picture::fields('u', null, 'userid');
 805  
 806      if (!$submissions = $DB->get_records_sql('SELECT asb.id, asb.timemodified, ' .
 807                                                       $userfields .
 808                                               '  FROM {assign_submission} asb
 809                                                  JOIN {assign} a ON a.id = asb.assignment
 810                                                  JOIN {user} u ON u.id = asb.userid ' .
 811                                            $groupjoin .
 812                                              '  WHERE asb.timemodified > :timestart AND
 813                                                       asb.status = :submitted AND
 814                                                       a.id = :cminstance
 815                                                       ' . $userselect . ' ' . $groupselect .
 816                                              ' ORDER BY asb.timemodified ASC', $params)) {
 817           return;
 818      }
 819  
 820      $groupmode       = groups_get_activity_groupmode($cm, $course);
 821      $cmcontext      = context_module::instance($cm->id);
 822      $grader          = has_capability('moodle/grade:viewall', $cmcontext);
 823      $accessallgroups = has_capability('moodle/site:accessallgroups', $cmcontext);
 824      $viewfullnames   = has_capability('moodle/site:viewfullnames', $cmcontext);
 825  
 826  
 827      $showrecentsubmissions = get_config('assign', 'showrecentsubmissions');
 828      $show = array();
 829      foreach ($submissions as $submission) {
 830          if ($submission->userid == $USER->id) {
 831              $show[] = $submission;
 832              continue;
 833          }
 834          // The act of submitting of assignment may be considered private -
 835          // only graders will see it if specified.
 836          if (empty($showrecentsubmissions)) {
 837              if (!$grader) {
 838                  continue;
 839              }
 840          }
 841  
 842          if ($groupmode == SEPARATEGROUPS and !$accessallgroups) {
 843              if (isguestuser()) {
 844                  // Shortcut - guest user does not belong into any group.
 845                  continue;
 846              }
 847  
 848              // This will be slow - show only users that share group with me in this cm.
 849              if (!$modinfo->get_groups($cm->groupingid)) {
 850                  continue;
 851              }
 852              $usersgroups =  groups_get_all_groups($course->id, $submission->userid, $cm->groupingid);
 853              if (is_array($usersgroups)) {
 854                  $usersgroups = array_keys($usersgroups);
 855                  $intersect = array_intersect($usersgroups, $modinfo->get_groups($cm->groupingid));
 856                  if (empty($intersect)) {
 857                      continue;
 858                  }
 859              }
 860          }
 861          $show[] = $submission;
 862      }
 863  
 864      if (empty($show)) {
 865          return;
 866      }
 867  
 868      if ($grader) {
 869          require_once($CFG->libdir.'/gradelib.php');
 870          $userids = array();
 871          foreach ($show as $id => $submission) {
 872              $userids[] = $submission->userid;
 873          }
 874          $grades = grade_get_grades($courseid, 'mod', 'assign', $cm->instance, $userids);
 875      }
 876  
 877      $aname = format_string($cm->name, true);
 878      foreach ($show as $submission) {
 879          $activity = new stdClass();
 880  
 881          $activity->type         = 'assign';
 882          $activity->cmid         = $cm->id;
 883          $activity->name         = $aname;
 884          $activity->sectionnum   = $cm->sectionnum;
 885          $activity->timestamp    = $submission->timemodified;
 886          $activity->user         = new stdClass();
 887          if ($grader) {
 888              $activity->grade = $grades->items[0]->grades[$submission->userid]->str_long_grade;
 889          }
 890  
 891          $userfields = explode(',', user_picture::fields());
 892          foreach ($userfields as $userfield) {
 893              if ($userfield == 'id') {
 894                  // Aliased in SQL above.
 895                  $activity->user->{$userfield} = $submission->userid;
 896              } else {
 897                  $activity->user->{$userfield} = $submission->{$userfield};
 898              }
 899          }
 900          $activity->user->fullname = fullname($submission, $viewfullnames);
 901  
 902          $activities[$index++] = $activity;
 903      }
 904  
 905      return;
 906  }
 907  
 908  /**
 909   * Print recent activity from all assignments in a given course
 910   *
 911   * This is used by course/recent.php
 912   * @param stdClass $activity
 913   * @param int $courseid
 914   * @param bool $detail
 915   * @param array $modnames
 916   */
 917  function assign_print_recent_mod_activity($activity, $courseid, $detail, $modnames) {
 918      global $CFG, $OUTPUT;
 919  
 920      echo '<table border="0" cellpadding="3" cellspacing="0" class="assignment-recent">';
 921  
 922      echo '<tr><td class="userpicture" valign="top">';
 923      echo $OUTPUT->user_picture($activity->user);
 924      echo '</td><td>';
 925  
 926      if ($detail) {
 927          $modname = $modnames[$activity->type];
 928          echo '<div class="title">';
 929          echo '<img src="' . $OUTPUT->pix_url('icon', 'assign') . '" '.
 930               'class="icon" alt="' . $modname . '">';
 931          echo '<a href="' . $CFG->wwwroot . '/mod/assign/view.php?id=' . $activity->cmid . '">';
 932          echo $activity->name;
 933          echo '</a>';
 934          echo '</div>';
 935      }
 936  
 937      if (isset($activity->grade)) {
 938          echo '<div class="grade">';
 939          echo get_string('grade').': ';
 940          echo $activity->grade;
 941          echo '</div>';
 942      }
 943  
 944      echo '<div class="user">';
 945      echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->id}&amp;course=$courseid\">";
 946      echo "{$activity->user->fullname}</a>  - " . userdate($activity->timestamp);
 947      echo '</div>';
 948  
 949      echo '</td></tr></table>';
 950  }
 951  
 952  /**
 953   * Checks if a scale is being used by an assignment.
 954   *
 955   * This is used by the backup code to decide whether to back up a scale
 956   * @param int $assignmentid
 957   * @param int $scaleid
 958   * @return boolean True if the scale is used by the assignment
 959   */
 960  function assign_scale_used($assignmentid, $scaleid) {
 961      global $DB;
 962  
 963      $return = false;
 964      $rec = $DB->get_record('assign', array('id'=>$assignmentid, 'grade'=>-$scaleid));
 965  
 966      if (!empty($rec) && !empty($scaleid)) {
 967          $return = true;
 968      }
 969  
 970      return $return;
 971  }
 972  
 973  /**
 974   * Checks if scale is being used by any instance of assignment
 975   *
 976   * This is used to find out if scale used anywhere
 977   * @param int $scaleid
 978   * @return boolean True if the scale is used by any assignment
 979   */
 980  function assign_scale_used_anywhere($scaleid) {
 981      global $DB;
 982  
 983      if ($scaleid and $DB->record_exists('assign', array('grade'=>-$scaleid))) {
 984          return true;
 985      } else {
 986          return false;
 987      }
 988  }
 989  
 990  /**
 991   * List the actions that correspond to a view of this module.
 992   * This is used by the participation report.
 993   *
 994   * Note: This is not used by new logging system. Event with
 995   *       crud = 'r' and edulevel = LEVEL_PARTICIPATING will
 996   *       be considered as view action.
 997   *
 998   * @return array
 999   */
1000  function assign_get_view_actions() {
1001      return array('view submission', 'view feedback');
1002  }
1003  
1004  /**
1005   * List the actions that correspond to a post of this module.
1006   * This is used by the participation report.
1007   *
1008   * Note: This is not used by new logging system. Event with
1009   *       crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING
1010   *       will be considered as post action.
1011   *
1012   * @return array
1013   */
1014  function assign_get_post_actions() {
1015      return array('upload', 'submit', 'submit for grading');
1016  }
1017  
1018  /**
1019   * Call cron on the assign module.
1020   */
1021  function assign_cron() {
1022      global $CFG;
1023  
1024      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1025      assign::cron();
1026  
1027      $plugins = core_component::get_plugin_list('assignsubmission');
1028  
1029      foreach ($plugins as $name => $plugin) {
1030          $disabled = get_config('assignsubmission_' . $name, 'disabled');
1031          if (!$disabled) {
1032              $class = 'assign_submission_' . $name;
1033              require_once($CFG->dirroot . '/mod/assign/submission/' . $name . '/locallib.php');
1034              $class::cron();
1035          }
1036      }
1037      $plugins = core_component::get_plugin_list('assignfeedback');
1038  
1039      foreach ($plugins as $name => $plugin) {
1040          $disabled = get_config('assignfeedback_' . $name, 'disabled');
1041          if (!$disabled) {
1042              $class = 'assign_feedback_' . $name;
1043              require_once($CFG->dirroot . '/mod/assign/feedback/' . $name . '/locallib.php');
1044              $class::cron();
1045          }
1046      }
1047  
1048      return true;
1049  }
1050  
1051  /**
1052   * Returns all other capabilities used by this module.
1053   * @return array Array of capability strings
1054   */
1055  function assign_get_extra_capabilities() {
1056      return array('gradereport/grader:view',
1057                   'moodle/grade:viewall',
1058                   'moodle/site:viewfullnames',
1059                   'moodle/site:config');
1060  }
1061  
1062  /**
1063   * Create grade item for given assignment.
1064   *
1065   * @param stdClass $assign record with extra cmidnumber
1066   * @param array $grades optional array/object of grade(s); 'reset' means reset grades in gradebook
1067   * @return int 0 if ok, error code otherwise
1068   */
1069  function assign_grade_item_update($assign, $grades=null) {
1070      global $CFG;
1071      require_once($CFG->libdir.'/gradelib.php');
1072  
1073      if (!isset($assign->courseid)) {
1074          $assign->courseid = $assign->course;
1075      }
1076  
1077      $params = array('itemname'=>$assign->name, 'idnumber'=>$assign->cmidnumber);
1078  
1079      // Check if feedback plugin for gradebook is enabled, if yes then
1080      // gradetype = GRADE_TYPE_TEXT else GRADE_TYPE_NONE.
1081      $gradefeedbackenabled = false;
1082  
1083      if (isset($assign->gradefeedbackenabled)) {
1084          $gradefeedbackenabled = $assign->gradefeedbackenabled;
1085      } else if ($assign->grade == 0) { // Grade feedback is needed only when grade == 0.
1086          require_once($CFG->dirroot . '/mod/assign/locallib.php');
1087          $mod = get_coursemodule_from_instance('assign', $assign->id, $assign->courseid);
1088          $cm = context_module::instance($mod->id);
1089          $assignment = new assign($cm, null, null);
1090          $gradefeedbackenabled = $assignment->is_gradebook_feedback_enabled();
1091      }
1092  
1093      if ($assign->grade > 0) {
1094          $params['gradetype'] = GRADE_TYPE_VALUE;
1095          $params['grademax']  = $assign->grade;
1096          $params['grademin']  = 0;
1097  
1098      } else if ($assign->grade < 0) {
1099          $params['gradetype'] = GRADE_TYPE_SCALE;
1100          $params['scaleid']   = -$assign->grade;
1101  
1102      } else if ($gradefeedbackenabled) {
1103          // $assign->grade == 0 and feedback enabled.
1104          $params['gradetype'] = GRADE_TYPE_TEXT;
1105      } else {
1106          // $assign->grade == 0 and no feedback enabled.
1107          $params['gradetype'] = GRADE_TYPE_NONE;
1108      }
1109  
1110      if ($grades  === 'reset') {
1111          $params['reset'] = true;
1112          $grades = null;
1113      }
1114  
1115      return grade_update('mod/assign',
1116                          $assign->courseid,
1117                          'mod',
1118                          'assign',
1119                          $assign->id,
1120                          0,
1121                          $grades,
1122                          $params);
1123  }
1124  
1125  /**
1126   * Return grade for given user or all users.
1127   *
1128   * @param stdClass $assign record of assign with an additional cmidnumber
1129   * @param int $userid optional user id, 0 means all users
1130   * @return array array of grades, false if none
1131   */
1132  function assign_get_user_grades($assign, $userid=0) {
1133      global $CFG;
1134  
1135      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1136  
1137      $cm = get_coursemodule_from_instance('assign', $assign->id, 0, false, MUST_EXIST);
1138      $context = context_module::instance($cm->id);
1139      $assignment = new assign($context, null, null);
1140      $assignment->set_instance($assign);
1141      return $assignment->get_user_grades_for_gradebook($userid);
1142  }
1143  
1144  /**
1145   * Update activity grades.
1146   *
1147   * @param stdClass $assign database record
1148   * @param int $userid specific user only, 0 means all
1149   * @param bool $nullifnone - not used
1150   */
1151  function assign_update_grades($assign, $userid=0, $nullifnone=true) {
1152      global $CFG;
1153      require_once($CFG->libdir.'/gradelib.php');
1154  
1155      if ($assign->grade == 0) {
1156          assign_grade_item_update($assign);
1157  
1158      } else if ($grades = assign_get_user_grades($assign, $userid)) {
1159          foreach ($grades as $k => $v) {
1160              if ($v->rawgrade == -1) {
1161                  $grades[$k]->rawgrade = null;
1162              }
1163          }
1164          assign_grade_item_update($assign, $grades);
1165  
1166      } else {
1167          assign_grade_item_update($assign);
1168      }
1169  }
1170  
1171  /**
1172   * List the file areas that can be browsed.
1173   *
1174   * @param stdClass $course
1175   * @param stdClass $cm
1176   * @param stdClass $context
1177   * @return array
1178   */
1179  function assign_get_file_areas($course, $cm, $context) {
1180      global $CFG;
1181      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1182  
1183      $areas = array(ASSIGN_INTROATTACHMENT_FILEAREA => get_string('introattachments', 'mod_assign'));
1184  
1185      $assignment = new assign($context, $cm, $course);
1186      foreach ($assignment->get_submission_plugins() as $plugin) {
1187          if ($plugin->is_visible()) {
1188              $pluginareas = $plugin->get_file_areas();
1189  
1190              if ($pluginareas) {
1191                  $areas = array_merge($areas, $pluginareas);
1192              }
1193          }
1194      }
1195      foreach ($assignment->get_feedback_plugins() as $plugin) {
1196          if ($plugin->is_visible()) {
1197              $pluginareas = $plugin->get_file_areas();
1198  
1199              if ($pluginareas) {
1200                  $areas = array_merge($areas, $pluginareas);
1201              }
1202          }
1203      }
1204  
1205      return $areas;
1206  }
1207  
1208  /**
1209   * File browsing support for assign module.
1210   *
1211   * @param file_browser $browser
1212   * @param object $areas
1213   * @param object $course
1214   * @param object $cm
1215   * @param object $context
1216   * @param string $filearea
1217   * @param int $itemid
1218   * @param string $filepath
1219   * @param string $filename
1220   * @return object file_info instance or null if not found
1221   */
1222  function assign_get_file_info($browser,
1223                                $areas,
1224                                $course,
1225                                $cm,
1226                                $context,
1227                                $filearea,
1228                                $itemid,
1229                                $filepath,
1230                                $filename) {
1231      global $CFG;
1232      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1233  
1234      if ($context->contextlevel != CONTEXT_MODULE) {
1235          return null;
1236      }
1237  
1238      $urlbase = $CFG->wwwroot.'/pluginfile.php';
1239      $fs = get_file_storage();
1240      $filepath = is_null($filepath) ? '/' : $filepath;
1241      $filename = is_null($filename) ? '.' : $filename;
1242  
1243      // Need to find where this belongs to.
1244      $assignment = new assign($context, $cm, $course);
1245      if ($filearea === ASSIGN_INTROATTACHMENT_FILEAREA) {
1246          if (!has_capability('moodle/course:managefiles', $context)) {
1247              // Students can not peak here!
1248              return null;
1249          }
1250          if (!($storedfile = $fs->get_file($assignment->get_context()->id,
1251                                            'mod_assign', $filearea, 0, $filepath, $filename))) {
1252              return null;
1253          }
1254          return new file_info_stored($browser,
1255                          $assignment->get_context(),
1256                          $storedfile,
1257                          $urlbase,
1258                          $filearea,
1259                          $itemid,
1260                          true,
1261                          true,
1262                          false);
1263      }
1264  
1265      $pluginowner = null;
1266      foreach ($assignment->get_submission_plugins() as $plugin) {
1267          if ($plugin->is_visible()) {
1268              $pluginareas = $plugin->get_file_areas();
1269  
1270              if (array_key_exists($filearea, $pluginareas)) {
1271                  $pluginowner = $plugin;
1272                  break;
1273              }
1274          }
1275      }
1276      if (!$pluginowner) {
1277          foreach ($assignment->get_feedback_plugins() as $plugin) {
1278              if ($plugin->is_visible()) {
1279                  $pluginareas = $plugin->get_file_areas();
1280  
1281                  if (array_key_exists($filearea, $pluginareas)) {
1282                      $pluginowner = $plugin;
1283                      break;
1284                  }
1285              }
1286          }
1287      }
1288  
1289      if (!$pluginowner) {
1290          return null;
1291      }
1292  
1293      $result = $pluginowner->get_file_info($browser, $filearea, $itemid, $filepath, $filename);
1294      return $result;
1295  }
1296  
1297  /**
1298   * Prints the complete info about a user's interaction with an assignment.
1299   *
1300   * @param stdClass $course
1301   * @param stdClass $user
1302   * @param stdClass $coursemodule
1303   * @param stdClass $assign the database assign record
1304   *
1305   * This prints the submission summary and feedback summary for this student.
1306   */
1307  function assign_user_complete($course, $user, $coursemodule, $assign) {
1308      global $CFG;
1309      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1310  
1311      $context = context_module::instance($coursemodule->id);
1312  
1313      $assignment = new assign($context, $coursemodule, $course);
1314  
1315      echo $assignment->view_student_summary($user, false);
1316  }
1317  
1318  /**
1319   * Rescale all grades for this activity and push the new grades to the gradebook.
1320   *
1321   * @param stdClass $course Course db record
1322   * @param stdClass $cm Course module db record
1323   * @param float $oldmin
1324   * @param float $oldmax
1325   * @param float $newmin
1326   * @param float $newmax
1327   */
1328  function assign_rescale_activity_grades($course, $cm, $oldmin, $oldmax, $newmin, $newmax) {
1329      global $DB;
1330  
1331      if ($oldmax <= $oldmin) {
1332          // Grades cannot be scaled.
1333          return false;
1334      }
1335      $scale = ($newmax - $newmin) / ($oldmax - $oldmin);
1336      if (($newmax - $newmin) <= 1) {
1337          // We would lose too much precision, lets bail.
1338          return false;
1339      }
1340  
1341      $params = array(
1342          'p1' => $oldmin,
1343          'p2' => $scale,
1344          'p3' => $newmin,
1345          'a' => $cm->instance
1346      );
1347  
1348      $sql = 'UPDATE {assign_grades} set grade = (((grade - :p1) * :p2) + :p3) where assignment = :a';
1349      $dbupdate = $DB->execute($sql, $params);
1350      if (!$dbupdate) {
1351          return false;
1352      }
1353  
1354      // Now re-push all grades to the gradebook.
1355      $dbparams = array('id' => $cm->instance);
1356      $assign = $DB->get_record('assign', $dbparams);
1357      $assign->cmidnumber = $cm->idnumber;
1358  
1359      assign_update_grades($assign);
1360  
1361      return true;
1362  }
1363  
1364  /**
1365   * Print the grade information for the assignment for this user.
1366   *
1367   * @param stdClass $course
1368   * @param stdClass $user
1369   * @param stdClass $coursemodule
1370   * @param stdClass $assignment
1371   */
1372  function assign_user_outline($course, $user, $coursemodule, $assignment) {
1373      global $CFG;
1374      require_once($CFG->libdir.'/gradelib.php');
1375      require_once($CFG->dirroot.'/grade/grading/lib.php');
1376  
1377      $gradinginfo = grade_get_grades($course->id,
1378                                          'mod',
1379                                          'assign',
1380                                          $assignment->id,
1381                                          $user->id);
1382  
1383      $gradingitem = $gradinginfo->items[0];
1384      $gradebookgrade = $gradingitem->grades[$user->id];
1385  
1386      if (empty($gradebookgrade->str_long_grade)) {
1387          return null;
1388      }
1389      $result = new stdClass();
1390      $result->info = get_string('outlinegrade', 'assign', $gradebookgrade->str_long_grade);
1391      $result->time = $gradebookgrade->dategraded;
1392  
1393      return $result;
1394  }
1395  
1396  /**
1397   * Obtains the automatic completion state for this module based on any conditions
1398   * in assign settings.
1399   *
1400   * @param object $course Course
1401   * @param object $cm Course-module
1402   * @param int $userid User ID
1403   * @param bool $type Type of comparison (or/and; can be used as return value if no conditions)
1404   * @return bool True if completed, false if not, $type if conditions not set.
1405   */
1406  function assign_get_completion_state($course, $cm, $userid, $type) {
1407      global $CFG, $DB;
1408      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1409  
1410      $assign = new assign(null, $cm, $course);
1411  
1412      // If completion option is enabled, evaluate it and return true/false.
1413      if ($assign->get_instance()->completionsubmit) {
1414          if ($assign->get_instance()->teamsubmission) {
1415              $submission = $assign->get_group_submission($userid, 0, false);
1416          } else {
1417              $submission = $assign->get_user_submission($userid, false);
1418          }
1419          return $submission && $submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED;
1420      } else {
1421          // Completion option is not enabled so just return $type.
1422          return $type;
1423      }
1424  }
1425  
1426  /**
1427   * Serves intro attachment files.
1428   *
1429   * @param mixed $course course or id of the course
1430   * @param mixed $cm course module or id of the course module
1431   * @param context $context
1432   * @param string $filearea
1433   * @param array $args
1434   * @param bool $forcedownload
1435   * @param array $options additional options affecting the file serving
1436   * @return bool false if file not found, does not return if found - just send the file
1437   */
1438  function assign_pluginfile($course,
1439                  $cm,
1440                  context $context,
1441                  $filearea,
1442                  $args,
1443                  $forcedownload,
1444                  array $options=array()) {
1445      global $CFG;
1446  
1447      if ($context->contextlevel != CONTEXT_MODULE) {
1448          return false;
1449      }
1450  
1451      require_login($course, false, $cm);
1452      if (!has_capability('mod/assign:view', $context)) {
1453          return false;
1454      }
1455  
1456      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1457      $assign = new assign($context, $cm, $course);
1458  
1459      if ($filearea !== ASSIGN_INTROATTACHMENT_FILEAREA) {
1460          return false;
1461      }
1462      if (!$assign->show_intro()) {
1463          return false;
1464      }
1465  
1466      $itemid = (int)array_shift($args);
1467      if ($itemid != 0) {
1468          return false;
1469      }
1470  
1471      $relativepath = implode('/', $args);
1472  
1473      $fullpath = "/{$context->id}/mod_assign/$filearea/$itemid/$relativepath";
1474  
1475      $fs = get_file_storage();
1476      if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
1477          return false;
1478      }
1479      send_stored_file($file, 0, 0, $forcedownload, $options);
1480  }
1481  
1482  /**
1483   * Serve the grading panel as a fragment.
1484   *
1485   * @param array $args List of named arguments for the fragment loader.
1486   * @return string
1487   */
1488  function mod_assign_output_fragment_gradingpanel($args) {
1489      global $CFG;
1490  
1491      $context = $args['context'];
1492  
1493      if ($context->contextlevel != CONTEXT_MODULE) {
1494          return null;
1495      }
1496      require_once($CFG->dirroot . '/mod/assign/locallib.php');
1497      $assign = new assign($context, null, null);
1498  
1499      $userid = clean_param($args['userid'], PARAM_INT);
1500      $attemptnumber = clean_param($args['attemptnumber'], PARAM_INT);
1501      $formdata = array();
1502      if (!empty($args['jsonformdata'])) {
1503          $serialiseddata = json_decode($args['jsonformdata']);
1504          parse_str($serialiseddata, $formdata);
1505      }
1506      $viewargs = array(
1507          'userid' => $userid,
1508          'attemptnumber' => $attemptnumber,
1509          'formdata' => $formdata
1510      );
1511  
1512      return $assign->view('gradingpanel', $viewargs);
1513  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1