MDL-49543 badges: Add decription format and backup/restore
[moodle.git] / badges / criteria / award_criteria_course.php
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/>.
17 /**
18  * This file contains the course completion badge award criteria type class
19  *
20  * @package    core
21  * @subpackage badges
22  * @copyright  2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  * @author     Yuliya Bozhko <yuliya.bozhko@totaralms.com>
25  */
27 defined('MOODLE_INTERNAL') || die();
28 require_once($CFG->libdir . '/completionlib.php');
29 require_once($CFG->dirroot . '/grade/querylib.php');
30 require_once($CFG->libdir . '/gradelib.php');
32 /**
33  * Badge award criteria -- award on course completion
34  *
35  */
36 class award_criteria_course extends award_criteria {
38     /* @var int Criteria [BADGE_CRITERIA_TYPE_COURSE] */
39     public $criteriatype = BADGE_CRITERIA_TYPE_COURSE;
41     private $courseid;
42     private $coursestartdate;
44     public $required_param = 'course';
45     public $optional_params = array('grade', 'bydate');
47     public function __construct($record) {
48         global $DB;
49         parent::__construct($record);
51         $course = $DB->get_record_sql('SELECT b.courseid, c.startdate
52                         FROM {badge} b INNER JOIN {course} c ON b.courseid = c.id
53                         WHERE b.id = :badgeid ', array('badgeid' => $this->badgeid));
54         $this->courseid = $course->courseid;
55         $this->coursestartdate = $course->startdate;
56     }
58     /**
59      * Add appropriate form elements to the criteria form
60      *
61      * @param moodleform $mform  Moodle forms object
62      * @param stdClass $data details of various modules
63      */
64     public function config_form_criteria($data) {
65         global $OUTPUT;
67         $editurl = new moodle_url('/badges/criteria_settings.php', array('badgeid' => $this->badgeid, 'edit' => true, 'type' => $this->criteriatype, 'crit' => $this->id));
68         $deleteurl = new moodle_url('/badges/criteria_action.php', array('badgeid' => $this->badgeid, 'delete' => true, 'type' => $this->criteriatype));
69         $editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null, array('class' => 'criteria-action'));
70         $deleteaction = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', get_string('delete')), null, array('class' => 'criteria-action'));
72         echo $OUTPUT->box_start();
73         if (!$data->is_locked() && !$data->is_active()) {
74             echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header'));
75         }
76         echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
78         if (!empty($this->description)) {
79             echo $OUTPUT->box(
80                 format_text($this->description, $this->descriptionformat,
81                         array('context' => context_course::instance($this->courseid))
82                 ),
83                 'criteria-description'
84             );
85         }
87         if (!empty($this->params)) {
88             echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges') . $this->get_details(), array('clearfix'));
89         }
90         echo $OUTPUT->box_end();
91     }
93     /**
94      * Get criteria details for displaying to users
95      *
96      * @return string
97      */
98     public function get_details($short = '') {
99         global $DB;
100         $param = reset($this->params);
102         $course = $DB->get_record('course', array('id' => $param['course']));
103         if (!$course) {
104             $str = $OUTPUT->error_text(get_string('error:nosuchcourse', 'badges'));
105         } else {
106             $options = array('context' => context_course::instance($course->id));
107             $str = html_writer::tag('b', '"' . format_string($course->fullname, true, $options) . '"');
108             if (isset($param['bydate'])) {
109                 $str .= get_string('criteria_descr_bydate', 'badges', userdate($param['bydate'], get_string('strftimedate', 'core_langconfig')));
110             }
111             if (isset($param['grade'])) {
112                 $str .= get_string('criteria_descr_grade', 'badges', $param['grade']);
113             }
114         }
115         return $str;
116     }
118     /**
119      * Add appropriate new criteria options to the form
120      *
121      */
122     public function get_options(&$mform) {
123         global $DB;
124         $param = array();
126         if ($this->id !== 0) {
127             $param = reset($this->params);
128         } else {
129             $param['course'] = $mform->getElementValue('course');
130             $mform->removeElement('course');
131         }
132         $course = $DB->get_record('course', array('id' => $param['course']));
134         if (!($course->enablecompletion == COMPLETION_ENABLED)) {
135             $none = true;
136             $message = get_string('completionnotenabled', 'badges');
137         } else {
138             $mform->addElement('header', 'criteria_course', $this->get_title());
139             $mform->addHelpButton('criteria_course', 'criteria_' . $this->criteriatype, 'badges');
140             $parameter = array();
141             $parameter[] =& $mform->createElement('static', 'mgrade_', null, get_string('mingrade', 'badges'));
142             $parameter[] =& $mform->createElement('text', 'grade_' . $param['course'], '', array('size' => '5'));
143             $parameter[] =& $mform->createElement('static', 'complby_' . $param['course'], null, get_string('bydate', 'badges'));
144             $parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['course'], '', array('optional' => true));
145             $mform->setType('grade_' . $param['course'], PARAM_INT);
146             $mform->addGroup($parameter, 'param_' . $param['course'], '', array(' '), false);
148             $mform->disabledIf('bydate_' . $param['course'] . '[day]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
149             $mform->disabledIf('bydate_' . $param['course'] . '[month]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
150             $mform->disabledIf('bydate_' . $param['course'] . '[year]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
152             // Set existing values.
153             if (isset($param['bydate'])) {
154                 $mform->setDefault('bydate_' . $param['course'], $param['bydate']);
155             }
157             if (isset($param['grade'])) {
158                 $mform->setDefault('grade_' . $param['course'], $param['grade']);
159             }
161             // Add hidden elements.
162             $mform->addElement('hidden', 'course_' . $course->id, $course->id);
163             $mform->setType('course_' . $course->id, PARAM_INT);
164             $mform->addElement('hidden', 'agg', BADGE_CRITERIA_AGGREGATION_ALL);
165             $mform->setType('agg', PARAM_INT);
167             $none = false;
168             $message = '';
169         }
170         return array($none, $message);
171     }
173     /**
174      * Review this criteria and decide if it has been completed
175      *
176      * @param int $userid User whose criteria completion needs to be reviewed.
177      * @param bool $filtered An additional parameter indicating that user list
178      *        has been reduced and some expensive checks can be skipped.
179      *
180      * @return bool Whether criteria is complete
181      */
182     public function review($userid, $filtered = false) {
183         $course = new stdClass();
184         $course->id = $this->courseid;
186         if ($this->coursestartdate > time()) {
187             return false;
188         }
190         $info = new completion_info($course);
192         foreach ($this->params as $param) {
193             $check_grade = true;
194             $check_date = true;
196             if (isset($param['grade'])) {
197                 $grade = grade_get_course_grade($userid, $course->id);
198                 $check_grade = ($grade->grade >= $param['grade']);
199             }
201             if (!$filtered && isset($param['bydate'])) {
202                 $cparams = array(
203                         'userid' => $userid,
204                         'course' => $course->id,
205                 );
206                 $completion = new completion_completion($cparams);
207                 $date = $completion->timecompleted;
208                 $check_date = ($date <= $param['bydate']);
209             }
211             if ($info->is_course_complete($userid) && $check_grade && $check_date) {
212                 return true;
213             }
214         }
216         return false;
217     }
219     /**
220      * Returns array with sql code and parameters returning all ids
221      * of users who meet this particular criterion.
222      *
223      * @return array list($join, $where, $params)
224      */
225     public function get_completed_criteria_sql() {
226         // We have only one criterion here, so taking the first one.
227         $coursecriteria = reset($this->params);
229         $join = " LEFT JOIN {course_completions} cc ON cc.userid = u.id AND cc.timecompleted > 0";
230         $where = ' AND cc.course = :courseid ';
231         $params['courseid'] = $this->courseid;
233         // Add by date parameter.
234         if (isset($param['bydate'])) {
235             $where .= ' AND cc.timecompleted <= :completebydate';
236             $params['completebydate'] = $coursecriteria['bydate'];
237         }
239         return array($join, $where, $params);
240     }