Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Contains class containing completion API.
19
 *
20
 * @package    core_completion
21
 * @copyright  2017 Mark Nelson <markn@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_completion;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
/**
30
 * Class containing completion API.
31
 *
32
 * @package    core_completion
33
 * @copyright  2017 Mark Nelson <markn@moodle.com>
34
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35
 */
36
class api {
37
 
38
    /**
39
     * @var string The completion expected on event.
40
     */
41
    const COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED = 'expectcompletionon';
42
 
43
    /**
44
     * Creates, updates or deletes an event for the expected completion date.
45
     *
46
     * @param int $cmid The course module id
47
     * @param string $modulename The name of the module (eg. assign, quiz)
48
     * @param \stdClass|int $instanceorid The instance object or ID.
49
     * @param int|null $completionexpectedtime The time completion is expected, null if not set
50
     * @return bool
51
     */
52
    public static function update_completion_date_event($cmid, $modulename, $instanceorid, $completionexpectedtime) {
53
        global $CFG, $DB;
54
 
55
        // Required for calendar constant CALENDAR_EVENT_TYPE_ACTION.
56
        require_once($CFG->dirroot . '/calendar/lib.php');
57
 
58
        $instance = null;
59
        if (is_object($instanceorid)) {
60
            $instance = $instanceorid;
61
        } else {
62
            $instance = $DB->get_record($modulename, array('id' => $instanceorid), '*', IGNORE_MISSING);
63
        }
64
        if (!$instance) {
65
            return false;
66
        }
67
        $course = get_course($instance->course);
68
 
69
        $completion = new \completion_info($course);
70
 
71
        // Can not create/update an event if completion is disabled.
72
        if (!$completion->is_enabled() && $completionexpectedtime !== null) {
73
            return true;
74
        }
75
 
76
        // Create the \stdClass we will be using for our language strings.
77
        $lang = new \stdClass();
78
        $lang->modulename = get_string('pluginname', $modulename);
79
        $lang->instancename = $instance->name;
80
 
81
        // Create the calendar event.
82
        $event = new \stdClass();
83
        $event->type = CALENDAR_EVENT_TYPE_ACTION;
84
        $event->eventtype = self::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED;
85
        if ($event->id = $DB->get_field('event', 'id', array('modulename' => $modulename,
86
                'instance' => $instance->id, 'eventtype' => $event->eventtype))) {
87
            if ($completionexpectedtime !== null) {
88
                // Calendar event exists so update it.
89
                $event->name = get_string('completionexpectedfor', 'completion', $lang);
90
                $event->description = format_module_intro($modulename, $instance, $cmid, false);
91
                $event->format = FORMAT_HTML;
92
                $event->timestart = $completionexpectedtime;
93
                $event->timesort = $completionexpectedtime;
94
                $event->visible = instance_is_visible($modulename, $instance);
95
                $event->timeduration = 0;
96
 
97
                $calendarevent = \calendar_event::load($event->id);
98
                $calendarevent->update($event, false);
99
            } else {
100
                // Calendar event is no longer needed.
101
                $calendarevent = \calendar_event::load($event->id);
102
                $calendarevent->delete();
103
            }
104
        } else {
105
            // Event doesn't exist so create one.
106
            if ($completionexpectedtime !== null) {
107
                $event->name = get_string('completionexpectedfor', 'completion', $lang);
108
                $event->description = format_module_intro($modulename, $instance, $cmid, false);
109
                $event->format = FORMAT_HTML;
110
                $event->courseid = $instance->course;
111
                $event->groupid = 0;
112
                $event->userid = 0;
113
                $event->modulename = $modulename;
114
                $event->instance = $instance->id;
115
                $event->timestart = $completionexpectedtime;
116
                $event->timesort = $completionexpectedtime;
117
                $event->visible = instance_is_visible($modulename, $instance);
118
                $event->timeduration = 0;
119
 
120
                \calendar_event::create($event, false);
121
            }
122
        }
123
 
124
        return true;
125
    }
126
 
127
    /**
128
     * Mark users who completed course based on activity criteria.
129
     * @param array $userdata If set only marks specified user in given course else checks all courses/users.
130
     * @return int Completion record id if $userdata is set, 0 else.
131
     * @since Moodle 4.0
132
     */
133
    public static function mark_course_completions_activity_criteria($userdata = null): int {
134
        global $DB;
135
 
136
        // Get all users who meet this criteria
137
        $sql = "SELECT DISTINCT c.id AS course,
138
                                cr.id AS criteriaid,
139
                                ra.userid AS userid,
140
                                mc.timemodified AS timecompleted
141
                  FROM {course_completion_criteria} cr
142
            INNER JOIN {course} c ON cr.course = c.id
143
            INNER JOIN {context} con ON con.instanceid = c.id
144
            INNER JOIN {role_assignments} ra ON ra.contextid = con.id
145
            INNER JOIN {course_modules} cm ON cm.id = cr.moduleinstance
146
            INNER JOIN {course_modules_completion} mc ON mc.coursemoduleid = cr.moduleinstance AND mc.userid = ra.userid
147
             LEFT JOIN {course_completion_crit_compl} cc ON cc.criteriaid = cr.id AND cc.userid = ra.userid
148
                 WHERE cr.criteriatype = :criteriatype
149
                       AND con.contextlevel = :contextlevel
150
                       AND c.enablecompletion = 1
151
                       AND cc.id IS NULL
152
                       AND (
153
                            mc.completionstate = :completionstate
154
                            OR (cm.completionpassgrade = 1 AND mc.completionstate = :completionstatepass1)
155
                            OR (cm.completionpassgrade = 0 AND (mc.completionstate = :completionstatepass2
156
                                                                OR mc.completionstate = :completionstatefail))
157
                            )";
158
 
159
        $params = [
160
            'criteriatype' => COMPLETION_CRITERIA_TYPE_ACTIVITY,
161
            'contextlevel' => CONTEXT_COURSE,
162
            'completionstate' => COMPLETION_COMPLETE,
163
            'completionstatepass1' => COMPLETION_COMPLETE_PASS,
164
            'completionstatepass2' => COMPLETION_COMPLETE_PASS,
165
            'completionstatefail' => COMPLETION_COMPLETE_FAIL
166
        ];
167
 
168
        if ($userdata) {
169
            $params['courseid'] = $userdata['courseid'];
170
            $params['userid'] = $userdata['userid'];
171
            $sql .= " AND c.id = :courseid AND ra.userid = :userid";
172
            // Mark as complete.
173
            $record = $DB->get_record_sql($sql, $params);
174
            if ($record) {
175
                $completion = new \completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY);
176
                $result = $completion->mark_complete($record->timecompleted);
177
                return $result;
178
            }
179
        } else {
180
            // Loop through completions, and mark as complete.
181
            $rs = $DB->get_recordset_sql($sql, $params);
182
            foreach ($rs as $record) {
183
                $completion = new \completion_criteria_completion((array) $record, DATA_OBJECT_FETCH_BY_KEY);
184
                $completion->mark_complete($record->timecompleted);
185
            }
186
            $rs->close();
187
        }
188
        return 0;
189
    }
190
}