Exemplo n.º 1
0
 public function is_available($not, \core_availability\info $info, $grabthelot, $userid)
 {
     $modinfo = $info->get_modinfo();
     $completion = new \completion_info($modinfo->get_course());
     if (!array_key_exists($this->cmid, $modinfo->cms)) {
         // If the cmid cannot be found, always return false regardless
         // of the condition or $not state. (Will be displayed in the
         // information message.)
         $allow = false;
     } else {
         // The completion system caches its own data so no caching needed here.
         $completiondata = $completion->get_data((object) array('id' => $this->cmid), $grabthelot, $userid, $modinfo);
         $allow = true;
         if ($this->expectedcompletion == COMPLETION_COMPLETE) {
             // Complete also allows the pass, fail states.
             switch ($completiondata->completionstate) {
                 case COMPLETION_COMPLETE:
                 case COMPLETION_COMPLETE_FAIL:
                 case COMPLETION_COMPLETE_PASS:
                     break;
                 default:
                     $allow = false;
             }
         } else {
             // Other values require exact match.
             if ($completiondata->completionstate != $this->expectedcompletion) {
                 $allow = false;
             }
         }
         if ($not) {
             $allow = !$allow;
         }
     }
     return $allow;
 }
Exemplo n.º 2
0
 /**
  * Taken from /format/renderer.php
  * Generate a summary of the activites in a section
  *
  * @param stdClass $section The course_section entry from DB
  * @param stdClass $course the course record from DB
  * @param array    $mods (argument not used)
  * @return string HTML to output.
  */
 public static function section_activity_summary($section, $course, $mods)
 {
     global $CFG;
     require_once $CFG->libdir . '/completionlib.php';
     $modinfo = get_fast_modinfo($course);
     if (empty($modinfo->sections[$section->section])) {
         return '';
     }
     // Generate array with count of activities in this section.
     $sectionmods = array();
     $total = 0;
     $complete = 0;
     $cancomplete = isloggedin() && !isguestuser();
     $completioninfo = new completion_info($course);
     foreach ($modinfo->sections[$section->section] as $cmid) {
         $thismod = $modinfo->cms[$cmid];
         if ($thismod->uservisible) {
             if (isset($sectionmods[$thismod->modname])) {
                 $sectionmods[$thismod->modname]['name'] = $thismod->modplural;
                 $sectionmods[$thismod->modname]['count']++;
             } else {
                 $sectionmods[$thismod->modname]['name'] = $thismod->modfullname;
                 $sectionmods[$thismod->modname]['count'] = 1;
             }
             if ($cancomplete && $completioninfo->is_enabled($thismod) != COMPLETION_TRACKING_NONE) {
                 $total++;
                 $completiondata = $completioninfo->get_data($thismod, true);
                 if ($completiondata->completionstate == COMPLETION_COMPLETE || $completiondata->completionstate == COMPLETION_COMPLETE_PASS) {
                     $complete++;
                 }
             }
         }
     }
     if (empty($sectionmods)) {
         // No sections.
         return '';
     }
     // Output section activities summary.
     $o = '';
     $o .= "<div class='section-summary-activities mdl-right'>";
     foreach ($sectionmods as $mod) {
         $o .= "<span class='activity-count'>";
         $o .= $mod['name'] . ': ' . $mod['count'];
         $o .= "</span>";
     }
     $o .= "</div>";
     $a = false;
     // Output section completion data.
     if ($total > 0) {
         $a = new stdClass();
         $a->complete = $complete;
         $a->total = $total;
         $a->percentage = $complete / $total * 100;
         $o .= "<div class='section-summary-activities mdl-right'>";
         $o .= "<span class='activity-count'>" . get_string('progresstotal', 'completion', $a) . "</span>";
         $o .= "</div>";
     }
     $retobj = (object) array('output' => $o, 'progress' => $a, 'complete' => $complete, 'total' => $total);
     return $retobj;
 }
Exemplo n.º 3
0
 /**
  * toc progress percentage
  * @param stdClass $section
  * @param stdClass $course
  * @param boolean $perc - display as a percentage if true
  * @return string
  *
  * @Author Guy Thomas
  * @Date 2014-05-23
  */
 protected function toc_progress($section, $course, $perc = false)
 {
     global $CFG, $OUTPUT;
     require_once $CFG->libdir . '/completionlib.php';
     $completioninfo = new completion_info($course);
     if (!$completioninfo->is_enabled()) {
         return '';
         // Completion tracking not enabled.
     }
     $sac = snap_shared::section_activity_summary($section, $course, null);
     if (!empty($sac->progress)) {
         if ($perc) {
             $percentage = $sac->progress->percentage != null ? round($sac->progress->percentage, 0) . '%' : '';
             return '<span class="completionstatus percentage">' . $percentage . '</span>';
         } else {
             if ($sac->progress->total > 0) {
                 $progress = get_string('progresstotal', 'completion', $sac->progress);
                 $completed = '';
                 if ($sac->progress->complete === $sac->progress->total) {
                     $winbadge = $OUTPUT->pix_url('i/completion-manual-y');
                     $completedstr = s(get_string('completed', 'completion'));
                     $completed = "<img class=snap-section-complete src='{$winbadge}' alt='{$completedstr}' />";
                 }
                 $printprogress = "<span class='completionstatus outoftotal'>{$completed} {$progress}</span>";
                 return $printprogress;
             } else {
                 return '';
             }
         }
     }
 }
Exemplo n.º 4
0
 /**
  * Test update_activity_completion_status_manually
  */
 public function test_update_activity_completion_status_manually()
 {
     global $DB, $CFG;
     $this->resetAfterTest(true);
     $CFG->enablecompletion = true;
     $user = $this->getDataGenerator()->create_user();
     $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
     $data = $this->getDataGenerator()->create_module('data', array('course' => $course->id), array('completion' => 1));
     $cm = get_coursemodule_from_id('data', $data->cmid);
     $studentrole = $DB->get_record('role', array('shortname' => 'student'));
     $this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
     $this->setUser($user);
     $result = core_completion_external::update_activity_completion_status_manually($data->cmid, true);
     // We need to execute the return values cleaning process to simulate the web service server.
     $result = external_api::clean_returnvalue(core_completion_external::update_activity_completion_status_manually_returns(), $result);
     // Check in DB.
     $this->assertEquals(1, $DB->get_field('course_modules_completion', 'completionstate', array('coursemoduleid' => $data->cmid)));
     // Check using the API.
     $completion = new completion_info($course);
     $completiondata = $completion->get_data($cm);
     $this->assertEquals(1, $completiondata->completionstate);
     $this->assertTrue($result['status']);
     $result = core_completion_external::update_activity_completion_status_manually($data->cmid, false);
     // We need to execute the return values cleaning process to simulate the web service server.
     $result = external_api::clean_returnvalue(core_completion_external::update_activity_completion_status_manually_returns(), $result);
     $this->assertEquals(0, $DB->get_field('course_modules_completion', 'completionstate', array('coursemoduleid' => $data->cmid)));
     $completiondata = $completion->get_data($cm);
     $this->assertEquals(0, $completiondata->completionstate);
     $this->assertTrue($result['status']);
 }
/**
 * Check if an activity is configured to only show navbuttons when
 * complete and then check if the activity is complete
 * @param cm_info $cm the course module for the activity
 * @return boolean true if the navbuttons should be shown
 */
