MDL-55491 badges: Add cohort as badge criteria
[moodle.git] / badges / criteria / award_criteria_cohort.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 cohort membership badge award criteria type class
19  *
20  * @package    core
21  * @subpackage badges
22  * @copyright  2016 onwards Catalyst IT {@link https://www.catalyst.net.nz/}
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  * @author     Eugene Venter <eugene@catalyst.net.nz>
25  */
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->dirroot.'/cohort/lib.php');
31 /**
32  * Badge award criteria -- award on cohort membership
33  *
34  */
35 class award_criteria_cohort extends award_criteria {
37     /* @var int Criteria [BADGE_CRITERIA_TYPE_COHORT] */
38     public $criteriatype = BADGE_CRITERIA_TYPE_COHORT;
40     public $required_param = 'cohort';
41     public $optional_params = array();
43     /**
44      * Get criteria details for displaying to users
45      *
46      * @return string
47      */
48     public function get_details($short = '') {
49         global $DB, $OUTPUT;
50         $output = array();
51         foreach ($this->params as $p) {
52             $cohortname = $DB->get_field('cohort', 'name', array('id' => $p['cohort']));
53             if (!$cohortname) {
54                 $str = $OUTPUT->error_text(get_string('error:nosuchcohort', 'badges'));
55             } else {
56                 $str = html_writer::tag('b', '"' . $cohortname . '"');
57             }
58             $output[] = $str;
59         }
61         if ($short) {
62             return implode(', ', $output);
63         } else {
64             return html_writer::alist($output, array(), 'ul');
65         }
66     }
69     /**
70      * Add appropriate new criteria options to the form
71      *
72      */
73     public function get_options(&$mform) {
74         global $DB;
75         $none = false;
77         $mform->addElement('header', 'first_header', $this->get_title());
78         $mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges');
80         // Get cohorts
81         $cohorts = $DB->get_records_menu('cohort', array(), 'name ASC', 'id, name');
82         if (!empty($cohorts)) {
83             $select = array();
84             $selected = array();
85             foreach ($cohorts as $cid => $cohortname) {
86                 $select[$cid] = format_string($cohortname, true);
87             }
89             if ($this->id !== 0) {
90                 $selected = array_keys($this->params);
91             }
92             $settings = array('multiple' => 'multiple', 'size' => 20, 'class' => 'selectcohort');
93             $mform->addElement('select', 'cohort_cohorts', get_string('addcohort', 'badges'), $select, $settings);
94             $mform->addRule('cohort_cohorts', get_string('requiredcohort', 'badges'), 'required');
95             $mform->addHelpButton('cohort_cohorts', 'addcohort', 'badges');
97             if ($this->id !== 0) {
98                 $mform->setDefault('cohort_cohorts', $selected);
99             }
100         } else {
101             $mform->addElement('static', 'nocohorts', '', get_string('error:nocohorts', 'badges'));
102             $none = true;
103         }
105         // Add aggregation.
106         if (!$none) {
107             $mform->addElement('header', 'aggregation', get_string('method', 'badges'));
108             $agg = array();
109             $agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodcohort', 'badges'), 1);
110             $agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodcohort', 'badges'), 2);
111             $mform->addGroup($agg, 'methodgr', '', array('<br/>'), false);
112             if ($this->id !== 0) {
113                 $mform->setDefault('agg', $this->method);
114             } else {
115                 $mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY);
116             }
117         }
119         return array($none, get_string('noparamstoadd', 'badges'));
120     }
122     /**
123      * Save criteria records
124      *
125      * @param $params criteria params
126      */
127     public function save($params = array()) {
128         $cohorts = $params['cohort_cohorts'];
129         unset($params['cohort_cohorts']);
130         foreach ($cohorts as $cohortid) {
131             $params["cohort_{$cohortid}"] = $cohortid;
132         }
134         parent::save($params);
135     }
137     /**
138      * Review this criteria and decide if it has been completed
139      *
140      * @return bool Whether criteria is complete
141      */
142     public function review($userid, $filtered = false) {
143         global $DB;
144         $overall = false;
146         foreach ($this->params as $param) {
147             $cohort = $DB->get_record('cohort', array('id' => $param['cohort']));
149             // Extra check in case a cohort was deleted while badge is still active.
150             if (!$cohort) {
151                 if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
152                     return false;
153                 } else {
154                     continue;
155                 }
156             }
158             if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
159                 if (cohort_is_member($cohort->id, $userid)) {
160                     $overall = true;
161                     continue;
162                 } else {
163                     return false;
164                 }
165             } else if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
166                 if (cohort_is_member($cohort->id, $userid)) {
167                     return true;
168                 } else {
169                     $overall = false;
170                     continue;
171                 }
172             }
173         }
175         return $overall;
176     }
178     /**
179      * Checks criteria for any major problems.
180      *
181      * @return array A list containing status and an error message (if any).
182      */
183     public function validate() {
184         global $DB;
185         $params = array_keys($this->params);
186         $method = ($this->method == BADGE_CRITERIA_AGGREGATION_ALL);
187         $singleparam = (count($params) == 1);
189         foreach ($params as $param) {
190             // Perform check if there only one parameter with any type of aggregation,
191             // Or there are more than one parameter with aggregation ALL.
192             if (($singleparam || $method) && !$DB->record_exists('cohort', array('id' => $param))) {
193                 return array(false, get_string('error:invalidparamcohort', 'badges'));
194             }
195         }
197         return array(true, '');
198     }
200     public function get_completed_criteria_sql() {
201 // TODO;
203         return array($join, $where, $params);
204     }