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 * Guesses course start and end dates based on activity logs. 19 * 20 * @package tool_analytics 21 * @copyright 2016 David Monllao {@link http://www.davidmonllao.com} 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 define('CLI_SCRIPT', true); 26 27 require_once(__DIR__ . '/../../../../config.php'); 28 require_once($CFG->libdir.'/clilib.php'); 29 30 require_once($CFG->dirroot . '/course/lib.php'); 31 require_once($CFG->dirroot . '/course/format/weeks/lib.php'); 32 33 $help = "Guesses course start and end dates based on activity logs. 34 35 IMPORTANT: Don't use this script if you keep previous academic years users enrolled in courses. Guesses would not be accurate. 36 37 Options: 38 --guessstart Guess the course start date (default to true) 39 --guessend Guess the course end date (default to true) 40 --guessall Guess all start and end dates, even if they are already set (default to false) 41 --update Update the db or just notify the guess (default to false) 42 --filter Analyser dependant. e.g. A courseid would evaluate the model using a single course (Optional) 43 -h, --help Print out this help 44 45 Example: 46 \$ php admin/tool/analytics/cli/guess_course_start_and_end_dates.php --update=1 --filter=123,321 47 "; 48 49 // Now get cli options. 50 list($options, $unrecognized) = cli_get_params( 51 array( 52 'help' => false, 53 'guessstart' => true, 54 'guessend' => true, 55 'guessall' => false, 56 'update' => false, 57 'filter' => false 58 ), 59 array( 60 'h' => 'help', 61 ) 62 ); 63 64 if ($options['help']) { 65 echo $help; 66 exit(0); 67 } 68 69 if ($options['guessstart'] === false && $options['guessend'] === false && $options['guessall'] === false) { 70 echo $help; 71 exit(0); 72 } 73 74 // Reformat them as an array. 75 if ($options['filter'] !== false) { 76 $options['filter'] = explode(',', clean_param($options['filter'], PARAM_SEQUENCE)); 77 } 78 79 // We need admin permissions. 80 \core\session\manager::set_user(get_admin()); 81 82 $conditions = array('id != 1'); 83 if (!$options['guessall']) { 84 if ($options['guessstart']) { 85 $conditions[] = '(startdate is null or startdate = 0)'; 86 } 87 if ($options['guessend']) { 88 $conditions[] = '(enddate is null or enddate = 0)'; 89 } 90 } 91 92 $coursessql = ''; 93 $params = null; 94 if ($options['filter']) { 95 list($coursessql, $params) = $DB->get_in_or_equal($options['filter'], SQL_PARAMS_NAMED); 96 $conditions[] = 'id ' . $coursessql; 97 } 98 99 $courses = $DB->get_recordset_select('course', implode(' AND ', $conditions), $params, 'sortorder ASC'); 100 foreach ($courses as $course) { 101 tool_analytics_calculate_course_dates($course, $options); 102 } 103 $courses->close(); 104 105 106 /** 107 * tool_analytics_calculate_course_dates 108 * 109 * @param stdClass $course 110 * @param array $options CLI options 111 * @return void 112 */ 113 function tool_analytics_calculate_course_dates($course, $options) { 114 global $DB, $OUTPUT; 115 116 $courseman = new \core_analytics\course($course); 117 118 $notification = $course->shortname . ' (id = ' . $course->id . '): '; 119 120 $originalenddate = null; 121 $guessedstartdate = null; 122 $guessedenddate = null; 123 $samestartdate = null; 124 $lowerenddate = null; 125 126 if ($options['guessstart'] || $options['guessall']) { 127 128 $originalstartdate = $course->startdate; 129 130 $guessedstartdate = $courseman->guess_start(); 131 $samestartdate = ($guessedstartdate == $originalstartdate); 132 $lowerenddate = ($course->enddate && ($course->enddate < $guessedstartdate)); 133 134 if ($samestartdate) { 135 if (!$guessedstartdate) { 136 $notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics'); 137 } else { 138 // No need to update. 139 $notification .= PHP_EOL . ' ' . get_string('samestartdate', 'tool_analytics') . ': ' . userdate($guessedstartdate); 140 } 141 } else if (!$guessedstartdate) { 142 $notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics'); 143 } else if ($lowerenddate) { 144 $notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics') . ': ' . 145 get_string('enddatebeforestartdate', 'error') . ' - ' . userdate($guessedstartdate); 146 } else { 147 // Update it to something we guess. 148 149 // We set it to $course even if we don't update because may be needed to guess the end one. 150 $course->startdate = $guessedstartdate; 151 $notification .= PHP_EOL . ' ' . get_string('startdate') . ': ' . userdate($guessedstartdate); 152 153 // Two different course updates because week's end date may be recalculated after setting the start date. 154 if ($options['update']) { 155 update_course($course); 156 157 // Refresh course data as end date may have been updated. 158 $course = $DB->get_record('course', array('id' => $course->id)); 159 $courseman = new \core_analytics\course($course); 160 } 161 } 162 } 163 164 if ($options['guessend'] || $options['guessall']) { 165 166 if (!empty($lowerenddate) && !empty($guessedstartdate)) { 167 $course->startdate = $guessedstartdate; 168 } 169 170 $originalenddate = $course->enddate; 171 172 $format = course_get_format($course); 173 $formatoptions = $format->get_format_options(); 174 175 // Change this for a course formats API level call in MDL-60702. 176 if ((get_class($format) == 'format_weeks' || is_subclass_of($format, 'format_weeks')) && 177 method_exists($format, 'update_end_date') && $formatoptions['automaticenddate']) { 178 // Special treatment for weeks-based formats with automatic end date. 179 180 if ($options['update']) { 181 $format::update_end_date($course->id); 182 $course->enddate = $DB->get_field('course', 'enddate', array('id' => $course->id)); 183 $notification .= PHP_EOL . ' ' . get_string('weeksenddateautomaticallyset', 'tool_analytics') . ': ' . 184 userdate($course->enddate); 185 } else { 186 // We can't provide more info without actually updating it in db. 187 $notification .= PHP_EOL . ' ' . get_string('weeksenddatedefault', 'tool_analytics'); 188 } 189 } else { 190 $guessedenddate = $courseman->guess_end(); 191 192 if ($guessedenddate == $originalenddate) { 193 if (!$guessedenddate) { 194 $notification .= PHP_EOL . ' ' . get_string('cantguessenddate', 'tool_analytics'); 195 } else { 196 // No need to update. 197 $notification .= PHP_EOL . ' ' . get_string('sameenddate', 'tool_analytics') . ': ' . userdate($guessedenddate); 198 } 199 } else if (!$guessedenddate) { 200 $notification .= PHP_EOL . ' ' . get_string('cantguessenddate', 'tool_analytics'); 201 } else { 202 // Update it to something we guess. 203 204 $course->enddate = $guessedenddate; 205 206 $updateit = false; 207 if ($course->enddate < $course->startdate) { 208 $notification .= PHP_EOL . ' ' . get_string('errorendbeforestart', 'course', userdate($course->enddate)); 209 } else if ($course->startdate + (YEARSECS + (WEEKSECS * 4)) > $course->enddate) { 210 $notification .= PHP_EOL . ' ' . get_string('coursetoolong', 'course'); 211 } else { 212 $notification .= PHP_EOL . ' ' . get_string('enddate') . ': ' . userdate($course->enddate); 213 $updateit = true; 214 } 215 216 if ($options['update'] && $updateit) { 217 update_course($course); 218 } 219 } 220 } 221 222 } 223 224 mtrace($notification); 225 } 226 227 mtrace(get_string('success')); 228 229 exit(0);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body