function navbuttons_activity_showbuttons($cm)
{
    $modname = $cm->modname;
    $show = get_config('block_navbuttons', 'activity' . $modname);
    if ($show === false || $show == NAVBUTTONS_ACTIVITY_ALWAYS) {
        return true;
        // No config or 'always show'
    }
    if ($show == NAVBUTTONS_ACTIVITY_NEVER) {
        return false;
    }
    if ($show == NAVBUTTONS_ACTIVITY_COMPLETE) {
        $completion = new completion_info($cm->get_course());
        if (!$completion->is_enabled($cm)) {
            return true;
            // No completion tracking - show the buttons
        }
        $cmcompletion = $completion->get_data($cm);
        if ($cmcompletion->completionstate == COMPLETION_INCOMPLETE) {
            return false;
        }
        return true;
    }
    if (!isloggedin() || isguestuser()) {
        return true;
        // Always show the buttons if not logged in
    }
    // NAVBUTTONS_ACTIVITY_CUSTOM
    $funcname = 'navbuttons_mod_' . $modname . '_showbuttons';
    if (!function_exists($funcname)) {
        return true;
        // Shouldn't have got to here, but allow the buttons anyway
    }
    return $funcname($cm);
}
Exemplo n.º 6
0
 /**
  * Test survey_view
  * @return void
  */
 public function test_survey_view()
 {
     global $CFG;
     $CFG->enablecompletion = 1;
     $this->resetAfterTest();
     $this->setAdminUser();
     // Setup test data.
     $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
     $survey = $this->getDataGenerator()->create_module('survey', array('course' => $course->id), array('completion' => 2, 'completionview' => 1));
     $context = context_module::instance($survey->cmid);
     $cm = get_coursemodule_from_instance('survey', $survey->id);
     // Trigger and capture the event.
     $sink = $this->redirectEvents();
     survey_view($survey, $course, $cm, $context, 'form');
     $events = $sink->get_events();
     // 2 additional events thanks to completion.
     $this->assertCount(3, $events);
     $event = array_shift($events);
     // Checking that the event contains the expected values.
     $this->assertInstanceOf('\\mod_survey\\event\\course_module_viewed', $event);
     $this->assertEquals($context, $event->get_context());
     $moodleurl = new \moodle_url('/mod/survey/view.php', array('id' => $cm->id));
     $this->assertEquals($moodleurl, $event->get_url());
     $this->assertEquals('form', $event->other['viewed']);
     $this->assertEventContextNotUsed($event);
     $this->assertNotEmpty($event->get_name());
     // Check completion status.
     $completion = new completion_info($course);
     $completiondata = $completion->get_data($cm);
     $this->assertEquals(1, $completiondata->completionstate);
 }
Exemplo n.º 7
0
 /**
  * Update completion status for the current user in an activity, only for activities with manual tracking.
  * @param  int $cmid      Course module id
  * @param  bool $completed Activity completed or not
  * @return array            Result and possible warnings
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function update_activity_completion_status_manually($cmid, $completed)
 {
     // Validate and normalize parameters.
     $params = self::validate_parameters(self::update_activity_completion_status_manually_parameters(), array('cmid' => $cmid, 'completed' => $completed));
     $cmid = $params['cmid'];
     $completed = $params['completed'];
     $warnings = array();
     $context = context_module::instance($cmid);
     self::validate_context($context);
     list($course, $cm) = get_course_and_cm_from_cmid($cmid);
     // Set up completion object and check it is enabled.
     $completion = new completion_info($course);
     if (!$completion->is_enabled()) {
         throw new moodle_exception('completionnotenabled', 'completion');
     }
     // Check completion state is manual.
     if ($cm->completion != COMPLETION_TRACKING_MANUAL) {
         throw new moodle_exception('cannotmanualctrack', 'error');
     }
     $targetstate = $completed ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE;
     $completion->update_state($cm, $targetstate);
     $result = array();
     $result['status'] = true;
     $result['warnings'] = $warnings;
     return $result;
 }
Exemplo n.º 8
0
    function execute($data, $row, $user, $courseid, $starttime = 0, $endtime = 0) {
        global $DB, $CFG;

        require_once("{$CFG->libdir}/completionlib.php");

        $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);

        $info = new completion_info($course);

        // Is course complete?
        $coursecomplete = $info->is_course_complete($row->id);

        // Load course completion.
        $params = array(
            'userid' => $row->id,
            'course' => $course->id
        );
        $ccompletion = new completion_completion($params);

        // Has this user completed any criteria?
        $criteriacomplete = $info->count_course_user_data($row->id);

        $content = "";
        if ($coursecomplete) {
            $content .= get_string('complete');
        } else if (!$criteriacomplete && !$ccompletion->timestarted) {
            $content .= html_writer::tag('i', get_string('notyetstarted', 'completion'));
        } else {
            $content .= html_writer::tag('i', get_string('inprogress', 'completion'));
        }
        return $content;
    }
 public function execute()
 {
     global $DB, $CFG;
     $result = $DB->get_records_sql('SELECT ba.id, ba.bookingid, ba.optionid, ba.userid, b.course
         FROM {booking_answers} AS ba
         LEFT JOIN {booking_options} AS bo 
         ON bo.id = ba.optionid
         LEFT JOIN {booking} AS b
         ON b.id = bo.bookingid
         WHERE bo.removeafterminutes > 0
         AND ba.completed = 1
         AND IF(ba.timemodified < (UNIX_TIMESTAMP() - (bo.removeafterminutes*60)), 1, 0) = 1;');
     require_once $CFG->libdir . '/completionlib.php';
     foreach ($result as $value) {
         $course = $DB->get_record('course', array('id' => $value->course));
         $completion = new \completion_info($course);
         $cm = get_coursemodule_from_instance('booking', $value->bookingid);
         $userData = $DB->get_record('booking_answers', array('id' => $value->id));
         $booking = $DB->get_record('booking', array('id' => $value->bookingid));
         $userData->completed = '0';
         $userData->timemodified = time();
         $DB->update_record('booking_answers', $userData);
         if ($completion->is_enabled($cm) && $booking->enablecompletion) {
             $completion->update_state($cm, COMPLETION_INCOMPLETE, $userData->userid);
         }
     }
 }
 public function get_content()
 {
     global $CFG, $USER;
     // If content is cached
     if ($this->content !== NULL) {
         return $this->content;
     }
     // Create empty content
     $this->content = new stdClass();
     // Can edit settings?
     $can_edit = has_capability('moodle/course:update', get_context_instance(CONTEXT_COURSE, $this->page->course->id));
     // Get course completion data
     $info = new completion_info($this->page->course);
     // Don't display if completion isn't enabled!
     if (!completion_info::is_enabled_for_site()) {
         if ($can_edit) {
             $this->content->text = get_string('completionnotenabledforsite', 'completion');
         }
         return $this->content;
     } else {
         if (!$info->is_enabled()) {
             if ($can_edit) {
                 $this->content->text = get_string('completionnotenabledforcourse', 'completion');
             }
             return $this->content;
         }
     }
     // Get this user's data
     $completion = $info->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF);
     // Check if self completion is one of this course's criteria
     if (empty($completion)) {
         if ($can_edit) {
             $this->content->text = get_string('selfcompletionnotenabled', 'block_selfcompletion');
         }
         return $this->content;
     }
     // Check this user is enroled
     if (!$info->is_tracked_user($USER->id)) {
         $this->content->text = get_string('notenroled', 'completion');
         return $this->content;
     }
     // Is course complete?
     if ($info->is_course_complete($USER->id)) {
         $this->content->text = get_string('coursealreadycompleted', 'completion');
         return $this->content;
         // Check if the user has already marked themselves as complete
     } else {
         if ($completion->is_complete()) {
             $this->content->text = get_string('alreadyselfcompleted', 'block_selfcompletion');
             return $this->content;
             // If user is not complete, or has not yet self completed
         } else {
             $this->content->text = '';
             $this->content->footer = '<br /><a href="' . $CFG->wwwroot . '/course/togglecompletion.php?course=' . $this->page->course->id . '">';
             $this->content->footer .= get_string('completecourse', 'block_selfcompletion') . '</a>...';
         }
     }
     return $this->content;
 }
Exemplo n.º 11
0
/**
 * This function extends the navigation with the report items
 *
 * @param navigation_node $navigation The navigation node to extend
 * @param stdClass $course The course to object for the report
 * @param stdClass $context The context of the course
 */
