2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Competency rule points based.
20 * @package core_competency
21 * @copyright 2015 Frédéric Massart - FMCorz.net
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace core_competency
;
26 defined('MOODLE_INTERNAL') ||
die();
33 * Competency rule points based class.
35 * This rule matches when related competencies contribute for a required number of points.
37 * @package core_competency
38 * @copyright 2015 Frédéric Massart - FMCorz.net
39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 class competency_rule_points
extends competency_rule
{
44 * Get the rule config.
48 protected function get_config() {
49 $config = parent
::get_config();
50 return json_decode($config);
54 * Whether or not the rule is matched.
56 * @param user_competency $usercompetency The user competency.
59 public function matches(user_competency
$usercompetency) {
62 $config = $this->get_config();
63 $pointsrequired = $config->base
->points
;
65 // Index by competency ID and extract required.
66 $compsrules = array();
67 $requiredids = array();
68 foreach ($config->competencies
as $comp) {
69 $compsrules[$comp->id
] = $comp;
70 if ($comp->required
) {
71 $requiredids[$comp->id
] = $comp->id
;
75 // Find all the user competency records.
76 list($insql, $params) = $DB->get_in_or_equal(array_keys($compsrules), SQL_PARAMS_NAMED
);
77 $sql = "userid = :userid
78 AND proficiency = :proficiency
79 AND competencyid $insql";
80 $params['userid'] = $usercompetency->get('userid');
81 $params['proficiency'] = 1;
82 $ucs = user_competency
::get_records_select($sql, $params, '', 'competencyid');
84 // Check that all the required are found.
85 if (!empty($requiredids)) {
86 $unmetrequired = array_diff_key($requiredids, $ucs);
87 if (!empty($unmetrequired)) {
92 // Check that we have enough points.
94 foreach ($compsrules as $compid => $comp) {
95 if (array_key_exists($compid, $ucs)) {
96 $points +
= $comp->points
;
100 return $points >= $pointsrequired;
104 * Validate the rule config.
106 * @param string $value The value to validate.
109 public function validate_config($value) {
111 $config = json_decode($value);
112 if ($config === null ||
!isset($config->base
) ||
!isset($config->competencies
)) {
116 if (!isset($config->base
->points
)) {
121 $requiredpoints = validate_param($config->base
->points
, PARAM_INT
);
122 } catch (\invalid_parameter_exception
$e) {
126 if ($requiredpoints < 1) {
132 // Validate the competency info.
133 foreach ($config->competencies
as $competency) {
135 // Cannot include self.
136 if ($competency->id
== $this->competency
->get('id')) {
140 // Check for duplicates.
141 if (in_array($competency->id
, $compids)) {
145 // Check for required fields.
146 if (!isset($competency->id
)
147 ||
!isset($competency->points
)
148 ||
!isset($competency->required
)) {
152 // Validate the parameters.
154 validate_param($competency->id
, PARAM_INT
);
155 $points = validate_param($competency->points
, PARAM_INT
);
156 validate_param($competency->required
, PARAM_BOOL
);
157 } catch (\invalid_parameter_exception
$e) {
161 $totalpoints +
= $points;
166 $compids[] = $competency->id
;
169 // No competencies, that's strange.
170 if (empty($compids)) {
174 // Impossible to reach the points required.
175 if ($requiredpoints > $totalpoints) {
179 // Check that all the competencies are children of the competency.
180 // We may want to relax this check at a later stage if we want to allow competencies
181 // to be linked throughout the whole framework.
182 return $this->competency
->is_parent_of($compids);
186 * The name of the rule.
188 * @return lang_string
190 public static function get_name() {
191 return new lang_string('pointsrequiredaremet', 'core_competency');
195 * Migrate rule config when duplicate competency based on mapping competencies ids.
197 * @param string $config the config rule of a competency
198 * @param array $mappings array that match the old competency ids with the new competencies
201 public static function migrate_config($config, $mappings) {
202 $ruleconfig = json_decode($config, true);
203 if (is_array($ruleconfig)) {
204 foreach ($ruleconfig['competencies'] as $key => $rulecomp) {
205 $rulecmpid = $rulecomp['id'];
206 if (array_key_exists($rulecmpid, $mappings)) {
207 $ruleconfig['competencies'][$key]['id'] = $mappings[$rulecmpid]->get('id');
209 throw new coding_exception("The competency id is not found in the matchids.");
213 throw new coding_exception("Invalid JSON config rule.");
216 return json_encode($ruleconfig);