Merge branch 'MDL-73245-master' of https://github.com/cameron1729/moodle
[moodle.git] / competency / classes / template_cohort.php
blobbfc1a80db5ff925c417736794d0df82fe431d5c4
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.
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 * Template cohort persistent.
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();
28 use lang_string;
29 use core_competency\template;
31 /**
32 * Template cohort persistent.
34 * @package core_competency
35 * @copyright 2015 Frédéric Massart - FMCorz.net
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 class template_cohort extends persistent {
40 const TABLE = 'competency_templatecohort';
42 /** 2 hours of threshold to prevent expired plans **/
43 const DUEDATE_THRESHOLD = 7200;
45 /**
46 * Return the custom definition of the properties of this model.
48 * @return array Where keys are the property names.
50 protected static function define_properties() {
51 return array(
52 'templateid' => array(
53 'type' => PARAM_INT
55 'cohortid' => array(
56 'type' => PARAM_INT
61 /**
62 * Validate the cohort ID.
64 * @param int $value The cohort ID.
65 * @return true|lang_string
67 protected function validate_cohortid($value) {
68 global $DB;
69 if (!$DB->record_exists('cohort', array('id' => $value))) {
70 return new lang_string('invaliddata', 'error');
72 return true;
75 /**
76 * Validate the template ID.
78 * @param int $value The template ID.
79 * @return true|lang_string
81 protected function validate_templateid($value) {
82 if (!template::record_exists($value)) {
83 return new lang_string('invaliddata', 'error');
85 return true;
88 /**
89 * Return an array of user IDs for which the plans are missing.
91 * Plans are considered as missing when a member of a cohort does not have a plan created.
92 * When the parameter $unlinkedaremissing is set to false, plans that were unlinked from
93 * their template will be ignored so that we do not recreate unlinked plans endlessly.
95 * This method ignores the due date of the template.
97 * @param int $templateid The template ID.
98 * @param int $cohortid The cohort ID.
99 * @param boolean $unlinkedaremissing When true, unlinked plans are considered as missing.
100 * @return int[] User IDs.
102 public static function get_missing_plans($templateid, $cohortid, $unlinkedaremissing = false) {
103 global $DB;
105 $skipsql = '';
106 $skipparams = array();
107 if (!$unlinkedaremissing) {
108 $skipsql = 'OR p.origtemplateid = :origtemplateid';
109 $skipparams = array('origtemplateid' => $templateid);
112 $sql = "SELECT cm.userid
113 FROM {cohort_members} cm
114 LEFT JOIN {" . plan::TABLE . "} p
115 ON p.userid = cm.userid
116 AND (p.templateid = :templateid
117 $skipsql)
118 WHERE cm.cohortid = :cohortid
119 AND p.id IS NULL";
120 $params = array('templateid' => $templateid, 'cohortid' => $cohortid) + $skipparams;
122 return $DB->get_fieldset_sql($sql, $params);
126 * Get a relation.
128 * This does not perform any validation on the data passed. If the relation exists in the database
129 * then it is loaded in a the model, if not then it is up to the developer to save the model.
131 * @param int $templateid
132 * @param int $cohortid
133 * @return template_cohort
135 public static function get_relation($templateid, $cohortid) {
136 global $DB;
138 $params = array(
139 'templateid' => $templateid,
140 'cohortid' => $cohortid
143 $relation = new static(null, (object) $params);
144 if ($record = $DB->get_record(self::TABLE, $params)) {
145 $relation->from_record($record);
148 return $relation;
152 * Get a relations by templateid.
154 * This does not perform any validation on the data passed. If the relation exists in the database
155 * then it is loaded in a the model, if not then it is up to the developer to save the model.
157 * @param int $templateid
158 * @return template_cohort[] array of template cohort
160 public static function get_relations_by_templateid($templateid) {
161 global $DB;
163 $params = array(
164 'templateid' => $templateid
167 $relations = array();
168 $records = $DB->get_records(self::TABLE, $params);
169 foreach ($records as $record) {
170 $relations[] = new template_cohort(0, $record);
173 return $relations;
177 * Return an array of templates persistent with their missing userids.
179 * Note that only cohorts associated with visible templates are considered,
180 * as well as only templates with a due date in the future, or no due date.
182 * @param int $lastruntime The last time the Cohort ssync task ran.
183 * @param bool $unlinkedaremissing When true, unlinked plans are considered as missing.
184 * @return array( array(
185 * 'template' => \core_competency\template,
186 * 'userids' => array
187 * ))
189 public static function get_all_missing_plans($lastruntime = 0, $unlinkedaremissing = false) {
190 global $DB;
192 $planwhereclause = " WHERE (p.id is NULL
193 AND (cm.timeadded >= :lastruntime1
194 OR tc.timecreated >= :lastruntime3
195 OR t.timemodified >= :lastruntime4))";
197 if ($unlinkedaremissing) {
198 $planwhereclause .= " OR (p.origtemplateid IS NOT NULL AND cm.timeadded < :lastruntime2)";
201 $sql = "SELECT " . $DB->sql_concat('cm.userid', 'tc.templateid') . " as uniqueid, cm.userid, t.*
202 FROM {cohort_members} cm
203 JOIN {" . self::TABLE . "} tc ON cm.cohortid = tc.cohortid
204 JOIN {" . template::TABLE . "} t
205 ON (tc.templateid = t.id AND t.visible = 1)
206 AND (t.duedate = 0 OR t.duedate > :time1)
207 LEFT JOIN {" . plan::TABLE . "} p ON (cm.userid = p.userid AND (t.id = p.templateid OR t.id = p.origtemplateid))
208 $planwhereclause
209 ORDER BY t.id";
211 $params = array('time1' => time(), 'time2' => time(),
212 'lastruntime1' => $lastruntime, 'lastruntime2' => $lastruntime,
213 'lastruntime3' => $lastruntime, 'lastruntime4' => $lastruntime);
214 $results = $DB->get_records_sql($sql, $params);
216 $missingplans = array();
217 foreach ($results as $usertemplate) {
218 $userid = $usertemplate->userid;
220 // Check if template already exist in the array.
221 if (isset($missingplans[$usertemplate->id])) {
222 $missingplans[$usertemplate->id]['userids'][] = $userid;
223 } else {
224 unset($usertemplate->userid);
225 unset($usertemplate->uniqueid);
226 $template = new template(0, $usertemplate);
227 $missingplans[$template->get('id')]['template'] = $template;
228 $missingplans[$template->get('id')]['userids'][] = $userid;
231 return array_values($missingplans);