function completion_report_extend_navigation($navigation, $course, $context)
{
    global $CFG, $OUTPUT;
    if (has_capability('coursereport/completion:view', $context)) {
        $completion = new completion_info($course);
        if ($completion->is_enabled() && $completion->has_criteria()) {
            $url = new moodle_url('/course/report/completion/index.php', array('course' => $course->id));
            $navigation->add(get_string('pluginname', 'coursereport_completion'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/report', ''));
        }
    }
}
Exemplo n.º 12
0
 protected function allow_add($course, \cm_info $cm = null, \section_info $section = null)
 {
     global $CFG;
     // Check if completion is enabled for the course.
     require_once $CFG->libdir . '/completionlib.php';
     $info = new \completion_info($course);
     if (!$info->is_enabled()) {
         return false;
     }
     // Check if there's at least one other module with completion info.
     $params = $this->get_javascript_init_params($course, $cm, $section);
     return (array) $params[0] != false;
 }
Exemplo n.º 13
0
 public function course_completion_gauge(&$course, $div, $width = 160, $height = 160, $type = 'progressbar')
 {
     global $USER, $PAGE;
     $str = '';
     $completion = new completion_info($course);
     if ($completion->is_enabled(null)) {
         $alltracked = count($completion->get_activities());
         $progressinfo = $completion->get_progress_all('u.id = :userid', array('userid' => $USER->id));
         $completed = 0;
         if (!empty($progressinfo)) {
             if (!empty($progressinfo[$USER->id]->progress)) {
                 foreach ($progressinfo[$USER->id]->progress as $progressrecord) {
                     if ($progressrecord->completionstate) {
                         $completed++;
                     }
                 }
             }
         }
         $ratio = $alltracked == 0 ? 0 : round($completed / $alltracked * 100);
         $jqwrenderer = $PAGE->get_renderer('local_vflibs');
         if ($div == 'div') {
             $str .= '<div class="course-completion" title="' . get_string('completion', 'local_my', 0 + $ratio) . '">';
         } else {
             $str .= '<td class="course-completion" title="' . get_string('completion', 'local_my', 0 + $ratio) . '">';
         }
         if ($type == 'gauge') {
             $properties = array('width' => $width, 'height' => $height, 'max' => 100, 'crop' => 120);
             $str .= $jqwrenderer->jqw_bargauge_simple('completion-jqw-' . $course->id, array($ratio), $properties);
         } else {
             $properties = array('width' => $width, 'height' => $height, 'animation' => 300, 'template' => 'success');
             $str .= $jqwrenderer->jqw_progress_bar('completion-jqw-' . $course->id, $ratio, $properties);
         }
         if ($div == 'div') {
             $str .= '</div>';
         } else {
             $str .= '</td>';
         }
     } else {
         if ($div == 'div') {
             $str .= '<div class="course-completion">';
         } else {
             $str .= '<td class="course-completion">';
         }
         if ($div == 'div') {
             $str .= '</div>';
         } else {
             $str .= '</td>';
         }
     }
     return $str;
 }
 /**
  * Routes to a valid action.
  *
  * @param string $action
  * @access public
  * @return string Rendered output for display.
  */
 public function display_action($action)
 {
     $this->renderer->setup_page($this);
     $method = "action_{$action}";
     if (!method_exists(__CLASS__, $method)) {
         throw new \invalid_parameter_exception("Unknown action: {$action}");
     }
     $output = $this->{$method}();
     $completion = new \completion_info($this->course);
     $completion->set_module_viewed($this->cm);
     $header = $this->header();
     $footer = $this->renderer->footer();
     return $header . $output . $footer;
 }
Exemplo n.º 15
0
/**
 * This function extends the navigation with the report items
 *
 * @param navigation_node $navigation The navigation node to extend
 * @param stdClass $course The course to object for the report
 * @param stdClass $context The context of the course
 */
function progress_report_extend_navigation($navigation, $course, $context)
{
    global $CFG, $OUTPUT;
    $showonnavigation = has_capability('coursereport/progress:view', $context);
    $group = groups_get_course_group($course, true);
    // Supposed to verify group
    if ($group === 0 && $course->groupmode == SEPARATEGROUPS) {
        $showonnavigation = $showonnavigation && has_capability('moodle/site:accessallgroups', $context);
    }
    $completion = new completion_info($course);
    $showonnavigation = $showonnavigation && $completion->is_enabled() && count($completion->get_activities()) > 0;
    if ($showonnavigation) {
        $url = new moodle_url('/course/report/progress/index.php', array('course' => $course->id));
        $navigation->add(get_string('pluginname', 'coursereport_progress'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/report', ''));
    }
}
 function test_has_activities()
 {
     global $DB;
     $this->resetAfterTest(true);
     // Create a course with mixed auto completion data.
     $course = $this->getDataGenerator()->create_course();
     $course2 = $this->getDataGenerator()->create_course();
     $completionauto = array('completion' => COMPLETION_TRACKING_AUTOMATIC);
     $completionnone = array('completion' => COMPLETION_TRACKING_NONE);
     $c1forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id), $completionauto);
     $c2forum = $this->getDataGenerator()->create_module('forum', array('course' => $course2->id), $completionnone);
     $c1 = new completion_info($course);
     $c2 = new completion_info($course2);
     $this->assertTrue($c1->has_activities());
     $this->assertFalse($c2->has_activities());
 }
Exemplo n.º 17
0
/**
 *
 * @param cm_info $cm
 * @param stdClass $stopwatch
 * @param int $duration
 */
function mod_stopwatch_update_timer(cm_info $cm, $stopwatch, $duration)
{
    global $USER, $DB, $CFG;
    require_once $CFG->libdir . '/completionlib.php';
    $record = $DB->get_record('stopwatch_user', array('stopwatchid' => $cm->instance, 'courseid' => $cm->course, 'userid' => $USER->id));
    if ($record) {
        $data = array('id' => $record->id, 'timemodified' => time(), 'duration' => $duration);
        $DB->update_record('stopwatch_user', $data);
    } else {
        $data = array('courseid' => $cm->course, 'stopwatchid' => $cm->instance, 'userid' => $USER->id, 'timecreated' => time(), 'timemodified' => time(), 'duration' => $duration);
        $DB->insert_record('stopwatch_user', $data);
    }
    // Update completion state
    $completion = new completion_info($cm->get_course());
    if ($completion->is_enabled($cm) && $stopwatch->completiontimed) {
        $completion->update_state($cm, COMPLETION_COMPLETE);
    }
}
Exemplo n.º 18
0
 /**
  * Updates activity completion status.
  *
  * @return void
  */
 public static function update_require_specific_grade(\core\event\base $event)
 {
     global $DB;
     $entryuserid = $event->relateduserid;
     $giid = $event->other['itemid'];
     if (!($gitem = \grade_item::fetch(array('id' => $giid, 'itemmodule' => 'dataform')))) {
         return;
     }
     $dataformid = $gitem->iteminstance;
     $df = \mod_dataform_dataform::instance($dataformid);
     // Currently only completion by require entries.
     if ($df->completionspecificgrade) {
         $completion = new \completion_info($df->course);
         if ($completion->is_enabled($df->cm) != COMPLETION_TRACKING_AUTOMATIC) {
             return;
         }
         $completion->update_state($df->cm, COMPLETION_UNKNOWN, $entryuserid);
     }
 }
 /**
  * Read page
  *
  * @throws \coding_exception
  * @return stdClass
  */
 private function read_page()
 {
     global $PAGE, $COURSE;
     $cm = $PAGE->cm;
     $page = \theme_snap\local::get_page_mod($cm);
     $context = $PAGE->context;
     // Trigger module instance viewed event.
     $event = \mod_page\event\course_module_viewed::create(array('objectid' => $page->id, 'context' => $context));
     $event->add_record_snapshot('course_modules', $cm);
     $event->add_record_snapshot('course', $COURSE);
     $event->add_record_snapshot('page', $page);
     $event->trigger();
     // Update 'viewed' state if required by completion system.
     $completion = new \completion_info($COURSE);
     $completion->set_module_viewed($cm);
     $renderer = $PAGE->get_renderer('core', 'course');
     $page->completionhtml = $renderer->course_section_cm_completion($COURSE, $completion, $cm);
     return $page;
 }
Exemplo n.º 20
0
 public function get_content()
 {
     global $USER;
     // If content is cached
     if ($this->content !== NULL) {
         return $this->content;
     }
     global $CFG;
     // Create empty content
     $this->content = new stdClass();
     // Don't display if completion isn't enabled!
     if (!$this->page->course->enablecompletion) {
         $this->content->text = get_string('completionnotenabled', 'block_selfcompletion');
         return $this->content;
     }
     // Get course completion data
     $info = new completion_info($this->page->course);
     $completion = $info->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF);
     // Is course complete?
     if ($info->is_course_complete($USER->id)) {
         return $this->content;
     }
     // Check if self completion is one of this course's criteria
     if (empty($completion)) {
         $this->content->text = get_string('selfcompletionnotenabled', 'block_selfcompletion');
         return $this->content;
     }
     // Check this user is enroled
     if (!$info->is_tracked_user($USER->id)) {
         $this->content->text = get_string('notenroled', 'completion');
         return $this->content;
     }
     // Check if the user has already marked themselves as complete
     if ($completion->is_complete()) {
         return $this->content;
     } else {
         $this->content->text = '';
         $this->content->footer = '<br /><a href="' . $CFG->wwwroot . '/course/togglecompletion.php?course=' . $this->page->course->id . '">' . get_string('completecourse', 'block_selfcompletion') . '</a>...';
     }
     return $this->content;
 }
Exemplo n.º 21
0
/**
 * get_activity_tree :: course_modinfo -> integer -> context -> array
 * @param \course_modinfo $modinfo
 * @param integer $section_number
 * @param \context $context
 * @return array
 */
function get_activity_tree(\course_modinfo $modinfo, $section_number, \context $context)
{
    $completion_info = new \completion_info($modinfo->get_course());
    return F\map(F\filter($modinfo->get_section_info_all(), function (\section_info $section_info) {
        return $section_info->visible;
    }), function (\section_info $section_info) use($completion_info, $section_number, $context) {
        $mods = F\map(F\filter($section_info->modinfo->cms, function (\cm_info $cm_info) use($section_info) {
            global $CFG;
            return ($cm_info->uservisible || $CFG->enableavailability && !empty($cm_info->availableinfo)) && (int) $cm_info->sectionnum === (int) $section_info->section;
        }), function (\cm_info $cm_info) use($completion_info, $context) {
            global $CFG;
            $canComplete = $CFG->enablecompletion && isloggedin() && !isguestuser() && (int) $completion_info->is_enabled($cm_info) === COMPLETION_TRACKING_MANUAL;
            $hasCompleted = false;
            if ($canComplete) {
                $completion_data = $completion_info->get_data($cm_info, true);
                $hasCompleted = F\contains([COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS], (int) $completion_data->completionstate);
            }
            return (object) ['id' => (int) $cm_info->id, 'name' => $cm_info->name, 'modname' => $cm_info->modname, 'current' => is_current_mod($cm_info, $context), 'available' => $cm_info->available, 'canComplete' => $canComplete, 'hasCompleted' => $hasCompleted];
        });
        return (object) ['id' => (int) $section_info->id, 'section' => (int) $section_info->section, 'name' => \get_section_name($section_info->modinfo->courseid, $section_info->section), 'current' => is_current_section($section_info, $section_number, $context), 'activities' => array_values($mods)];
    });
}
 /**
  * Set properties from course and section.
  * @param \stdClass $course
  * @param \stdClass $section
  */
 public function __construct($course, $section)
 {
     global $OUTPUT;
     static $compinfos = [];
     if (isset($compinfos[$course->id])) {
         $completioninfo = $compinfos[$course->id];
     } else {
         $completioninfo = new \completion_info($course);
         $compinfos[$course->id] = $completioninfo;
     }
     if (!$completioninfo->is_enabled()) {
         return '';
         // Completion tracking not enabled.
     }
     $sac = shared::section_activity_summary($section, $course, null);
     if (empty($sac->progress)) {
         return;
     }
     $this->progress = (object) ['complete' => $sac->progress->complete, 'total' => $sac->progress->total];
     $this->pixcompleted = $OUTPUT->pix_url('i/completion-manual-y');
     $this->completed = $sac->progress->complete === $sac->progress->total;
 }
Exemplo n.º 23
0
 public function test_glossary_view()
 {
     global $CFG;
     $origcompletion = $CFG->enablecompletion;
     $CFG->enablecompletion = true;
     $this->resetAfterTest(true);
     // Generate all the things.
     $c1 = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
     $g1 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1));
     $g2 = $this->getDataGenerator()->create_module('glossary', array('course' => $c1->id, 'completion' => COMPLETION_TRACKING_AUTOMATIC, 'completionview' => 1));
     $u1 = $this->getDataGenerator()->create_user();
     $this->getDataGenerator()->enrol_user($u1->id, $c1->id);
     $modinfo = course_modinfo::instance($c1->id);
     $cm1 = $modinfo->get_cm($g1->cmid);
     $cm2 = $modinfo->get_cm($g2->cmid);
     $ctx1 = $cm1->context;
     $completion = new completion_info($c1);
     $this->setUser($u1);
     // Confirm what we've set up.
     $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate);
     $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate);
     // Simulate the view call.
     $sink = $this->redirectEvents();
     glossary_view($g1, $c1, $cm1, $ctx1, 'letter');
     $events = $sink->get_events();
     // Assertions.
     $this->assertCount(3, $events);
     $this->assertEquals('\\core\\event\\course_module_completion_updated', $events[0]->eventname);
     $this->assertEquals('\\core\\event\\course_module_completion_updated', $events[1]->eventname);
     $this->assertEquals('\\mod_glossary\\event\\course_module_viewed', $events[2]->eventname);
     $this->assertEquals($g1->id, $events[2]->objectid);
     $this->assertEquals('letter', $events[2]->other['mode']);
     $this->assertEquals(COMPLETION_VIEWED, $completion->get_data($cm1, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_COMPLETE, $completion->get_data($cm1, false, $u1->id)->completionstate);
     $this->assertEquals(COMPLETION_NOT_VIEWED, $completion->get_data($cm2, false, $u1->id)->viewed);
     $this->assertEquals(COMPLETION_INCOMPLETE, $completion->get_data($cm2, false, $u1->id)->completionstate);
     // Tear down.
     $sink->close();
     $CFG->enablecompletion = $origcompletion;
 }
Exemplo n.º 24
0
                    $nonsubmitters->send_message($nonsubmitteduser->id, $subject, $message);
                }
                // Send a copy of message to the instructor if appropriate.
                if (!empty($sendtoself)) {
                    $nonsubmitters->send_message($USER->id, $subject, $message);
                }
                $do = "emailsent";
            }
            $params = array('id' => $id, 'do' => $do, 'view_context' => 'box_solid');
            redirect(new moodle_url('/mod/turnitintooltwo/view.php', $params));
            exit;
            break;
    }
}
// Enable activity completion on page view.
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
// Show header and navigation
if ($viewcontext == "box" || $viewcontext == "box_solid") {
    $PAGE->set_pagelayout('embedded');
    $turnitintooltwoview->output_header($cm, $course, $url, '', '', array(), "", "", true, '', '');
} else {
    $turnitintooltwoview->output_header($cm, $course, $url, $turnitintooltwoassignment->turnitintooltwo->name, $SITE->fullname, array(), "", "", true, $OUTPUT->update_module_button($cm->id, "turnitintooltwo"), '');
    // Dropdown to filter by groups.
    $groupmode = groups_get_activity_groupmode($cm);
    if ($groupmode) {
        groups_get_activity_group($cm, true);
        groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/turnitintooltwo/view.php?id=' . $id . '&do=' . $do);
    }
    $turnitintooltwoview->draw_tool_tab_menu($cm, $do);
}
Exemplo n.º 25
0
 /**
  * Output the html for a multiple section page
  *
  * @param stdClass $course The course entry from DB
  * @param array $sections (argument not used)
  * @param array $mods (argument not used)
  * @param array $modnames (argument not used)
  * @param array $modnamesused (argument not used)
  */
 public function print_multiple_section_page($course, $sections, $mods, $modnames, $modnamesused)
 {
     $modinfo = get_fast_modinfo($course);
     $course = $this->courseformat->get_course();
     if (empty($this->tcsettings)) {
         $this->tcsettings = $this->courseformat->get_settings();
     }
     $context = context_course::instance($course->id);
     // Title with completion help icon.
     $completioninfo = new completion_info($course);
     echo $completioninfo->display_help_icon();
     echo $this->output->heading($this->page_title(), 2, 'accesshide');
     // Copy activity clipboard..
     echo $this->course_activity_clipboard($course, 0);
     // Now the list of sections..
     $this->tccolumnwidth = 100;
     // Reset to default.
     echo $this->start_section_list();
     $sections = $modinfo->get_section_info_all();
     // General section if non-empty.
     $thissection = $sections[0];
     unset($sections[0]);
     if ($thissection->summary or !empty($modinfo->sections[0]) or $this->userisediting) {
         echo $this->section_header($thissection, $course, false, 0);
         echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
         echo $this->courserenderer->course_section_add_cm_control($course, $thissection->section, 0, 0);
         echo $this->section_footer();
     }
     if ($course->numsections > 0) {
         if ($course->numsections > 1) {
             if ($this->userisediting || $course->coursedisplay != COURSE_DISPLAY_MULTIPAGE) {
                 // Collapsed Topics all toggles.
                 echo $this->toggle_all();
                 if ($this->tcsettings['displayinstructions'] == 2) {
                     // Collapsed Topics instructions.
                     echo $this->display_instructions();
                 }
             }
         }
         $currentsectionfirst = false;
         if ($this->tcsettings['layoutstructure'] == 4) {
             $currentsectionfirst = true;
         }
         if ($this->tcsettings['layoutstructure'] != 3 || $this->userisediting) {
             $section = 1;
         } else {
             $timenow = time();
             $weekofseconds = 604800;
             $course->enddate = $course->startdate + $weekofseconds * $course->numsections;
             $section = $course->numsections;
             $weekdate = $course->enddate;
             // This should be 0:00 Monday of that week.
             $weekdate -= 7200;
             // Subtract two hours to avoid possible DST problems.
         }
         $numsections = $course->numsections;
         // Because we want to manipulate this for column breakpoints.
         if ($this->tcsettings['layoutstructure'] == 3 && $this->userisediting == false) {
             $loopsection = 1;
             $numsections = 0;
             while ($loopsection <= $course->numsections) {
                 $nextweekdate = $weekdate - $weekofseconds;
                 if ((($thissection->uservisible || $thissection->visible && !$thissection->available && !empty($thissection->availableinfo)) && $nextweekdate <= $timenow) == true) {
                     $numsections++;
                     // Section not shown so do not count in columns calculation.
                 }
                 $weekdate = $nextweekdate;
                 $section--;
                 $loopsection++;
             }
             // Reset.
             $section = $course->numsections;
             $weekdate = $course->enddate;
             // This should be 0:00 Monday of that week.
             $weekdate -= 7200;
             // Subtract two hours to avoid possible DST problems.
         }
         if ($numsections < $this->tcsettings['layoutcolumns']) {
             $this->tcsettings['layoutcolumns'] = $numsections;
             // Help to ensure a reasonable display.
         }
         if ($this->tcsettings['layoutcolumns'] > 1 && $this->mobiletheme === false) {
             if ($this->tcsettings['layoutcolumns'] > 4) {
                 // Default in config.php (and reset in database) or database has been changed incorrectly.
                 $this->tcsettings['layoutcolumns'] = 4;
                 // Update....
                 $this->courseformat->update_topcoll_columns_setting($this->tcsettings['layoutcolumns']);
             }
             if ($this->tablettheme === true && $this->tcsettings['layoutcolumns'] > 2) {
                 // Use a maximum of 2 for tablets.
                 $this->tcsettings['layoutcolumns'] = 2;
             }
             $this->tccolumnwidth = 100 / $this->tcsettings['layoutcolumns'];
             if ($this->tcsettings['layoutcolumnorientation'] == 2) {
                 // Horizontal column layout.
                 $this->tccolumnwidth -= 1;
             } else {
                 $this->tccolumnwidth -= 0.2;
             }
             $this->tccolumnpadding = 0;
             // In 'px'.
         } else {
             if ($this->tcsettings['layoutcolumns'] < 1) {
                 // Distributed default in plugin settings (and reset in database) or database has been changed incorrectly.
                 $this->tcsettings['layoutcolumns'] = 1;
                 // Update....
                 $this->courseformat->update_topcoll_columns_setting($this->tcsettings['layoutcolumns']);
             }
         }
         echo $this->end_section_list();
         echo $this->start_toggle_section_list();
         $loopsection = 1;
         $canbreak = false;
         // Once the first section is shown we can decide if we break on another column.
         $columncount = 1;
         $columnbreakpoint = 0;
         $shownsectioncount = 0;
         if ($this->userpreference != null) {
             $this->isoldtogglepreference = $this->togglelib->is_old_preference($this->userpreference);
             if ($this->isoldtogglepreference == true) {
                 $ts1 = base_convert(substr($this->userpreference, 0, 6), 36, 2);
                 $ts2 = base_convert(substr($this->userpreference, 6, 12), 36, 2);
                 $thesparezeros = "00000000000000000000000000";
                 if (strlen($ts1) < 26) {
                     // Need to PAD.
                     $ts1 = substr($thesparezeros, 0, 26 - strlen($ts1)) . $ts1;
                 }
                 if (strlen($ts2) < 27) {
                     // Need to PAD.
                     $ts2 = substr($thesparezeros, 0, 27 - strlen($ts2)) . $ts2;
                 }
                 $tb = $ts1 . $ts2;
             } else {
                 // Check we have enough digits for the number of toggles in case this has increased.
                 $numdigits = $this->togglelib->get_required_digits($course->numsections);
                 if ($numdigits > strlen($this->userpreference)) {
                     if ($this->defaultuserpreference == 0) {
                         $dchar = $this->togglelib->get_min_digit();
                     } else {
                         $dchar = $this->togglelib->get_max_digit();
                     }
                     for ($i = strlen($this->userpreference); $i < $numdigits; $i++) {
                         $this->userpreference .= $dchar;
                     }
                 }
                 $this->togglelib->set_toggles($this->userpreference);
             }
         } else {
             $numdigits = $this->togglelib->get_required_digits($course->numsections);
             if ($this->defaultuserpreference == 0) {
                 $dchar = $this->togglelib->get_min_digit();
             } else {
                 $dchar = $this->togglelib->get_max_digit();
             }
             $this->userpreference = '';
             for ($i = 0; $i < $numdigits; $i++) {
                 $this->userpreference .= $dchar;
             }
             $this->togglelib->set_toggles($this->userpreference);
         }
         while ($loopsection <= $course->numsections) {
             if ($this->tcsettings['layoutstructure'] == 3 && $this->userisediting == false) {
                 $nextweekdate = $weekdate - $weekofseconds;
             }
             $thissection = $modinfo->get_section_info($section);
             /* Show the section if the user is permitted to access it, OR if it's not available
                but there is some available info text which explains the reason & should display. */
             if ($this->tcsettings['layoutstructure'] != 3 || $this->userisediting) {
                 $showsection = $thissection->uservisible || $thissection->visible && !$thissection->available && !empty($thissection->availableinfo);
             } else {
                 $showsection = ($thissection->uservisible || $thissection->visible && !$thissection->available && !empty($thissection->availableinfo)) && $nextweekdate <= $timenow;
             }
             if ($currentsectionfirst == true && $showsection == true) {
                 // Show  the section if we were meant to and it is the current section:....
                 $showsection = $course->marker == $section;
             } else {
                 if ($this->tcsettings['layoutstructure'] == 4 && $course->marker == $section) {
                     $showsection = false;
                     // Do not reshow current section.
                 }
             }
             if (!$showsection) {
                 // Hidden section message is overridden by 'unavailable' control.
                 if ($this->tcsettings['layoutstructure'] != 4) {
                     if ($this->tcsettings['layoutstructure'] != 3 || $this->userisediting) {
                         if (!$course->hiddensections && $thissection->available) {
                             $shownsectioncount++;
                             echo $this->section_hidden($thissection);
                         }
                     }
                 }
             } else {
                 $shownsectioncount++;
                 if (!$this->userisediting && $course->coursedisplay == COURSE_DISPLAY_MULTIPAGE) {
                     // Display section summary only.
                     echo $this->section_summary($thissection, $course, null);
                 } else {
                     if ($this->isoldtogglepreference == true) {
                         $togglestate = substr($tb, $section, 1);
                         if ($togglestate == '1') {
                             $thissection->toggle = true;
                         } else {
                             $thissection->toggle = false;
                         }
                     } else {
                         $thissection->toggle = $this->togglelib->get_toggle_state($thissection->section);
                     }
                     echo $this->section_header($thissection, $course, false, 0);
                     if ($thissection->uservisible) {
                         echo $this->courserenderer->course_section_cm_list($course, $thissection, 0);
                         echo $this->courserenderer->course_section_add_cm_control($course, $thissection->section, 0);
                     }
                     echo html_writer::end_tag('div');
                     echo $this->section_footer();
                 }
             }
             if ($currentsectionfirst == false) {
                 /* Only need to do this on the iteration when $currentsectionfirst is not true as this iteration will always
                    happen.  Otherwise you get duplicate entries in course_sections in the DB. */
                 unset($sections[$section]);
             }
             if ($this->tcsettings['layoutstructure'] != 3 || $this->userisediting) {
                 $section++;
             } else {
                 $section--;
                 if ($this->tcsettings['layoutstructure'] == 3 && $this->userisediting == false) {
                     $weekdate = $nextweekdate;
                 }
             }
             if ($this->mobiletheme === false) {
                 // Only break in non-mobile themes.
                 if ($this->tcsettings['layoutcolumnorientation'] == 1) {
                     // Only break columns in vertical mode.
                     if ($canbreak == false && $currentsectionfirst == false && $showsection == true) {
                         $canbreak = true;
                         $columnbreakpoint = $shownsectioncount + $numsections / $this->tcsettings['layoutcolumns'] - 1;
                         if ($this->tcsettings['layoutstructure'] == 4) {
                             $columnbreakpoint -= 1;
                         }
                     }
                     if ($currentsectionfirst == false && $canbreak == true && $shownsectioncount >= $columnbreakpoint && $columncount < $this->tcsettings['layoutcolumns']) {
                         echo $this->end_section_list();
                         echo $this->start_toggle_section_list();
                         $columncount++;
                         // Next breakpoint is...
                         $columnbreakpoint += $numsections / $this->tcsettings['layoutcolumns'];
                     }
                 }
             }
             $loopsection++;
             if ($currentsectionfirst == true && $loopsection > $course->numsections) {
                 // Now show the rest.
                 $currentsectionfirst = false;
                 $loopsection = 1;
                 $section = 1;
             }
             if ($section > $course->numsections) {
                 // Activities inside this section are 'orphaned', this section will be printed as 'stealth' below.
                 break;
             }
         }
     }
     if ($this->userisediting and has_capability('moodle/course:update', $context)) {
         // Print stealth sections if present.
         foreach ($modinfo->get_section_info_all() as $section => $thissection) {
             if ($section <= $course->numsections or empty($modinfo->sections[$section])) {
                 // This is not stealth section or it is empty.
                 continue;
             }
             echo $this->stealth_section_header($section);
             echo $this->courserenderer->course_section_cm_list($course, $thissection->section, 0);
             echo $this->stealth_section_footer();
         }
         echo $this->end_section_list();
         echo html_writer::start_tag('div', array('id' => 'changenumsections', 'class' => 'mdl-right'));
         // Increase number of sections.
         $straddsection = get_string('increasesections', 'moodle');
         $url = new moodle_url('/course/changenumsections.php', array('courseid' => $course->id, 'increase' => true, 'sesskey' => sesskey()));
         $icon = $this->output->pix_icon('t/switch_plus', $straddsection);
         echo html_writer::link($url, $icon . get_accesshide($straddsection), array('class' => 'increase-sections'));
         if ($course->numsections > 0) {
             // Reduce number of sections sections.
             $strremovesection = get_string('reducesections', 'moodle');
             $url = new moodle_url('/course/changenumsections.php', array('courseid' => $course->id, 'increase' => false, 'sesskey' => sesskey()));
             $icon = $this->output->pix_icon('t/switch_minus', $strremovesection);
             echo html_writer::link($url, $icon . get_accesshide($strremovesection), array('class' => 'reduce-sections'));
         }
         echo html_writer::end_tag('div');
     } else {
         echo $this->end_section_list();
     }
 }
Exemplo n.º 26
0
/**
 * Deletes a single forum post.
 *
 * @global object
 * @param object $post Forum post object
 * @param mixed $children Whether to delete children. If false, returns false
 *   if there are any children (without deleting the post). If true,
 *   recursively deletes all children. If set to special value 'ignore', deletes
 *   post regardless of children (this is for use only when deleting all posts
 *   in a disussion).
 * @param object $course Course
 * @param object $cm Course-module
 * @param object $forum Forum
 * @param bool $skipcompletion True to skip updating completion state if it
 *   would otherwise be updated, i.e. when deleting entire forum anyway.
 * @return bool
 */
function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompletion=false) {
    global $DB, $CFG;
    require_once($CFG->libdir.'/completionlib.php');

    $context = context_module::instance($cm->id);

    if ($children !== 'ignore' && ($childposts = $DB->get_records('forum_posts', array('parent'=>$post->id)))) {
       if ($children) {
           foreach ($childposts as $childpost) {
               forum_delete_post($childpost, true, $course, $cm, $forum, $skipcompletion);
           }
       } else {
           return false;
       }
    }

    //delete ratings
    require_once($CFG->dirroot.'/rating/lib.php');
    $delopt = new stdClass;
    $delopt->contextid = $context->id;
    $delopt->component = 'mod_forum';
    $delopt->ratingarea = 'post';
    $delopt->itemid = $post->id;
    $rm = new rating_manager();
    $rm->delete_ratings($delopt);

    //delete attachments
    $fs = get_file_storage();
    $fs->delete_area_files($context->id, 'mod_forum', 'attachment', $post->id);
    $fs->delete_area_files($context->id, 'mod_forum', 'post', $post->id);

    if ($DB->delete_records("forum_posts", array("id" => $post->id))) {

        forum_tp_delete_read_records(-1, $post->id);

    // Just in case we are deleting the last post
        forum_discussion_update_last_post($post->discussion);

        // Update completion state if we are tracking completion based on number of posts
        // But don't bother when deleting whole thing

        if (!$skipcompletion) {
            $completion = new completion_info($course);
            if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC &&
               ($forum->completiondiscussions || $forum->completionreplies || $forum->completionposts)) {
                $completion->update_state($cm, COMPLETION_INCOMPLETE, $post->userid);
            }
        }

        return true;
    }
    return false;
}
Exemplo n.º 27
0
function checklist_update_grades($checklist, $userid = 0)
{
    global $CFG, $DB;
    $items = $DB->get_records('checklist_item', array('checklist' => $checklist->id, 'userid' => 0, 'itemoptional' => CHECKLIST_OPTIONAL_NO, 'hidden' => CHECKLIST_HIDDEN_NO), '', 'id, grouping');
    if (!$items) {
        return;
    }
    if (!($course = $DB->get_record('course', array('id' => $checklist->course)))) {
        return;
    }
    if (!($cm = get_coursemodule_from_instance('checklist', $checklist->id, $course->id))) {
        return;
    }
    $checkgroupings = false;
    // Don't check items against groupings unless we really have to
    if (isset($CFG->enablegroupmembersonly) && $CFG->enablegroupmembersonly && $checklist->autopopulate) {
        foreach ($items as $item) {
            if ($item->grouping) {
                $checkgroupings = true;
                break;
            }
        }
    }
    if ($checklist->teacheredit == CHECKLIST_MARKING_STUDENT) {
        $date = ', MAX(c.usertimestamp) AS datesubmitted';
        $where = 'c.usertimestamp > 0';
    } else {
        $date = ', MAX(c.teachertimestamp) AS dategraded';
        $where = 'c.teachermark = ' . CHECKLIST_TEACHERMARK_YES;
    }
    if ($checkgroupings) {
        if ($userid) {
            $users = $DB->get_records('user', array('id' => $userid), null, 'id, firstname, lastname');
        } else {
            if ($CFG->version < 2011120100) {
                $context = get_context_instance(CONTEXT_MODULE, $cm->id);
            } else {
                $context = context_module::instance($cm->id);
            }
            if (!($users = get_users_by_capability($context, 'mod/checklist:updateown', 'u.id, u.firstname, u.lastname', '', '', '', '', '', false))) {
                return;
            }
        }
        $grades = array();
        // With groupings, need to update each user individually (as each has different groupings)
        foreach ($users as $userid => $user) {
            $groupings = checklist_class::get_user_groupings($userid, $course->id);
            $total = 0;
            $itemlist = '';
            foreach ($items as $item) {
                if ($item->grouping) {
                    if (!in_array($item->grouping, $groupings)) {
                        continue;
                    }
                }
                $itemlist .= $item->id . ',';
                $total++;
            }
            if (!$total) {
                // No items - set score to 0
                $ugrade = new stdClass();
                $ugrade->userid = $userid;
                $ugrade->rawgrade = 0;
                $ugrade->date = time();
            } else {
                $itemlist = substr($itemlist, 0, -1);
                // Remove trailing ','
                $sql = 'SELECT ? AS userid, (SUM(CASE WHEN ' . $where . ' THEN 1 ELSE 0 END) * ? / ? ) AS rawgrade' . $date;
                $sql .= " FROM {checklist_check} c ";
                $sql .= " WHERE c.item IN ({$itemlist})";
                $sql .= ' AND c.userid = ? ';
                $ugrade = $DB->get_record_sql($sql, array($userid, $checklist->maxgrade, $total, $userid));
                if (!$ugrade) {
                    $ugrade = new stdClass();
                    $ugrade->userid = $userid;
                    $ugrade->rawgrade = 0;
                    $ugrade->date = time();
                }
            }
            $ugrade->firstname = $user->firstname;
            $ugrade->lastname = $user->lastname;
            $grades[$userid] = $ugrade;
        }
    } else {
        // No need to check groupings, so update all student grades at once
        if ($userid) {
            $users = $userid;
        } else {
            if ($CFG->version < 2011120100) {
                $context = get_context_instance(CONTEXT_MODULE, $cm->id);
            } else {
                $context = context_module::instance($cm->id);
            }
            if (!($users = get_users_by_capability($context, 'mod/checklist:updateown', 'u.id', '', '', '', '', '', false))) {
                return;
            }
            $users = array_keys($users);
        }
        $total = count($items);
        list($usql, $uparams) = $DB->get_in_or_equal($users);
        list($isql, $iparams) = $DB->get_in_or_equal(array_keys($items));
        $sql = 'SELECT u.id AS userid, (SUM(CASE WHEN ' . $where . ' THEN 1 ELSE 0 END) * ? / ? ) AS rawgrade' . $date;
        $sql .= ' , u.firstname, u.lastname ';
        $sql .= ' FROM {user} u LEFT JOIN {checklist_check} c ON u.id = c.userid';
        $sql .= " WHERE u.id {$usql}";
        $sql .= " AND c.item {$isql}";
        $sql .= ' GROUP BY u.id, u.firstname, u.lastname';
        $params = array_merge($uparams, $iparams);
        $params = array_merge(array($checklist->maxgrade, $total), $params);
        $grades = $DB->get_records_sql($sql, $params);
    }
    foreach ($grades as $grade) {
        // Log completion of checklist
        if ($grade->rawgrade == $checklist->maxgrade) {
            if ($checklist->emailoncomplete) {
                $timelimit = time() - 1 * 60 * 60;
                // Do not send another email if this checklist was already 'completed' in the last hour
                $filter = "l.time > ? AND l.cmid = ? AND l.userid = ? AND l.action = 'complete'";
                get_logs($filter, array($timelimit, $cm->id, $grade->userid), '', 1, 1, $logcount);
                if ($logcount == 0) {
                    if (!isset($context)) {
                        if ($CFG->version < 2011120100) {
                            $context = get_context_instance(CONTEXT_MODULE, $cm->id);
                        } else {
                            $context = context_module::instance($cm->id);
                        }
                    }
                    if ($recipients = get_users_by_capability($context, 'mod/checklist:emailoncomplete', 'u.*', '', '', '', '', '', false)) {
                        foreach ($recipients as $recipient) {
                            $details = new stdClass();
                            $details->user = fullname($grade);
                            $details->checklist = s($checklist->name);
                            $subj = get_string('emailoncompletesubject', 'checklist', $details);
                            $content = get_string('emailoncompletebody', 'checklist', $details);
                            $content .= $CFG->wwwroot . '/mod/checklist/view.php?id=' . $cm->id;
                            email_to_user($recipient, $grade, $subj, $content, '', '', '', false);
                        }
                    }
                }
            }
            add_to_log($checklist->course, 'checklist', 'complete', "view.php?id={$cm->id}", $checklist->name, $cm->id, $grade->userid);
        }
        $ci = new completion_info($course);
        if ($cm->completion == COMPLETION_TRACKING_AUTOMATIC) {
            $ci->update_state($cm, COMPLETION_UNKNOWN, $grade->userid);
        }
    }
    checklist_grade_item_update($checklist, $grades);
}
Exemplo n.º 28
0
Arquivo: lib.php Projeto: dg711/moodle
/**
 * Mark the activity completed (if required) and trigger the page_viewed event.
 *
 * @param  stdClass $wiki       Wiki object.
 * @param  stdClass $page       Page object.
 * @param  stdClass $course     Course object.
 * @param  stdClass $cm         Course module object.
 * @param  stdClass $context    Context object.
 * @param  int $uid             Optional User ID.
 * @param  array $other         Optional Other params: title, wiki ID, group ID, groupanduser, prettyview.
 * @param  stdClass $subwiki    Optional Subwiki.
 * @since Moodle 3.1
 */
function wiki_page_view($wiki, $page, $course, $cm, $context, $uid = null, $other = null, $subwiki = null)
{
    // Trigger course_module_viewed event.
    $params = array('context' => $context, 'objectid' => $page->id);
    if ($uid != null) {
        $params['relateduserid'] = $uid;
    }
    if ($other != null) {
        $params['other'] = $other;
    }
    $event = \mod_wiki\event\page_viewed::create($params);
    $event->add_record_snapshot('wiki_pages', $page);
    $event->add_record_snapshot('course_modules', $cm);
    $event->add_record_snapshot('course', $course);
    $event->add_record_snapshot('wiki', $wiki);
    if ($subwiki != null) {
        $event->add_record_snapshot('wiki_subwikis', $subwiki);
    }
    $event->trigger();
    // Completion.
    $completion = new completion_info($course);
    $completion->set_module_viewed($cm);
}
Exemplo n.º 29
0
                    }
                } else {
                    echo $OUTPUT->notification('An error occurred while moving a section');
                }
            }
        }
    }
} else {
    $USER->editing = 0;
}
$SESSION->fromdiscussion = $PAGE->url->out(false);
if ($course->id == SITEID) {
    // This course is not a real course.
    redirect($CFG->wwwroot . '/');
}
$completion = new completion_info($course);
if ($completion->is_enabled() && ajaxenabled()) {
    $PAGE->requires->string_for_js('completion-title-manual-y', 'completion');
    $PAGE->requires->string_for_js('completion-title-manual-n', 'completion');
    $PAGE->requires->string_for_js('completion-alt-manual-y', 'completion');
    $PAGE->requires->string_for_js('completion-alt-manual-n', 'completion');
    $PAGE->requires->js_init_call('M.core_completion.init');
}
// We are currently keeping the button here from 1.x to help new teachers figure out
// what to do, even though the link also appears in the course admin block.  It also
// means you can back out of a situation where you removed the admin block. :)
if ($PAGE->user_allowed_editing()) {
    $buttons = $OUTPUT->edit_button($PAGE->url);
    $PAGE->set_button($buttons);
}
$PAGE->set_title(get_string('course') . ': ' . $course->fullname);
         case get_string("optionid", "booking"):
             $optionIDPos = $key;
             break;
         case get_string("user") . " " . get_string("idnumber"):
             $userIDPos = $key;
             break;
         case get_string("searchFinished", "booking"):
             $completedPos = $key;
             break;
         default:
             break;
     }
 }
 if ($optionIDPos > -1 && $userIDPos > -1 && $completedPos > -1) {
     array_shift($csvArr);
     $completion = new completion_info($course);
     foreach ($csvArr as $line) {
         if (count($line) >= 3) {
             $user = $DB->get_record('booking_answers', array('bookingid' => $booking->id, 'userid' => $line[$userIDPos], 'optionid' => $line[$optionIDPos]));
             if ($user !== FALSE) {
                 $user->completed = $line[$completedPos];
                 $user->timemodified = time();
                 $DB->update_record('booking_answers', $user, false);
                 if ($completion->is_enabled($cm) && $booking->enablecompletion && $user->completed == 0) {
                     $completion->update_state($cm, COMPLETION_INCOMPLETE, $user->userid);
                 }
                 if ($completion->is_enabled($cm) && $booking->enablecompletion && $user->completed == 1) {
                     $completion->update_state($cm, COMPLETION_COMPLETE, $user->userid);
                 }
             }
         }