Compare commits
319 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab9936962e | |||
| d39fcc420e | |||
| 08641175b3 | |||
| 66aee746e3 | |||
| f738fc8efd | |||
| 27973b545c | |||
| 3192438075 | |||
| 41b7375c07 | |||
| cb04dcf4ce | |||
| c3925187ed | |||
| 4ceece6ea1 | |||
| cfbc820e1b | |||
| fbbcf45ef2 | |||
| 6e2d8c121b | |||
| 6b2a9a6fb8 | |||
| fb5bbf1424 | |||
| ce225e1c5e | |||
| 08b7558483 | |||
| 9dead25fd5 | |||
| eac88b955f | |||
| 438c98cc98 | |||
| ba854606e6 | |||
| f5b63fc829 | |||
| 6996fbaa0e | |||
| 20305a8a8f | |||
| 5da020169e | |||
| 2f673d8b6a | |||
| 4bcb0a9a1d | |||
| a4e0b7468c | |||
| 7fdcdc04ff | |||
| bef5a8ca10 | |||
| 246698e779 | |||
| 4f3262fede | |||
| f169f4fd21 | |||
| d48d1ba19a | |||
| 7a571b813a | |||
| 754016ab33 | |||
| 10c17dcc10 | |||
| 5518a32de5 | |||
| 56f05f23c6 | |||
| bb869f05e8 | |||
| 7cf4331a6f | |||
| 762f8dc1db | |||
| a997dc9da5 | |||
| 446b21b512 | |||
| 3968d2ca7e | |||
| 68c580c903 | |||
| 0c0d460e8b | |||
| ed0e2cea00 | |||
| 7effd6dd79 | |||
| 29adfbc3c8 | |||
| 4e73acf3cf | |||
| fcafb22c22 | |||
| 6463a047a2 | |||
| ccf7578373 | |||
| 68ba214c65 | |||
| a471bc4971 | |||
| b6319f70bd | |||
| d3882ea4a3 | |||
| e759c9ed83 | |||
| c9f995872f | |||
| 2e36c42625 | |||
| 7a2300fd82 | |||
| f3342e1010 | |||
| ea90412944 | |||
| 8d64443452 | |||
| 4b0facc984 | |||
| d6d2cec4a0 | |||
| 57c9b7fc37 | |||
| cae37299f3 | |||
| c835126185 | |||
| 5243e93661 | |||
| b135c42a17 | |||
| ec8f488f30 | |||
| aa30dc8860 | |||
| 76f98c3bd5 | |||
| 7783fd0ec1 | |||
| a6943ebb59 | |||
| eaa43a132c | |||
| 81aa5e196f | |||
| b5b81de3d6 | |||
| f0fc8a194a | |||
| 03561ea899 | |||
| 6688ae2ba2 | |||
| b44bc9bf6c | |||
| 65c52e05d1 | |||
| 1ccc9f1953 | |||
| efe2681894 | |||
| e3a6d44845 | |||
| 8aa01fcf61 | |||
| 8072eb1384 | |||
| b9ae53f86b | |||
| 5616a31987 | |||
| 8926030555 | |||
| 13b19e40cb | |||
| 478b1d194f | |||
| 9aac9f7074 | |||
| 3a0951f027 | |||
| 7d416f9c2c | |||
| 589b602be3 | |||
| 8001199766 | |||
| a56833d49d | |||
| be88f0993d | |||
| 11e60032be | |||
| 401710883b | |||
| 40f05d2312 | |||
| 3602df58b2 | |||
| f3743b3041 | |||
| e2d635bbaf | |||
| a764855641 | |||
| 9b0f29239b | |||
| 8ce86ebba3 | |||
| 30890c2971 | |||
| 1bd70073c5 | |||
| 9e0884d410 | |||
| af25b8fc7f | |||
| ef29782f31 | |||
| 1ada616c56 | |||
| 8443b88995 | |||
| eb354bdefa | |||
| 4cd3927c4f | |||
| 6a973d261a | |||
| 796e48a58b | |||
| 496b39974f | |||
| 6586118e0f | |||
| 4a145a8ae5 | |||
| da8a0c97f0 | |||
| 20b2565c38 | |||
| 36e84e96fc | |||
| 159b4e5d8c | |||
| aa95085969 | |||
| 79ea89fea2 | |||
| 928bcb02d6 | |||
| b9fd516407 | |||
| c2502375ff | |||
| 20a5056df6 | |||
| 4071a2b6fe | |||
| 6630b38c95 | |||
| b974b5d05d | |||
| 1ab858314a | |||
| 6be1923d81 | |||
| 801a372dad | |||
| 1322351b92 | |||
| bb2071ca17 | |||
| be713b7144 | |||
| e20752c4f5 | |||
| 30ff29dc9f | |||
| 6607c5ffb6 | |||
| 7f14def230 | |||
| 39e364515f | |||
| 557d8528eb | |||
| 0bd6039f40 | |||
| 57e8c9f748 | |||
| 7b7bf31d4c | |||
| 59aff5f949 | |||
| f816ea9a67 | |||
| 6e3314f044 | |||
| 2a542d0265 | |||
| f18fb611c9 | |||
| 43caf0217f | |||
| 7b03092121 | |||
| 5dbd051502 | |||
| c39a22f600 | |||
| f0f38bf1d3 | |||
| 41080050b0 | |||
| ae348e78a0 | |||
| 71fc06aae5 | |||
| e3491a093a | |||
| a0a78199b8 | |||
| d523cbcb26 | |||
| 5c9acb8164 | |||
| 8242027da3 | |||
| fd2f1ae146 | |||
| c8419f87c0 | |||
| 4837fea0aa | |||
| 671440d708 | |||
| 6c3f463dbd | |||
| fca7e60c81 | |||
| 1e83eec993 | |||
| 216bb33940 | |||
| 58280ae0b8 | |||
| 0df5c743ad | |||
| e8da33d86e | |||
| 02331dcd48 | |||
| c8e7777766 | |||
| d25f1c3c3c | |||
| ab2095fb0f | |||
| 6b839f3222 | |||
| 66242b95e0 | |||
| 9a428ae012 | |||
| b8243e4164 | |||
| 14a1672cff | |||
| 89cf38c6d9 | |||
| 43a1e9a2a5 | |||
| 82735dec4d | |||
| 76f11421a4 | |||
| 1b0978abf3 | |||
| 098b16fb13 | |||
| 4916c9bb66 | |||
| 8fcb479246 | |||
| 73ec9b4778 | |||
| 9cca2db570 | |||
| 9daa5874a0 | |||
| 60829fbe6d | |||
| 9f33d5ac6e | |||
| 1cc7a14ce4 | |||
| 958c9c17ca | |||
| 4397da0c4d | |||
| d8966238dd | |||
| 065a754111 | |||
| 3e4de62607 | |||
| a37faf9c70 | |||
| aba60237cd | |||
| 5836baf593 | |||
| ed44df22a8 | |||
| 314b8093e7 | |||
| ade8dd5d08 | |||
| 28196427a2 | |||
| 8c4d7cee79 | |||
| 64476c520e | |||
| c851ee5ddb | |||
| 860d33c90a | |||
| eefa2c88e0 | |||
| 284c795d23 | |||
| 808b68835b | |||
| 46a3753424 | |||
| 7336f854e6 | |||
| 6065875eac | |||
| 3fdecc2841 | |||
| 8c00d189f4 | |||
| 8c7db03a56 | |||
| c550fd0e11 | |||
| 349b705d31 | |||
| 9cc55074d5 | |||
| 4fab795ac9 | |||
| 51af04ab2f | |||
| 9e6d1a3884 | |||
| 391ea5b7de | |||
| 9d0e1fca5a | |||
| 8f730872a7 | |||
| 4febb36efe | |||
| 368832d51c | |||
| cc80554892 | |||
| e905b656f5 | |||
| 526d354991 | |||
| eb3b38f04c | |||
| a1b696f943 | |||
| 4e52eb8eb0 | |||
| dae0ccfc45 | |||
| 40f1801c4b | |||
| 6078d420bf | |||
| 2479a7c446 | |||
| ef9f60a635 | |||
| db9d745c7b | |||
| 0d049757c0 | |||
| 0f56f6e6da | |||
| ff340a0afa | |||
| 62a38a4ece | |||
| a272c25649 | |||
| a9ca3fa167 | |||
| 7ec04e0e09 | |||
| 1fc642324a | |||
| 7f91fb036b | |||
| fd39db29e2 | |||
| 341505e5de | |||
| ef7df2ae0a | |||
| ed6d81c9f7 | |||
| 01ed53df0f | |||
| 4d03dbf13d | |||
| 4cc469b2cc | |||
| 1b7d75f19f | |||
| 4dc645d64d | |||
| a5327e449d | |||
| 4d4b8ae6bf | |||
| 1e67827131 | |||
| 7dfc9ea6b3 | |||
| 69e89f4a82 | |||
| b799cde890 | |||
| 9fd91f8eec | |||
| 6e186498fd | |||
| 3c2b703e00 | |||
| e6ccfad242 | |||
| 75909e3c92 | |||
| 2a1f7a4442 | |||
| 7851132177 | |||
| 4f7a80341e | |||
| 3b4e9a9fc8 | |||
| 507335e2de | |||
| 5b93dc8539 | |||
| 3a89d0b541 | |||
| cc4d7ce61b | |||
| b8bb8fe8de | |||
| a66de3ca70 | |||
| 13e7626834 | |||
| 6a633d36c2 | |||
| 7b18365be7 | |||
| 89ceede3bf | |||
| 8e85371800 | |||
| 786d9cd3a1 | |||
| 994ccb7845 | |||
| c282157fc3 | |||
| ff456b59ea | |||
| 88924ff772 | |||
| 57f4e9608d | |||
| 1003e7e57e | |||
| 429f78412d | |||
| d2065abd0b | |||
| 5fd7c11d17 | |||
| acd146fe7c | |||
| 79dff18711 | |||
| 9da0be8c46 | |||
| 80e4426aeb | |||
| 9eced5050b | |||
| 6d5f9d1218 | |||
| 71826ac268 | |||
| 21824a9325 | |||
| 9016f772ce | |||
| 84346754f6 | |||
| 5ef66eaf7e |
+5
-5
@@ -13,7 +13,7 @@ language: php
|
||||
|
||||
php:
|
||||
# We only run the highest and lowest supported versions to reduce the load on travis-ci.org.
|
||||
- 7.1
|
||||
- 7.2
|
||||
- 7.0
|
||||
|
||||
addons:
|
||||
@@ -30,7 +30,7 @@ env:
|
||||
# Although we want to run these jobs and see failures as quickly as possible, we also want to get the slowest job to
|
||||
# start first so that the total run time is not too high.
|
||||
#
|
||||
# We only run MySQL on PHP 7.1, so run that first.
|
||||
# We only run MySQL on PHP 7.2, so run that first.
|
||||
# CI Tests should be second-highest in priority as these only take <= 60 seconds to run under normal circumstances.
|
||||
# Postgres is significantly is pretty reasonable in its run-time.
|
||||
|
||||
@@ -54,12 +54,12 @@ matrix:
|
||||
|
||||
include:
|
||||
# Run grunt/npm install on highest version ('node' is an alias for the latest node.js version.)
|
||||
- php: 7.1
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='node'
|
||||
- php: 7.2
|
||||
env: DB=none TASK=GRUNT NVM_VERSION='8.9'
|
||||
|
||||
exclude:
|
||||
# MySQL - it's just too slow.
|
||||
# Exclude it on all versions except for 7.1
|
||||
# Exclude it on all versions except for 7.2
|
||||
|
||||
- env: DB=mysqli TASK=PHPUNIT
|
||||
php: 7.0
|
||||
|
||||
@@ -1754,6 +1754,7 @@
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.6.5" level="required">
|
||||
<RESTRICT function="restrict_php_version_72" message="unsupportedphpversion72" />
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
@@ -1919,6 +1920,7 @@
|
||||
<VENDOR name="oracle" version="10.2" />
|
||||
</DATABASE>
|
||||
<PHP version="5.6.5" level="required">
|
||||
<RESTRICT function="restrict_php_version_72" message="unsupportedphpversion72" />
|
||||
</PHP>
|
||||
<PCREUNICODE level="optional">
|
||||
<FEEDBACK>
|
||||
|
||||
+2
-1
@@ -868,6 +868,7 @@ $cachewarnings = cache_helper::warnings();
|
||||
$eventshandlers = $DB->get_records_sql('SELECT DISTINCT component FROM {events_handlers}');
|
||||
$themedesignermode = !empty($CFG->themedesignermode);
|
||||
$mobileconfigured = !empty($CFG->enablemobilewebservice);
|
||||
$invalidforgottenpasswordurl = !empty($CFG->forgottenpasswordurl) && empty(clean_param($CFG->forgottenpasswordurl, PARAM_URL));
|
||||
|
||||
// Check if a directory with development libraries exists.
|
||||
if (empty($CFG->disabledevlibdirscheck) && (is_dir($CFG->dirroot.'/vendor') || is_dir($CFG->dirroot.'/node_modules'))) {
|
||||
@@ -885,4 +886,4 @@ $output = $PAGE->get_renderer('core', 'admin');
|
||||
echo $output->admin_notifications_page($maturity, $insecuredataroot, $errorsdisplayed, $cronoverdue, $dbproblems,
|
||||
$maintenancemode, $availableupdates, $availableupdatesfetch, $buggyiconvnomb,
|
||||
$registered, $cachewarnings, $eventshandlers, $themedesignermode, $devlibdir,
|
||||
$mobileconfigured, $overridetossl);
|
||||
$mobileconfigured, $overridetossl, $invalidforgottenpasswordurl);
|
||||
|
||||
@@ -36,6 +36,6 @@ class core_register_renderer extends plugin_renderer_base {
|
||||
* @return string
|
||||
*/
|
||||
public function moodleorg_registration_message() {
|
||||
return format_text(get_string('registermoodlenet', 'admin'), FORMAT_MARKDOWN, ['noclean' => true]);
|
||||
return format_text(get_string('registermoodlenet', 'admin'), FORMAT_HTML, ['noclean' => true]);
|
||||
}
|
||||
}
|
||||
|
||||
+21
-1
@@ -280,6 +280,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
* @param bool $devlibdir Warn about development libs directory presence.
|
||||
* @param bool $mobileconfigured Whether the mobile web services have been enabled
|
||||
* @param bool $overridetossl Whether or not ssl is being forced.
|
||||
* @param bool $invalidforgottenpasswordurl Whether the forgotten password URL does not link to a valid URL.
|
||||
*
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
@@ -287,7 +288,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$cronoverdue, $dbproblems, $maintenancemode, $availableupdates, $availableupdatesfetch,
|
||||
$buggyiconvnomb, $registered, array $cachewarnings = array(), $eventshandlers = 0,
|
||||
$themedesignermode = false, $devlibdir = false, $mobileconfigured = false,
|
||||
$overridetossl = false) {
|
||||
$overridetossl = false, $invalidforgottenpasswordurl = false) {
|
||||
global $CFG;
|
||||
$output = '';
|
||||
|
||||
@@ -308,6 +309,7 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
$output .= $this->events_handlers($eventshandlers);
|
||||
$output .= $this->registration_warning($registered);
|
||||
$output .= $this->mobile_configuration_warning($mobileconfigured);
|
||||
$output .= $this->forgotten_password_url_warning($invalidforgottenpasswordurl);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//// IT IS ILLEGAL AND A VIOLATION OF THE GPL TO HIDE, REMOVE OR MODIFY THIS COPYRIGHT NOTICE ///
|
||||
@@ -866,6 +868,24 @@ class core_admin_renderer extends plugin_renderer_base {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a warning about the forgotten password URL not linking to a valid URL.
|
||||
*
|
||||
* @param boolean $invalidforgottenpasswordurl true if the forgotten password URL is not valid
|
||||
* @return string HTML to output.
|
||||
*/
|
||||
protected function forgotten_password_url_warning($invalidforgottenpasswordurl) {
|
||||
$output = '';
|
||||
if ($invalidforgottenpasswordurl) {
|
||||
$settingslink = new moodle_url('/admin/settings.php', ['section' => 'manageauths']);
|
||||
$configurebutton = $this->single_button($settingslink, get_string('check', 'moodle'));
|
||||
$output .= $this->warning(get_string('invalidforgottenpasswordurl', 'admin') . ' ' . $configurebutton,
|
||||
'error alert alert-danger');
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to render the information about the available Moodle update
|
||||
*
|
||||
|
||||
@@ -102,7 +102,7 @@ if ($hassiteconfig) {
|
||||
$temp->add(new admin_setting_configtext('alternateloginurl', new lang_string('alternateloginurl', 'auth'),
|
||||
new lang_string('alternatelogin', 'auth', htmlspecialchars(get_login_url())), ''));
|
||||
$temp->add(new admin_setting_configtext('forgottenpasswordurl', new lang_string('forgottenpasswordurl', 'auth'),
|
||||
new lang_string('forgottenpassword', 'auth'), ''));
|
||||
new lang_string('forgottenpassword', 'auth'), '', PARAM_URL));
|
||||
$temp->add(new admin_setting_confightmleditor('auth_instructions', new lang_string('instructions', 'auth'),
|
||||
new lang_string('authinstructions', 'auth'), ''));
|
||||
$setting = new admin_setting_configtext('allowemailaddresses', new lang_string('allowemailaddresses', 'admin'),
|
||||
|
||||
@@ -264,8 +264,13 @@ class models_list implements \renderable, \templatable {
|
||||
} else {
|
||||
$url = new \moodle_url('/admin/settings.php', array('section' => 'analyticssettings'),
|
||||
'id_s_analytics_onlycli');
|
||||
|
||||
$langstrid = 'clievaluationandpredictionsnoadmin';
|
||||
if (is_siteadmin()) {
|
||||
$langstrid = 'clievaluationandpredictions';
|
||||
}
|
||||
$data->infos = array(
|
||||
(object)array('message' => get_string('clievaluationandpredictions', 'tool_analytics', $url->out()),
|
||||
(object)array('message' => get_string($langstrid, 'tool_analytics', $url->out()),
|
||||
'closebutton' => true)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,12 +117,21 @@ function tool_analytics_calculate_course_dates($course, $options) {
|
||||
|
||||
$notification = $course->shortname . ' (id = ' . $course->id . '): ';
|
||||
|
||||
$originalenddate = null;
|
||||
$guessedstartdate = null;
|
||||
$guessedenddate = null;
|
||||
$samestartdate = null;
|
||||
$lowerenddate = null;
|
||||
|
||||
if ($options['guessstart'] || $options['guessall']) {
|
||||
|
||||
$originalstartdate = $course->startdate;
|
||||
|
||||
$guessedstartdate = $courseman->guess_start();
|
||||
if ($guessedstartdate == $originalstartdate) {
|
||||
$samestartdate = ($guessedstartdate == $originalstartdate);
|
||||
$lowerenddate = ($course->enddate && ($course->enddate < $guessedstartdate));
|
||||
|
||||
if ($samestartdate) {
|
||||
if (!$guessedstartdate) {
|
||||
$notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics');
|
||||
} else {
|
||||
@@ -131,6 +140,9 @@ function tool_analytics_calculate_course_dates($course, $options) {
|
||||
}
|
||||
} else if (!$guessedstartdate) {
|
||||
$notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics');
|
||||
} else if ($lowerenddate) {
|
||||
$notification .= PHP_EOL . ' ' . get_string('cantguessstartdate', 'tool_analytics') . ': ' .
|
||||
get_string('enddatebeforestartdate', 'error') . ' - ' . userdate($guessedstartdate);
|
||||
} else {
|
||||
// Update it to something we guess.
|
||||
|
||||
@@ -151,16 +163,21 @@ function tool_analytics_calculate_course_dates($course, $options) {
|
||||
|
||||
if ($options['guessend'] || $options['guessall']) {
|
||||
|
||||
if (!empty($lowerenddate) && !empty($guessedstartdate)) {
|
||||
$course->startdate = $guessedstartdate;
|
||||
}
|
||||
|
||||
$originalenddate = $course->enddate;
|
||||
|
||||
$format = course_get_format($course);
|
||||
$formatoptions = $format->get_format_options();
|
||||
|
||||
if ($course->format === 'weeks' && $formatoptions['automaticenddate']) {
|
||||
// Special treatment for weeks with automatic end date.
|
||||
// Change this for a course formats API level call in MDL-60702.
|
||||
if (method_exists($format, 'update_end_date') && $formatoptions['automaticenddate']) {
|
||||
// Special treatment for weeks-based formats with automatic end date.
|
||||
|
||||
if ($options['update']) {
|
||||
format_weeks::update_end_date($course->id);
|
||||
$format::update_end_date($course->id);
|
||||
$course->enddate = $DB->get_field('course', 'enddate', array('id' => $course->id));
|
||||
$notification .= PHP_EOL . ' ' . get_string('weeksenddateautomaticallyset', 'tool_analytics') . ': ' .
|
||||
userdate($course->enddate);
|
||||
@@ -195,10 +212,8 @@ function tool_analytics_calculate_course_dates($course, $options) {
|
||||
$updateit = true;
|
||||
}
|
||||
|
||||
if ($options['update']) {
|
||||
if ($course->enddate > $course->startdate) {
|
||||
update_course($course);
|
||||
}
|
||||
if ($options['update'] && $updateit) {
|
||||
update_course($course);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ $string['clearpredictions'] = 'Clear predictions';
|
||||
$string['clearmodelpredictions'] = 'Are you sure you want to clear all "{$a}" predictions?';
|
||||
$string['clienablemodel'] = 'You can enable the model by selecting a time-splitting method by its ID. Note that you can also enable it later using the web interface (\'none\' to exit).';
|
||||
$string['clievaluationandpredictions'] = 'A scheduled task iterates through enabled models and gets predictions. Models evaluation via the web interface is disabled. You can allow these processes to be executed manually via the web interface by disabling the <a href="{$a}">\'onlycli\'</a> analytics setting.';
|
||||
$string['clievaluationandpredictionsnoadmin'] = 'A scheduled task iterates through enabled models and gets predictions. Models evaluation via the web interface is disabled. It may be enabled by a site administrator.';
|
||||
$string['editmodel'] = 'Edit "{$a}" model';
|
||||
$string['edittrainedwarning'] = 'This model has already been trained. Note that changing its indicators or its time-splitting method will delete its previous predictions and start generating new predictions.';
|
||||
$string['enabled'] = 'Enabled';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_analytics'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_assignmentupgrade';
|
||||
$plugin->dependencies = array('mod_assign' => 2017050500);
|
||||
$plugin->dependencies = array('mod_assign' => 2017110800);
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_availabilityconditions';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_behat'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_capability'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_cohortroles'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
$plugin->dependencies = array(
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_customlang'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_dbtransfer'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_filetypes';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_generator';
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_health'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
$plugin->maturity = MATURITY_ALPHA; // this version's maturity level
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
namespace tool_httpsreplace;
|
||||
|
||||
use database_column_info;
|
||||
use progress_bar;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
@@ -60,7 +63,7 @@ class url_finder {
|
||||
* for less straightforward swaps.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $column
|
||||
* @param database_column_info $column
|
||||
* @param string $domain
|
||||
* @param string $search search string that has prefix, protocol, domain name and one extra character,
|
||||
* example1: src="http://host.com/
|
||||
@@ -174,7 +177,7 @@ class url_finder {
|
||||
$regex = '#((src|data)\ *=\ *[\'\"])(http://)([^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))[\'\"]#i';
|
||||
preg_match_all($regex, $record->$columnname, $match);
|
||||
foreach ($match[0] as $i => $fullmatch) {
|
||||
if (strpos($fullmatch, $CFG->wwwroot) !== false) {
|
||||
if (\core_text::strpos($fullmatch, $CFG->wwwroot) !== false) {
|
||||
continue;
|
||||
}
|
||||
$prefix = $match[1][$i];
|
||||
@@ -186,7 +189,7 @@ class url_finder {
|
||||
}
|
||||
if ($replacing) {
|
||||
// For replace string use: prefix, protocol, host and one extra character.
|
||||
$found[$prefix . substr($url, 0, strlen($host) + 8)] = $host;
|
||||
$found[$prefix . \core_text::substr($url, 0, \core_text::strlen($host) + 8)] = $host;
|
||||
} else {
|
||||
$entry["table"] = $table;
|
||||
$entry["columnname"] = $columnname;
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017082500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017082400; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_httpsreplace'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_innodb'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'tool_installaddon';
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->maturity = MATURITY_STABLE;
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_langimport'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017062600; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'logstore_database'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'logstore_legacy'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'logstore_standard'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_log'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$plugin->version = 2017062700; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_lp'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_lpimportcsv'; // Full name of the plugin (used for diagnostics).
|
||||
$plugin->dependencies = array('tool_lp' => 2017050500);
|
||||
$plugin->dependencies = array('tool_lp' => 2017110800);
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_lpmigrate'; // Full name of the plugin (used for diagnostics).
|
||||
$plugin->dependencies = array(
|
||||
'tool_lp' => ANY_VERSION
|
||||
|
||||
@@ -584,10 +584,10 @@ class manager {
|
||||
'usestream' => true,
|
||||
));
|
||||
|
||||
if ($part === $plainpartid) {
|
||||
if ($part == $plainpartid) {
|
||||
$contentplain = $this->process_message_part_body($messagedata, $partdata, $part);
|
||||
|
||||
} else if ($part === $htmlpartid) {
|
||||
} else if ($part == $htmlpartid) {
|
||||
$contenthtml = $this->process_message_part_body($messagedata, $partdata, $part);
|
||||
|
||||
} else if ($filename = $partdata->getName($part)) {
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_messageinbound';
|
||||
|
||||
@@ -140,7 +140,7 @@ class api {
|
||||
'rememberusername' => $CFG->rememberusername,
|
||||
'authloginviaemail' => $CFG->authloginviaemail,
|
||||
'registerauth' => $CFG->registerauth,
|
||||
'forgottenpasswordurl' => $CFG->forgottenpasswordurl,
|
||||
'forgottenpasswordurl' => clean_param($CFG->forgottenpasswordurl, PARAM_URL), // We may expect a mailto: here.
|
||||
'authinstructions' => $authinstructions,
|
||||
'authnoneenabled' => (int) is_enabled_auth('none'),
|
||||
'enablewebservices' => $CFG->enablewebservices,
|
||||
@@ -386,7 +386,8 @@ class api {
|
||||
// Return certificate information and verify the certificate.
|
||||
$curl->setopt(array('CURLOPT_CERTINFO' => 1, 'CURLOPT_SSL_VERIFYPEER' => true));
|
||||
$httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot); // Force https url.
|
||||
$curl->head($httpswwwroot . "/login/index.php");
|
||||
// Check https using a page not redirecting or returning exceptions.
|
||||
$curl->head($httpswwwroot . "/$CFG->admin/tool/mobile/mobile.webmanifest.php");
|
||||
$info = $curl->get_info();
|
||||
|
||||
// First of all, check the server certificate (if any).
|
||||
|
||||
@@ -97,11 +97,13 @@ class tool_mobile_external_testcase extends externallib_advanced_testcase {
|
||||
set_config('typeoflogin', api::LOGIN_VIA_BROWSER, 'tool_mobile');
|
||||
set_config('logo', 'mock.png', 'core_admin');
|
||||
set_config('logocompact', 'mock.png', 'core_admin');
|
||||
set_config('forgottenpasswordurl', 'mailto:fake@email.zy'); // Test old hack.
|
||||
|
||||
list($authinstructions, $notusedformat) = external_format_text($authinstructions, FORMAT_MOODLE, $context->id);
|
||||
$expected['registerauth'] = 'email';
|
||||
$expected['authinstructions'] = $authinstructions;
|
||||
$expected['typeoflogin'] = api::LOGIN_VIA_BROWSER;
|
||||
$expected['forgottenpasswordurl'] = ''; // Expect empty when it's not an URL.
|
||||
|
||||
if ($logourl = $OUTPUT->get_logo_url()) {
|
||||
$expected['logourl'] = $logourl->out(false);
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
$plugin->version = 2017051501; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_mobile'; // Full name of the plugin (used for diagnostics).
|
||||
$plugin->dependencies = array(
|
||||
'webservice_rest' => 2017050500
|
||||
'webservice_rest' => 2017110800
|
||||
);
|
||||
|
||||
@@ -26,6 +26,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_monitor'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_multilangupgrade'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_oauth2'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ if ($options['run']) {
|
||||
}
|
||||
}
|
||||
$_SERVER['argv'] = array_values($_SERVER['argv']);
|
||||
PHPUnit_TextUI_Command::main();
|
||||
PHPUnit\TextUI\Command::main();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_phpunit'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_profiling'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_recyclebin'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_replace'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
$plugin->maturity = MATURITY_ALPHA; // this version's maturity level
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'tool_spamcleaner'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_task'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_templatelibrary'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_unsuproles'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_uploadcourse'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_uploaduser'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current module version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current module version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'tool_usertours'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'tool_xmldb'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ defined('MOODLE_INTERNAL') || die();
|
||||
/**
|
||||
* Any element analysers can analyse.
|
||||
*
|
||||
* Analysers get_analysers method return all analysable elements in the site;
|
||||
* it is important that analysable elements implement lazy loading to avoid
|
||||
* big memory footprints. See \core_analytics\course example.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @copyright 2016 David Monllao {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
|
||||
+87
-235
@@ -40,9 +40,19 @@ require_once($CFG->dirroot . '/lib/enrollib.php');
|
||||
class course implements \core_analytics\analysable {
|
||||
|
||||
/**
|
||||
* @var \core_analytics\course[] $instances
|
||||
* @var bool Has this course data been already loaded.
|
||||
*/
|
||||
protected static $instances = array();
|
||||
protected $loaded = false;
|
||||
|
||||
/**
|
||||
* @var int $cachedid self::$cachedinstance analysable id.
|
||||
*/
|
||||
protected static $cachedid = 0;
|
||||
|
||||
/**
|
||||
* @var \core_analytics\course $cachedinstance
|
||||
*/
|
||||
protected static $cachedinstance = null;
|
||||
|
||||
/**
|
||||
* Course object
|
||||
@@ -122,7 +132,7 @@ class course implements \core_analytics\analysable {
|
||||
* Use self::instance() instead to get cached copies of the course. Instances obtained
|
||||
* through this constructor will not be cached.
|
||||
*
|
||||
* Loads course students and teachers.
|
||||
* Lazy load of course data, students and teachers.
|
||||
*
|
||||
* @param int|stdClass $course Course id
|
||||
* @return void
|
||||
@@ -130,18 +140,70 @@ class course implements \core_analytics\analysable {
|
||||
public function __construct($course) {
|
||||
|
||||
if (is_scalar($course)) {
|
||||
$this->course = get_course($course);
|
||||
$this->course = new \stdClass();
|
||||
$this->course->id = $course;
|
||||
} else {
|
||||
$this->course = $course;
|
||||
}
|
||||
}
|
||||
|
||||
$this->coursecontext = \context_course::instance($this->course->id);
|
||||
/**
|
||||
* Returns an analytics course instance.
|
||||
*
|
||||
* Lazy load of course data, students and teachers.
|
||||
*
|
||||
* @param int|stdClass $course Course object or course id
|
||||
* @return \core_analytics\course
|
||||
*/
|
||||
public static function instance($course) {
|
||||
|
||||
$courseid = $course;
|
||||
if (!is_scalar($courseid)) {
|
||||
$courseid = $course->id;
|
||||
}
|
||||
|
||||
if (self::$cachedid === $courseid) {
|
||||
return self::$cachedinstance;
|
||||
}
|
||||
|
||||
$cachedinstance = new \core_analytics\course($course);
|
||||
self::$cachedinstance = $cachedinstance;
|
||||
self::$cachedid = (int)$courseid;
|
||||
return self::$cachedinstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->course->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the analytics course object.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
protected function load() {
|
||||
|
||||
// The instance constructor could be already loaded with the full course object. Using shortname
|
||||
// because it is a required course field.
|
||||
if (empty($this->course->shortname)) {
|
||||
$this->course = get_course($this->course->id);
|
||||
}
|
||||
|
||||
$this->coursecontext = $this->get_context();
|
||||
|
||||
$this->now = time();
|
||||
|
||||
// Get the course users, including users assigned to student and teacher roles at an higher context.
|
||||
$cache = \cache::make_from_params(\cache_store::MODE_REQUEST, 'core_analytics', 'rolearchetypes');
|
||||
|
||||
// Flag the instance as loaded.
|
||||
$this->loaded = true;
|
||||
|
||||
if (!$studentroles = $cache->get('student')) {
|
||||
$studentroles = array_keys(get_archetype_roles('student'));
|
||||
$cache->set('student', $studentroles);
|
||||
@@ -155,53 +217,13 @@ class course implements \core_analytics\analysable {
|
||||
$this->teacherids = $this->get_user_ids($teacherroles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an analytics course instance.
|
||||
*
|
||||
* @param int|stdClass $course Course id
|
||||
* @return \core_analytics\course
|
||||
*/
|
||||
public static function instance($course) {
|
||||
|
||||
$courseid = $course;
|
||||
if (!is_scalar($courseid)) {
|
||||
$courseid = $course->id;
|
||||
}
|
||||
|
||||
if (!empty(self::$instances[$courseid])) {
|
||||
return self::$instances[$courseid];
|
||||
}
|
||||
|
||||
$instance = new \core_analytics\course($course);
|
||||
self::$instances[$courseid] = $instance;
|
||||
return self::$instances[$courseid];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all statically cached instances.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function reset_caches() {
|
||||
self::$instances = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* get_id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->course->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The course short name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name() {
|
||||
return format_string($this->course->shortname, true, array('context' => $this->get_context()));
|
||||
return format_string($this->get_course_data()->shortname, true, array('context' => $this->get_context()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -228,8 +250,8 @@ class course implements \core_analytics\analysable {
|
||||
}
|
||||
|
||||
// The field always exist but may have no valid if the course is created through a sync process.
|
||||
if (!empty($this->course->startdate)) {
|
||||
$this->starttime = (int)$this->course->startdate;
|
||||
if (!empty($this->get_course_data()->startdate)) {
|
||||
$this->starttime = (int)$this->get_course_data()->startdate;
|
||||
} else {
|
||||
$this->starttime = 0;
|
||||
}
|
||||
@@ -256,7 +278,7 @@ class course implements \core_analytics\analysable {
|
||||
|
||||
// We first try to find current course student logs.
|
||||
$firstlogs = array();
|
||||
foreach ($this->studentids as $studentid) {
|
||||
foreach ($this->get_students() as $studentid) {
|
||||
// Grrr, we are limited by logging API, we could do this easily with a
|
||||
// select min(timecreated) from xx where courseid = yy group by userid.
|
||||
|
||||
@@ -278,7 +300,7 @@ class course implements \core_analytics\analysable {
|
||||
sort($firstlogs);
|
||||
$firstlogsmedian = $this->median($firstlogs);
|
||||
|
||||
$studentenrolments = enrol_get_course_users($this->get_id(), $this->studentids);
|
||||
$studentenrolments = enrol_get_course_users($this->get_id(), $this->get_students());
|
||||
if (empty($studentenrolments)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -306,8 +328,8 @@ class course implements \core_analytics\analysable {
|
||||
}
|
||||
|
||||
// The enddate field is only available from Moodle 3.2 (MDL-22078).
|
||||
if (!empty($this->course->enddate)) {
|
||||
$this->endtime = (int)$this->course->enddate;
|
||||
if (!empty($this->get_course_data()->enddate)) {
|
||||
$this->endtime = (int)$this->get_course_data()->enddate;
|
||||
return $this->endtime;
|
||||
}
|
||||
|
||||
@@ -334,7 +356,7 @@ class course implements \core_analytics\analysable {
|
||||
$monthsago = time() - (WEEKSECS * 4 * 2);
|
||||
$select = $filterselect . ' AND timeaccess > :timeaccess';
|
||||
$params = $filterparams + array('timeaccess' => $monthsago);
|
||||
$sql = "SELECT timeaccess FROM {user_lastaccess} ula
|
||||
$sql = "SELECT DISTINCT timeaccess FROM {user_lastaccess} ula
|
||||
JOIN {enrol} e ON e.courseid = ula.courseid
|
||||
JOIN {user_enrolments} ue ON e.id = ue.enrolid AND ue.userid = ula.userid
|
||||
WHERE $select";
|
||||
@@ -342,7 +364,7 @@ class course implements \core_analytics\analysable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$sql = "SELECT timeaccess FROM {user_lastaccess} ula
|
||||
$sql = "SELECT DISTINCT timeaccess FROM {user_lastaccess} ula
|
||||
JOIN {enrol} e ON e.courseid = ula.courseid
|
||||
JOIN {user_enrolments} ue ON e.id = ue.enrolid AND ue.userid = ula.userid
|
||||
WHERE $filterselect AND ula.timeaccess != 0
|
||||
@@ -362,21 +384,12 @@ class course implements \core_analytics\analysable {
|
||||
* @return \stdClass
|
||||
*/
|
||||
public function get_course_data() {
|
||||
return $this->course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the course valid to extract indicators from it?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_valid() {
|
||||
|
||||
if (!$this->was_started() || !$this->is_finished()) {
|
||||
return false;
|
||||
if (!$this->loaded) {
|
||||
$this->load();
|
||||
}
|
||||
|
||||
return true;
|
||||
return $this->course;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,7 +440,7 @@ class course implements \core_analytics\analysable {
|
||||
public function get_user_ids($roleids) {
|
||||
|
||||
// We need to index by ra.id as a user may have more than 1 $roles role.
|
||||
$records = get_role_users($roleids, $this->coursecontext, true, 'ra.id, u.id AS userid, r.id AS roleid', 'ra.id ASC');
|
||||
$records = get_role_users($roleids, $this->get_context(), true, 'ra.id, u.id AS userid, r.id AS roleid', 'ra.id ASC');
|
||||
|
||||
// If a user have more than 1 $roles role array_combine will discard the duplicate.
|
||||
$callable = array($this, 'filter_user_id');
|
||||
@@ -441,6 +454,11 @@ class course implements \core_analytics\analysable {
|
||||
* @return stdClass[]
|
||||
*/
|
||||
public function get_students() {
|
||||
|
||||
if (!$this->loaded) {
|
||||
$this->load();
|
||||
}
|
||||
|
||||
return $this->studentids;
|
||||
}
|
||||
|
||||
@@ -453,7 +471,7 @@ class course implements \core_analytics\analysable {
|
||||
global $DB;
|
||||
|
||||
// No logs if no students.
|
||||
if (empty($this->studentids)) {
|
||||
if (empty($this->get_students())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -529,172 +547,6 @@ class course implements \core_analytics\analysable {
|
||||
return $grades;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses all activities that were available during a period of time.
|
||||
*
|
||||
* @param string $activitytype
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @param \stdClass $student
|
||||
* @return array
|
||||
*/
|
||||
public function get_activities($activitytype, $starttime, $endtime, $student = false) {
|
||||
|
||||
// Var $student may not be available, default to not calculating dynamic data.
|
||||
$studentid = -1;
|
||||
if ($student) {
|
||||
$studentid = $student->id;
|
||||
}
|
||||
$modinfo = get_fast_modinfo($this->get_course_data(), $studentid);
|
||||
$activities = $modinfo->get_instances_of($activitytype);
|
||||
|
||||
$timerangeactivities = array();
|
||||
foreach ($activities as $activity) {
|
||||
if (!$this->completed_by($activity, $starttime, $endtime)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$timerangeactivities[$activity->context->id] = $activity;
|
||||
}
|
||||
|
||||
return $timerangeactivities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was the activity supposed to be completed during the provided time range?.
|
||||
*
|
||||
* @param \cm_info $activity
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @return bool
|
||||
*/
|
||||
protected function completed_by(\cm_info $activity, $starttime, $endtime) {
|
||||
|
||||
// We can't check uservisible because:
|
||||
// - Any activity with available until would not be counted.
|
||||
// - Sites may block student's course view capabilities once the course is closed.
|
||||
|
||||
// Students can not view hidden activities by default, this is not reliable 100% but accurate in most of the cases.
|
||||
if ($activity->visible === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We skip activities that were not yet visible or their 'until' was not in this $starttime - $endtime range.
|
||||
if ($activity->availability) {
|
||||
$info = new \core_availability\info_module($activity);
|
||||
$activityavailability = $this->availability_completed_by($info, $starttime, $endtime);
|
||||
if ($activityavailability === false) {
|
||||
return false;
|
||||
} else if ($activityavailability === true) {
|
||||
// This activity belongs to this time range.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We skip activities in sections that were not yet visible or their 'until' was not in this $starttime - $endtime range.
|
||||
$section = $activity->get_modinfo()->get_section_info($activity->sectionnum);
|
||||
if ($section->availability) {
|
||||
$info = new \core_availability\info_section($section);
|
||||
$sectionavailability = $this->availability_completed_by($info, $starttime, $endtime);
|
||||
if ($sectionavailability === false) {
|
||||
return false;
|
||||
} else if ($sectionavailability === true) {
|
||||
// This activity belongs to this section time range.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// When the course is using format weeks we use the week's end date.
|
||||
$format = course_get_format($activity->get_modinfo()->get_course());
|
||||
if ($this->course->format === 'weeks') {
|
||||
$dates = $format->get_section_dates($section);
|
||||
|
||||
// We need to consider the +2 hours added by get_section_dates.
|
||||
// Avoid $starttime <= $dates->end because $starttime may be the start of the next week.
|
||||
if ($starttime < ($dates->end - 7200) && $endtime >= ($dates->end - 7200)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($activity->sectionnum == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->get_end() || !$this->get_start()) {
|
||||
debugging('Activities which due date is in a time range can not be calculated ' .
|
||||
'if the course doesn\'t have start and end date', DEBUG_DEVELOPER);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!course_format_uses_sections($this->course->format)) {
|
||||
// If it does not use sections and there are no availability conditions to access it it is available
|
||||
// and we can not magically classify it into any other time range than this one.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Split the course duration in the number of sections and consider the end of each section the due
|
||||
// date of all activities contained in that section.
|
||||
$formatoptions = $format->get_format_options();
|
||||
if (!empty($formatoptions['numsections'])) {
|
||||
$nsections = $formatoptions['numsections'];
|
||||
} else {
|
||||
// There are course format that use sections but without numsections, we fallback to the number
|
||||
// of cached sections in get_section_info_all, not that accurate though.
|
||||
$coursesections = $activity->get_modinfo()->get_section_info_all();
|
||||
$nsections = count($coursesections);
|
||||
if (isset($coursesections[0])) {
|
||||
// We don't count section 0 if it exists.
|
||||
$nsections--;
|
||||
}
|
||||
}
|
||||
|
||||
$courseduration = $this->get_end() - $this->get_start();
|
||||
$sectionduration = round($courseduration / $nsections);
|
||||
$activitysectionenddate = $this->get_start() + ($sectionduration * $activity->sectionnum);
|
||||
if ($activitysectionenddate > $starttime && $activitysectionenddate <= $endtime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the activity/section should have been completed during the provided period according to its availability rules.
|
||||
*
|
||||
* @param \core_availability\info $info
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @return bool|null
|
||||
*/
|
||||
protected function availability_completed_by(\core_availability\info $info, $starttime, $endtime) {
|
||||
|
||||
$dateconditions = $info->get_availability_tree()->get_all_children('\availability_date\condition');
|
||||
foreach ($dateconditions as $condition) {
|
||||
// Availability API does not allow us to check from / to dates nicely, we need to be naughty.
|
||||
$conditiondata = $condition->save();
|
||||
|
||||
if ($conditiondata->d === \availability_date\condition::DIRECTION_FROM &&
|
||||
$conditiondata->t > $endtime) {
|
||||
// Skip this activity if any 'from' date is later than the end time.
|
||||
return false;
|
||||
|
||||
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
|
||||
($conditiondata->t < $starttime || $conditiondata->t > $endtime)) {
|
||||
// Skip activity if any 'until' date is not in $starttime - $endtime range.
|
||||
return false;
|
||||
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
|
||||
$conditiondata->t < $endtime && $conditiondata->t > $starttime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// This can be interpreted as 'the activity was available but we don't know if its expected completion date
|
||||
// was during this period.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by get_user_ids to extract the user id.
|
||||
*
|
||||
@@ -731,7 +583,7 @@ class course implements \core_analytics\analysable {
|
||||
}
|
||||
|
||||
// Check the amount of student logs in the 4 previous weeks.
|
||||
list($studentssql, $studentsparams) = $DB->get_in_or_equal($this->studentids, SQL_PARAMS_NAMED);
|
||||
list($studentssql, $studentsparams) = $DB->get_in_or_equal($this->get_students(), SQL_PARAMS_NAMED);
|
||||
$filterselect = $prefix . 'courseid = :courseid AND ' . $prefix . 'userid ' . $studentssql;
|
||||
$filterparams = array('courseid' => $this->course->id) + $studentsparams;
|
||||
|
||||
|
||||
@@ -44,17 +44,21 @@ abstract class by_course extends base {
|
||||
|
||||
// Default to all system courses.
|
||||
if (!empty($this->options['filter'])) {
|
||||
$courses = $this->options['filter'];
|
||||
$courses = array();
|
||||
foreach ($this->options['filter'] as $courseid) {
|
||||
$courses[$courseid] = new \stdClass();
|
||||
$courses[$courseid]->id = $courseid;
|
||||
}
|
||||
} else {
|
||||
// Iterate through all potentially valid courses.
|
||||
$courses = get_courses('all', 'c.sortorder ASC');
|
||||
$courses = get_courses('all', 'c.sortorder ASC', 'c.id');
|
||||
}
|
||||
unset($courses[SITEID]);
|
||||
|
||||
$analysables = array();
|
||||
foreach ($courses as $course) {
|
||||
// Skip the frontpage course.
|
||||
$analysable = \core_analytics\course::instance($course);
|
||||
$analysable = \core_analytics\course::instance($course->id);
|
||||
$analysables[$analysable->get_id()] = $analysable;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,13 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
abstract class community_of_inquiry_activity extends linear {
|
||||
|
||||
/**
|
||||
* instancedata
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $instancedata = array();
|
||||
|
||||
/**
|
||||
* @var \core_analytics\course
|
||||
*/
|
||||
@@ -60,6 +67,56 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
*/
|
||||
const INDICATOR_SOCIAL = "social";
|
||||
|
||||
/**
|
||||
* Constant for this cognitive level.
|
||||
*/
|
||||
const COGNITIVE_LEVEL_1 = 1;
|
||||
|
||||
/**
|
||||
* Constant for this cognitive level.
|
||||
*/
|
||||
const COGNITIVE_LEVEL_2 = 2;
|
||||
|
||||
/**
|
||||
* Constant for this cognitive level.
|
||||
*/
|
||||
const COGNITIVE_LEVEL_3 = 3;
|
||||
|
||||
/**
|
||||
* Constant for this cognitive level.
|
||||
*/
|
||||
const COGNITIVE_LEVEL_4 = 4;
|
||||
|
||||
/**
|
||||
* Constant for this cognitive level.
|
||||
*/
|
||||
const COGNITIVE_LEVEL_5 = 5;
|
||||
|
||||
/**
|
||||
* Constant for this social level.
|
||||
*/
|
||||
const SOCIAL_LEVEL_1 = 1;
|
||||
|
||||
/**
|
||||
* Constant for this social level.
|
||||
*/
|
||||
const SOCIAL_LEVEL_2 = 2;
|
||||
|
||||
/**
|
||||
* Constant for this social level.
|
||||
*/
|
||||
const SOCIAL_LEVEL_3 = 3;
|
||||
|
||||
/**
|
||||
* Constant for this social level.
|
||||
*/
|
||||
const SOCIAL_LEVEL_4 = 4;
|
||||
|
||||
/**
|
||||
* Constant for this social level.
|
||||
*/
|
||||
const SOCIAL_LEVEL_5 = 5;
|
||||
|
||||
/**
|
||||
* Max cognitive depth level accepted.
|
||||
*/
|
||||
@@ -428,8 +485,8 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
// Samples are at cm level or below.
|
||||
$useractivities = array(\context_module::instance($cm->id)->id => $cm);
|
||||
} else {
|
||||
// All course activities.
|
||||
$useractivities = $this->course->get_activities($this->get_activity_type(), $starttime, $endtime, $user);
|
||||
// Activities that should be completed during this time period.
|
||||
$useractivities = $this->get_activities($starttime, $endtime, $user);
|
||||
}
|
||||
|
||||
return $useractivities;
|
||||
@@ -530,13 +587,15 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
foreach ($useractivities as $contextid => $cm) {
|
||||
|
||||
$potentiallevel = $this->get_cognitive_depth_level($cm);
|
||||
if (!is_int($potentiallevel) || $potentiallevel > self::MAX_COGNITIVE_LEVEL || $potentiallevel < 1) {
|
||||
if (!is_int($potentiallevel)
|
||||
|| $potentiallevel > self::MAX_COGNITIVE_LEVEL
|
||||
|| $potentiallevel < self::COGNITIVE_LEVEL_1) {
|
||||
throw new \coding_exception('Activities\' potential cognitive depth go from 1 to 5.');
|
||||
}
|
||||
$scoreperlevel = $scoreperactivity / $potentiallevel;
|
||||
|
||||
switch ($potentiallevel) {
|
||||
case 5:
|
||||
case self::COGNITIVE_LEVEL_5:
|
||||
// Cognitive level 5 is to submit after feedback.
|
||||
if ($this->any_feedback('submitted', $cm, $contextid, $user)) {
|
||||
$score += $scoreperlevel * 5;
|
||||
@@ -544,7 +603,7 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
}
|
||||
// The user didn't reach the activity max cognitive depth, continue with level 2.
|
||||
|
||||
case 4:
|
||||
case self::COGNITIVE_LEVEL_4:
|
||||
// Cognitive level 4 is to comment on feedback.
|
||||
if ($this->any_feedback('replied', $cm, $contextid, $user)) {
|
||||
$score += $scoreperlevel * 4;
|
||||
@@ -552,7 +611,7 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
}
|
||||
// The user didn't reach the activity max cognitive depth, continue with level 2.
|
||||
|
||||
case 3:
|
||||
case self::COGNITIVE_LEVEL_3:
|
||||
// Cognitive level 3 is to view feedback.
|
||||
|
||||
if ($this->any_feedback('viewed', $cm, $contextid, $user)) {
|
||||
@@ -562,7 +621,7 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
}
|
||||
// The user didn't reach the activity max cognitive depth, continue with level 2.
|
||||
|
||||
case 2:
|
||||
case self::COGNITIVE_LEVEL_2:
|
||||
// Cognitive depth level 2 is to submit content.
|
||||
|
||||
if ($this->any_write_log($contextid, $user)) {
|
||||
@@ -571,7 +630,7 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
}
|
||||
// The user didn't reach the activity max cognitive depth, continue with level 1.
|
||||
|
||||
case 1:
|
||||
case self::COGNITIVE_LEVEL_1:
|
||||
// Cognitive depth level 1 is just accessing the activity.
|
||||
|
||||
if ($this->any_log($contextid, $user)) {
|
||||
@@ -617,16 +676,18 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
foreach ($useractivities as $contextid => $cm) {
|
||||
|
||||
$potentiallevel = $this->get_social_breadth_level($cm);
|
||||
if (!is_int($potentiallevel) || $potentiallevel > self::MAX_SOCIAL_LEVEL || $potentiallevel < 1) {
|
||||
if (!is_int($potentiallevel)
|
||||
|| $potentiallevel > self::MAX_SOCIAL_LEVEL
|
||||
|| $potentiallevel < self::SOCIAL_LEVEL_1) {
|
||||
throw new \coding_exception('Activities\' potential social breadth go from 1 to ' .
|
||||
community_of_inquiry_activity::MAX_SOCIAL_LEVEL . '.');
|
||||
}
|
||||
$scoreperlevel = $scoreperactivity / $potentiallevel;
|
||||
switch ($potentiallevel) {
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case self::SOCIAL_LEVEL_2:
|
||||
case self::SOCIAL_LEVEL_3:
|
||||
case self::SOCIAL_LEVEL_4:
|
||||
case self::SOCIAL_LEVEL_5:
|
||||
// Core activities social breadth only reaches level 2, until core activities social
|
||||
// breadth do not reach level 5 we limit it to what we currently support, which is level 2.
|
||||
|
||||
@@ -639,7 +700,7 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
}
|
||||
// The user didn't reach the activity max social breadth, continue with level 1.
|
||||
|
||||
case 1:
|
||||
case self::SOCIAL_LEVEL_1:
|
||||
// Social breadth level 1 is just accessing the activity.
|
||||
if ($this->any_log($contextid, $user)) {
|
||||
$score += $scoreperlevel;
|
||||
@@ -687,6 +748,250 @@ abstract class community_of_inquiry_activity extends linear {
|
||||
$this->grades = $course->get_student_grades($courseactivities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses all activities that were available during a period of time.
|
||||
*
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @param \stdClass|false $student
|
||||
* @return array
|
||||
*/
|
||||
protected function get_activities($starttime, $endtime, $student = false) {
|
||||
|
||||
$activitytype = $this->get_activity_type();
|
||||
|
||||
// Var $student may not be available, default to not calculating dynamic data.
|
||||
$studentid = -1;
|
||||
if ($student) {
|
||||
$studentid = $student->id;
|
||||
}
|
||||
$modinfo = get_fast_modinfo($this->course->get_course_data(), $studentid);
|
||||
$activities = $modinfo->get_instances_of($activitytype);
|
||||
|
||||
$timerangeactivities = array();
|
||||
foreach ($activities as $activity) {
|
||||
|
||||
if (!$this->activity_completed_by($activity, $starttime, $endtime, $student)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$timerangeactivities[$activity->context->id] = $activity;
|
||||
}
|
||||
|
||||
return $timerangeactivities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Was the activity supposed to be completed during the provided time range?.
|
||||
*
|
||||
* @param \cm_info $activity
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @param \stdClass|false $student
|
||||
* @return bool
|
||||
*/
|
||||
protected function activity_completed_by(\cm_info $activity, $starttime, $endtime, $student = false) {
|
||||
|
||||
// We can't check uservisible because:
|
||||
// - Any activity with available until would not be counted.
|
||||
// - Sites may block student's course view capabilities once the course is closed.
|
||||
|
||||
// Students can not view hidden activities by default, this is not reliable 100% but accurate in most of the cases.
|
||||
if ($activity->visible === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Give priority to the different methods activities have to set a "due" date.
|
||||
$return = $this->activity_type_completed_by($activity, $starttime, $endtime, $student);
|
||||
if (!is_null($return)) {
|
||||
// Method activity_type_completed_by returns null if there is no due date method or there is but it is not set.
|
||||
return $return;
|
||||
}
|
||||
|
||||
// We skip activities that were not yet visible or their 'until' was not in this $starttime - $endtime range.
|
||||
if ($activity->availability) {
|
||||
$info = new \core_availability\info_module($activity);
|
||||
$activityavailability = $this->availability_completed_by($info, $starttime, $endtime);
|
||||
if ($activityavailability === false) {
|
||||
return false;
|
||||
} else if ($activityavailability === true) {
|
||||
// This activity belongs to this time range.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We skip activities in sections that were not yet visible or their 'until' was not in this $starttime - $endtime range.
|
||||
$section = $activity->get_modinfo()->get_section_info($activity->sectionnum);
|
||||
if ($section->availability) {
|
||||
$info = new \core_availability\info_section($section);
|
||||
$sectionavailability = $this->availability_completed_by($info, $starttime, $endtime);
|
||||
if ($sectionavailability === false) {
|
||||
return false;
|
||||
} else if ($sectionavailability === true) {
|
||||
// This activity belongs to this section time range.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// When the course is using format weeks we use the week's end date.
|
||||
$format = course_get_format($activity->get_modinfo()->get_course());
|
||||
// We should change this in MDL-60702.
|
||||
if (method_exists($format, 'get_section_dates')) {
|
||||
$dates = $format->get_section_dates($section);
|
||||
|
||||
// We need to consider the +2 hours added by get_section_dates.
|
||||
// Avoid $starttime <= $dates->end because $starttime may be the start of the next week.
|
||||
if ($starttime < ($dates->end - 7200) && $endtime >= ($dates->end - 7200)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($activity->sectionnum == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->course->get_end() || !$this->course->get_start()) {
|
||||
debugging('Activities which due date is in a time range can not be calculated ' .
|
||||
'if the course doesn\'t have start and end date', DEBUG_DEVELOPER);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!course_format_uses_sections($this->course->get_course_data()->format)) {
|
||||
// If it does not use sections and there are no availability conditions to access it it is available
|
||||
// and we can not magically classify it into any other time range than this one.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Split the course duration in the number of sections and consider the end of each section the due
|
||||
// date of all activities contained in that section.
|
||||
$formatoptions = $format->get_format_options();
|
||||
if (!empty($formatoptions['numsections'])) {
|
||||
$nsections = $formatoptions['numsections'];
|
||||
} else {
|
||||
// There are course format that use sections but without numsections, we fallback to the number
|
||||
// of cached sections in get_section_info_all, not that accurate though.
|
||||
$coursesections = $activity->get_modinfo()->get_section_info_all();
|
||||
$nsections = count($coursesections);
|
||||
if (isset($coursesections[0])) {
|
||||
// We don't count section 0 if it exists.
|
||||
$nsections--;
|
||||
}
|
||||
}
|
||||
|
||||
$courseduration = $this->course->get_end() - $this->course->get_start();
|
||||
$sectionduration = round($courseduration / $nsections);
|
||||
$activitysectionenddate = $this->course->get_start() + ($sectionduration * $activity->sectionnum);
|
||||
if ($activitysectionenddate > $starttime && $activitysectionenddate <= $endtime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the activity is due or it has been closed during this period, false if during another period, null if no due time.
|
||||
*
|
||||
* It can be overwritten by activities that allow teachers to set a due date or a time close separately
|
||||
* from Moodle availability system. Note that in most of the cases overwriting get_timeclose_field should
|
||||
* be enough.
|
||||
*
|
||||
* Returns true or false if the time close date falls into the provided time range. Null otherwise.
|
||||
*
|
||||
* @param \cm_info $activity
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @param \stdClass|false $student
|
||||
* @return null
|
||||
*/
|
||||
protected function activity_type_completed_by(\cm_info $activity, $starttime, $endtime, $student = false) {
|
||||
|
||||
$fieldname = $this->get_timeclose_field();
|
||||
if (!$fieldname) {
|
||||
// This activity type do not have its own availability control.
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->fill_instance_data($activity);
|
||||
$instance = $this->instancedata[$activity->instance];
|
||||
|
||||
if (!$instance->{$fieldname}) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($starttime < $instance->{$fieldname} && $endtime >= $instance->{$fieldname}) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the field that controls activity availability.
|
||||
*
|
||||
* Should be overwritten by activities that allow teachers to set a due date or a time close separately
|
||||
* from Moodle availability system.
|
||||
*
|
||||
* Just 1 field will not be enough for all cases, but for the most simple ones without
|
||||
* overrides and stuff like that.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function get_timeclose_field() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the activity/section should have been completed during the provided period according to its availability rules.
|
||||
*
|
||||
* @param \core_availability\info $info
|
||||
* @param int $starttime
|
||||
* @param int $endtime
|
||||
* @return bool|null
|
||||
*/
|
||||
protected function availability_completed_by(\core_availability\info $info, $starttime, $endtime) {
|
||||
|
||||
$dateconditions = $info->get_availability_tree()->get_all_children('\availability_date\condition');
|
||||
foreach ($dateconditions as $condition) {
|
||||
// Availability API does not allow us to check from / to dates nicely, we need to be naughty.
|
||||
$conditiondata = $condition->save();
|
||||
|
||||
if ($conditiondata->d === \availability_date\condition::DIRECTION_FROM &&
|
||||
$conditiondata->t > $endtime) {
|
||||
// Skip this activity if any 'from' date is later than the end time.
|
||||
return false;
|
||||
|
||||
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
|
||||
($conditiondata->t < $starttime || $conditiondata->t > $endtime)) {
|
||||
// Skip activity if any 'until' date is not in $starttime - $endtime range.
|
||||
return false;
|
||||
} else if ($conditiondata->d === \availability_date\condition::DIRECTION_UNTIL &&
|
||||
$conditiondata->t < $endtime && $conditiondata->t > $starttime) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// This can be interpreted as 'the activity was available but we don't know if its expected completion date
|
||||
// was during this period.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in activity instance data.
|
||||
*
|
||||
* @param \cm_info $cm
|
||||
* @return void
|
||||
*/
|
||||
protected function fill_instance_data(\cm_info $cm) {
|
||||
global $DB;
|
||||
|
||||
if (!isset($this->instancedata[$cm->instance])) {
|
||||
$this->instancedata[$cm->instance] = $DB->get_record($this->get_activity_type(), array('id' => $cm->instance),
|
||||
'*', MUST_EXIST);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines indicator type.
|
||||
*
|
||||
|
||||
@@ -197,6 +197,10 @@ abstract class base {
|
||||
|
||||
$dataset = $this->calculate_indicators($sampleids, $samplesorigin, $indicators, $ranges);
|
||||
|
||||
if (empty($dataset)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now that we have the indicators in place we can add the time range indicators (and target if provided) to each of them.
|
||||
$this->fill_dataset($dataset, $calculatedtarget);
|
||||
|
||||
|
||||
+131
-26
@@ -15,7 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Unit tests for course activities.
|
||||
* Unit tests for activities completed by classification.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
|
||||
@@ -25,13 +25,13 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Unit tests for course activities
|
||||
* Unit tests for activities completed by classification.
|
||||
*
|
||||
* @package core_analytics
|
||||
* @copyright 2017 David Monllaó {@link http://www.davidmonllao.com}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
class community_of_inquiry_activities_completed_by_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* availability_levels
|
||||
@@ -59,8 +59,6 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
// Forum1 is ignored as section 0 does not count.
|
||||
$forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
|
||||
|
||||
$courseman = new \core_analytics\course($course);
|
||||
|
||||
$modinfo = get_fast_modinfo($course, $stu1->id);
|
||||
$cm = $modinfo->get_cm($forum->cmid);
|
||||
|
||||
@@ -93,20 +91,23 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
|
||||
$cm = $modinfo->get_cm($forum->cmid);
|
||||
|
||||
$course = new \core_analytics\course($course);
|
||||
list($indicator, $method) = $this->instantiate_indicator('mod_forum', $course);
|
||||
|
||||
// Condition from after provided end time.
|
||||
$this->assertCount(0, $courseman->get_activities('forum', strtotime('2015-10-20 00:00:00 GMT'),
|
||||
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-20 00:00:00 GMT'),
|
||||
strtotime('2015-10-21 00:00:00 GMT'), $stu1));
|
||||
|
||||
// Condition until before provided start time
|
||||
$this->assertCount(0, $courseman->get_activities('forum', strtotime('2015-10-25 00:00:00 GMT'),
|
||||
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-25 00:00:00 GMT'),
|
||||
strtotime('2015-10-26 00:00:00 GMT'), $stu1));
|
||||
|
||||
// Condition until after provided end time.
|
||||
$this->assertCount(0, $courseman->get_activities('forum', strtotime('2015-10-22 00:00:00 GMT'),
|
||||
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-22 00:00:00 GMT'),
|
||||
strtotime('2015-10-23 00:00:00 GMT'), $stu1));
|
||||
|
||||
// Condition until after provided start time and before provided end time.
|
||||
$this->assertCount(1, $courseman->get_activities('forum', strtotime('2015-10-22 00:00:00 GMT'),
|
||||
$this->assertCount(1, $method->invoke($indicator, strtotime('2015-10-22 00:00:00 GMT'),
|
||||
strtotime('2015-10-25 00:00:00 GMT'), $stu1));
|
||||
}
|
||||
|
||||
@@ -138,7 +139,8 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
$forum5 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
|
||||
array('section' => 4));
|
||||
|
||||
$courseman = new \core_analytics\course($course);
|
||||
$course = new \core_analytics\course($course);
|
||||
list($indicator, $method) = $this->instantiate_indicator('mod_forum', $course);
|
||||
|
||||
$this->setUser($stu1);
|
||||
|
||||
@@ -146,10 +148,10 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
$second = $startdate + WEEKSECS;
|
||||
$third = $startdate + (WEEKSECS * 2);
|
||||
$forth = $startdate + (WEEKSECS * 3);
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $first, $first + WEEKSECS, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $second, $second + WEEKSECS, $stu1));
|
||||
$this->assertCount(0, $courseman->get_activities('forum', $third, $third + WEEKSECS, $stu1));
|
||||
$this->assertCount(2, $courseman->get_activities('forum', $forth, $forth + WEEKSECS, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $first, $first + WEEKSECS, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $second, $second + WEEKSECS, $stu1));
|
||||
$this->assertCount(0, $method->invoke($indicator, $third, $third + WEEKSECS, $stu1));
|
||||
$this->assertCount(2, $method->invoke($indicator, $forth, $forth + WEEKSECS, $stu1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +191,8 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
$forum6 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
|
||||
array('section' => 12));
|
||||
|
||||
$courseman = new \core_analytics\course($course);
|
||||
$course = new \core_analytics\course($course);
|
||||
list($indicator, $method) = $this->instantiate_indicator('mod_forum', $course);
|
||||
|
||||
$this->setUser($stu1);
|
||||
|
||||
@@ -199,10 +202,10 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
$second = $startdate + $duration;
|
||||
$third = $startdate + ($duration * 2);
|
||||
$forth = $startdate + ($duration * 3);
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $first, $first + $duration, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $second, $second + $duration, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $third, $third + $duration, $stu1));
|
||||
$this->assertCount(2, $courseman->get_activities('forum', $forth, $forth + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $first, $first + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $second, $second + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $third, $third + $duration, $stu1));
|
||||
$this->assertCount(2, $method->invoke($indicator, $forth, $forth + $duration, $stu1));
|
||||
|
||||
// Split the course in as many parts as sections.
|
||||
$duration = ($enddate - $startdate) / $numsections;
|
||||
@@ -210,15 +213,94 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
// The -1 because section 1 start represents the course start.
|
||||
$timeranges[$i] = $startdate + ($duration * ($i - 1));
|
||||
}
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[1], $timeranges[1] + $duration, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[4], $timeranges[4] + $duration, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[8], $timeranges[8] + $duration, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[10], $timeranges[10] + $duration, $stu1));
|
||||
$this->assertCount(1, $courseman->get_activities('forum', $timeranges[12], $timeranges[12] + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $timeranges[1], $timeranges[1] + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $timeranges[4], $timeranges[4] + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $timeranges[8], $timeranges[8] + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $timeranges[10], $timeranges[10] + $duration, $stu1));
|
||||
$this->assertCount(1, $method->invoke($indicator, $timeranges[12], $timeranges[12] + $duration, $stu1));
|
||||
|
||||
// Nothing here.
|
||||
$this->assertCount(0, $courseman->get_activities('forum', $timeranges[2], $timeranges[2] + $duration, $stu1));
|
||||
$this->assertCount(0, $courseman->get_activities('forum', $timeranges[3], $timeranges[3] + $duration, $stu1));
|
||||
$this->assertCount(0, $method->invoke($indicator, $timeranges[2], $timeranges[2] + $duration, $stu1));
|
||||
$this->assertCount(0, $method->invoke($indicator, $timeranges[3], $timeranges[3] + $duration, $stu1));
|
||||
}
|
||||
|
||||
/**
|
||||
* test_get_activities_with_specific_restrictions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_get_activities_with_specific_restrictions() {
|
||||
|
||||
list($course, $stu1) = $this->setup_course();
|
||||
|
||||
$end = strtotime('2015-10-24 00:00:00 GMT');
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$assign1 = $this->getDataGenerator()->create_module('assign', $params);
|
||||
$params['duedate'] = $end;
|
||||
$assign2 = $this->getDataGenerator()->create_module('assign', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$choice1 = $this->getDataGenerator()->create_module('choice', $params);
|
||||
$params['timeclose'] = $end;
|
||||
$choice1 = $this->getDataGenerator()->create_module('choice', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$data1 = $this->getDataGenerator()->create_module('data', $params);
|
||||
$params['timeavailableto'] = $end;
|
||||
$data1 = $this->getDataGenerator()->create_module('data', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$feedback1 = $this->getDataGenerator()->create_module('feedback', $params);
|
||||
$params['timeclose'] = $end;
|
||||
$feedback1 = $this->getDataGenerator()->create_module('feedback', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$lesson1 = $this->getDataGenerator()->create_module('lesson', $params);
|
||||
$params['deadline'] = $end;
|
||||
$lesson1 = $this->getDataGenerator()->create_module('lesson', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$quiz1 = $this->getDataGenerator()->create_module('quiz', $params);
|
||||
$params['timeclose'] = $end;
|
||||
$quiz1 = $this->getDataGenerator()->create_module('quiz', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$scorm1 = $this->getDataGenerator()->create_module('scorm', $params);
|
||||
$params['timeclose'] = $end;
|
||||
$scorm1 = $this->getDataGenerator()->create_module('scorm', $params);
|
||||
|
||||
// 1 with time close, one without.
|
||||
$params = array('course' => $course->id);
|
||||
$workshop1 = $this->getDataGenerator()->create_module('workshop', $params);
|
||||
$params['submissionend'] = $end;
|
||||
$workshop1 = $this->getDataGenerator()->create_module('workshop', $params);
|
||||
|
||||
$course = new \core_analytics\course($course);
|
||||
|
||||
$activitytypes = array('mod_assign', 'mod_choice', 'mod_data', 'mod_feedback', 'mod_lesson',
|
||||
'mod_quiz', 'mod_scorm', 'mod_workshop');
|
||||
foreach ($activitytypes as $activitytype) {
|
||||
|
||||
list($indicator, $method) = $this->instantiate_indicator($activitytype, $course);
|
||||
|
||||
$message = $activitytype . ' activity type returned activities do not match expected size';
|
||||
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-20 00:00:00 GMT'),
|
||||
strtotime('2015-10-21 00:00:00 GMT'), $stu1), $message);
|
||||
|
||||
$this->assertCount(0, $method->invoke($indicator, strtotime('2015-10-25 00:00:00 GMT'),
|
||||
strtotime('2015-10-26 00:00:00 GMT'), $stu1), $message);
|
||||
|
||||
$this->assertCount(1, $method->invoke($indicator, strtotime('2015-10-22 00:00:00 GMT'),
|
||||
strtotime('2015-10-25 00:00:00 GMT'), $stu1), $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,4 +325,27 @@ class core_analytics_course_activities_testcase extends advanced_testcase {
|
||||
return array($course, $stu1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the module cognitive depth indicator and the reflection method.
|
||||
*
|
||||
* @param string $modulename
|
||||
* @param \core_analytics\course $course
|
||||
* @return array
|
||||
*/
|
||||
private function instantiate_indicator($modulename, \core_analytics\course $course) {
|
||||
|
||||
$classname = '\\' . $modulename . '\analytics\indicator\cognitive_depth';
|
||||
$indicator = new $classname();
|
||||
$class = new ReflectionClass($indicator);
|
||||
|
||||
$property = $class->getProperty('course');
|
||||
$property->setAccessible(true);
|
||||
$property->setValue($indicator, $course);
|
||||
|
||||
$method = new ReflectionMethod($indicator, 'get_activities');
|
||||
$method->setAccessible(true);
|
||||
|
||||
return array($indicator, $method);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -86,7 +86,6 @@ class core_analytics_course_testcase extends advanced_testcase {
|
||||
$courseman = new \core_analytics\course($this->course->id);
|
||||
$this->assertFalse($courseman->was_started());
|
||||
$this->assertFalse($courseman->is_finished());
|
||||
$this->assertFalse($courseman->is_valid());
|
||||
|
||||
// Nothing should change when assigning as teacher.
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
@@ -94,7 +93,8 @@ class core_analytics_course_testcase extends advanced_testcase {
|
||||
$this->getDataGenerator()->enrol_user($user->id, $this->course->id, $this->teacherroleid);
|
||||
}
|
||||
$courseman = new \core_analytics\course($this->course->id);
|
||||
$this->assertFalse($courseman->is_valid());
|
||||
$this->assertFalse($courseman->was_started());
|
||||
$this->assertFalse($courseman->is_finished());
|
||||
|
||||
// More students now.
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
@@ -102,7 +102,8 @@ class core_analytics_course_testcase extends advanced_testcase {
|
||||
$this->getDataGenerator()->enrol_user($user->id, $this->course->id, $this->studentroleid);
|
||||
}
|
||||
$courseman = new \core_analytics\course($this->course->id);
|
||||
$this->assertFalse($courseman->is_valid());
|
||||
$this->assertFalse($courseman->was_started());
|
||||
$this->assertFalse($courseman->is_finished());
|
||||
|
||||
// Valid start date unknown end date.
|
||||
$this->course->startdate = gmmktime('0', '0', '0', 10, 24, 2015);
|
||||
@@ -110,7 +111,6 @@ class core_analytics_course_testcase extends advanced_testcase {
|
||||
$courseman = new \core_analytics\course($this->course->id);
|
||||
$this->assertTrue($courseman->was_started());
|
||||
$this->assertFalse($courseman->is_finished());
|
||||
$this->assertFalse($courseman->is_valid());
|
||||
|
||||
// Valid start and end date.
|
||||
$this->course->enddate = gmmktime('0', '0', '0', 8, 27, 2016);
|
||||
@@ -118,7 +118,6 @@ class core_analytics_course_testcase extends advanced_testcase {
|
||||
$courseman = new \core_analytics\course($this->course->id);
|
||||
$this->assertTrue($courseman->was_started());
|
||||
$this->assertTrue($courseman->is_finished());
|
||||
$this->assertTrue($courseman->is_valid());
|
||||
|
||||
// Valid start and ongoing course.
|
||||
$this->course->enddate = gmmktime('0', '0', '0', 8, 27, 2286);
|
||||
@@ -126,7 +125,6 @@ class core_analytics_course_testcase extends advanced_testcase {
|
||||
$courseman = new \core_analytics\course($this->course->id);
|
||||
$this->assertTrue($courseman->was_started());
|
||||
$this->assertFalse($courseman->is_finished());
|
||||
$this->assertFalse($courseman->is_valid());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once(__DIR__ . '/fixtures/test_indicator_max.php');
|
||||
require_once(__DIR__ . '/fixtures/test_indicator_min.php');
|
||||
require_once(__DIR__ . '/fixtures/test_indicator_fullname.php');
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_cas'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
$plugin->dependencies = array('auth_ldap' => 2017050500);
|
||||
$plugin->dependencies = array('auth_ldap' => 2017110800);
|
||||
|
||||
+2
-2
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_db'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die;
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_email'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -121,7 +121,7 @@ $string['didntgetusersfromldap'] = "Did not get any users from LDAP -- error? --
|
||||
$string['gotcountrecordsfromldap'] = "Got {\$a} records from LDAP\n";
|
||||
$string['ldapnotconfigured'] = 'The LDAP host url is currently not configured';
|
||||
$string['morethanoneuser'] = 'Strange! More than one user record found in ldap. Only using the first one.';
|
||||
$string['needbcmath'] = 'You need the BCMath extension to use grace logins with Active Directory';
|
||||
$string['needbcmath'] = 'You need the BCMath extension to use expired password checking with Active Directory.';
|
||||
$string['needmbstring'] = 'You need the mbstring extension to change passwords in Active Directory';
|
||||
$string['nodnforusername'] = 'Error in user_update_password(). No DN for: {$a->username}';
|
||||
$string['noemail'] = 'Tried to send you an email but failed!';
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017080100; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_ldap'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version (3.1).
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'auth_lti'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_manual'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_mnet'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_nologin'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_none'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051501; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'auth_oauth2'; // Full name of the plugin (used for diagnostics).
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_shibboleth'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'auth_webservice'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'availability_completion';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'availability_date';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'availability_grade';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'availability_group';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'availability_grouping';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500;
|
||||
$plugin->requires = 2017050500;
|
||||
$plugin->version = 2017111300;
|
||||
$plugin->requires = 2017110800;
|
||||
$plugin->component = 'availability_profile';
|
||||
|
||||
@@ -136,7 +136,7 @@ abstract class backup implements checksumable {
|
||||
* point is backup when some behavior/approach channged, in order to allow
|
||||
* conditional coding based on it.
|
||||
*/
|
||||
const VERSION = 2017051500;
|
||||
const VERSION = 2017111300;
|
||||
/**
|
||||
* Usually same than major release zero version, mainly for informative/historic purposes.
|
||||
*/
|
||||
|
||||
@@ -112,7 +112,7 @@ class cc_forum extends entities {
|
||||
|
||||
public function get_topic_data ($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class cc_quiz extends entities {
|
||||
$last_question_id = 0;
|
||||
$last_answer_id = 0;
|
||||
|
||||
$instances = '';
|
||||
$instances = array();
|
||||
|
||||
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class cc11_basiclti extends entities11 {
|
||||
|
||||
public function get_basiclti_data($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$basiclti_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ class cc11_forum extends entities11 {
|
||||
|
||||
public function get_topic_data ($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$topic_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class cc11_lti extends entities11 {
|
||||
|
||||
public function get_basiclti_data($instance) {
|
||||
|
||||
$topic_data = '';
|
||||
$topic_data = array();
|
||||
|
||||
$basiclti_file = $this->get_external_xml($instance['resource_indentifier']);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class cc11_quiz extends entities11 {
|
||||
$last_question_id = 0;
|
||||
$last_answer_id = 0;
|
||||
|
||||
$instances = '';
|
||||
$instances = array();
|
||||
|
||||
$types = array(MOODLE_TYPE_QUIZ, MOODLE_TYPE_QUESTION_BANK);
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_activity_modules'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'block_activity_results'; // Full name of the plugin (used for diagnostics).
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_admin_bookmarks'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version.
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version.
|
||||
$plugin->component = 'block_badges';
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_blog_menu'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_blog_recent'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_blog_tags'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -49,41 +49,14 @@ class block_calendar_month extends block_base {
|
||||
$this->content->footer = '';
|
||||
|
||||
$courseid = $this->page->course->id;
|
||||
$issite = ($courseid == SITEID);
|
||||
|
||||
$course = null;
|
||||
$courses = null;
|
||||
$categories = null;
|
||||
|
||||
if ($issite) {
|
||||
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
|
||||
// the list of courses it will be grabbing events from.
|
||||
$course = get_site();
|
||||
$courses = calendar_get_default_courses();
|
||||
|
||||
if ($this->page->context->contextlevel === CONTEXT_COURSECAT) {
|
||||
// Restrict to categories, and their parents, and the courses that the user is enrolled in within those
|
||||
// categories.
|
||||
$categories = array_keys($this->page->categories);
|
||||
$courses = array_filter($courses, function($course) use ($categories) {
|
||||
return array_search($course->category, $categories) !== false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Forcibly filter events to include only those from the particular course we are in.
|
||||
$course = $this->page->course;
|
||||
$courses = [$course->id => $course];
|
||||
}
|
||||
$categoryid = ($this->page->context->contextlevel === CONTEXT_COURSECAT) ? $this->page->category->id : null;
|
||||
$calendar = \calendar_information::create(time(), $courseid, $categoryid);
|
||||
list($data, $template) = calendar_get_view($calendar, 'mini', isloggedin());
|
||||
|
||||
$renderer = $this->page->get_renderer('core_calendar');
|
||||
|
||||
$calendar = new calendar_information();
|
||||
$calendar->set_sources($course, $courses, $this->page->category);
|
||||
|
||||
list($data, $template) = calendar_get_view($calendar, 'mini');
|
||||
$this->content->text .= $renderer->render_from_template($template, $data);
|
||||
|
||||
if (!$issite) {
|
||||
if ($this->page->course->id != SITEID) {
|
||||
$this->content->text .= $renderer->event_filter();
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_calendar_month'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
@@ -45,38 +45,83 @@ class block_calendar_upcoming extends block_base {
|
||||
}
|
||||
$this->content = new stdClass;
|
||||
$this->content->text = '';
|
||||
$this->content->footer = '';
|
||||
|
||||
$renderer = $this->page->get_renderer('core_calendar');
|
||||
$courseid = $this->page->course->id;
|
||||
$issite = ($courseid == SITEID);
|
||||
|
||||
if ($issite) {
|
||||
// Being displayed at site level. This will cause the filter to fall back to auto-detecting
|
||||
// the list of courses it will be grabbing events from.
|
||||
$course = get_site();
|
||||
$courses = calendar_get_default_courses();
|
||||
} else {
|
||||
// Forcibly filter events to include only those from the particular course we are in.
|
||||
$course = $this->page->course;
|
||||
$courses = [$course->id => $course];
|
||||
}
|
||||
$calendar = new calendar_information(0, 0, 0, time());
|
||||
$calendar->set_sources($course, $courses);
|
||||
|
||||
$categoryid = ($this->page->context->contextlevel === CONTEXT_COURSECAT) ? $this->page->category->id : null;
|
||||
$calendar = \calendar_information::create(time(), $courseid, $categoryid);
|
||||
list($data, $template) = calendar_get_view($calendar, 'upcoming_mini');
|
||||
|
||||
if (empty($data->events)) {
|
||||
$this->content->text = '<div class="post">'. get_string('noupcomingevents', 'calendar').'</div>';
|
||||
} else {
|
||||
$this->content->text .= $renderer->render_from_template($template, $data);
|
||||
$renderer = $this->page->get_renderer('core_calendar');
|
||||
$this->content->text .= $renderer->render_from_template($template, $data);
|
||||
|
||||
$url = new \moodle_url('/calendar/view.php', ['view' => 'upcoming']);
|
||||
if ($courseid != SITEID) {
|
||||
$url->param('course', $this->page->course->id);
|
||||
} else if (!empty($categoryid)) {
|
||||
$url->param('category', $this->page->category->id);
|
||||
}
|
||||
|
||||
$this->content->footer = '<div class="gotocal">
|
||||
<a href="'.$CFG->wwwroot.'/calendar/view.php?view=upcoming&course='.$courseid.'">'.
|
||||
get_string('gotocalendar', 'calendar').'</a>...</div>';
|
||||
$this->content->footer = html_writer::div(
|
||||
html_writer::link($url, get_string('gotocalendar', 'block_calendar_upcoming')),
|
||||
'gotocal'
|
||||
);
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the upcoming event block content.
|
||||
*
|
||||
* @param array $events list of events
|
||||
* @param \moodle_url|string $linkhref link to event referer
|
||||
* @param boolean $showcourselink whether links to courses should be shown
|
||||
* @return string|null $content html block content
|
||||
* @deprecated since 3.4
|
||||
*/
|
||||
public static function get_upcoming_content($events, $linkhref = null, $showcourselink = false) {
|
||||
debugging(
|
||||
'get_upcoming_content() is deprecated. ' .
|
||||
'Please see block_calendar_upcoming::get_content() for the correct API usage.',
|
||||
DEBUG_DEVELOPER
|
||||
);
|
||||
|
||||
$content = '';
|
||||
$lines = count($events);
|
||||
|
||||
if (!$lines) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $lines; ++$i) {
|
||||
if (!isset($events[$i]->time)) {
|
||||
continue;
|
||||
}
|
||||
$events[$i] = calendar_add_event_metadata($events[$i]);
|
||||
$content .= '<div class="event"><span class="icon c0">' . $events[$i]->icon . '</span>';
|
||||
if (!empty($events[$i]->referer)) {
|
||||
// That's an activity event, so let's provide the hyperlink.
|
||||
$content .= $events[$i]->referer;
|
||||
} else {
|
||||
if (!empty($linkhref)) {
|
||||
$href = calendar_get_link_href(new \moodle_url(CALENDAR_URL . $linkhref), 0, 0, 0,
|
||||
$events[$i]->timestart);
|
||||
$href->set_anchor('event_' . $events[$i]->id);
|
||||
$content .= \html_writer::link($href, $events[$i]->name);
|
||||
} else {
|
||||
$content .= $events[$i]->name;
|
||||
}
|
||||
}
|
||||
$events[$i]->time = str_replace('»', '<br />»', $events[$i]->time);
|
||||
if ($showcourselink && !empty($events[$i]->courselink)) {
|
||||
$content .= \html_writer::div($events[$i]->courselink, 'course');
|
||||
}
|
||||
$content .= '<div class="date">' . $events[$i]->time . '</div></div>';
|
||||
if ($i < $lines - 1) {
|
||||
$content .= '<hr />';
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,4 +24,5 @@
|
||||
|
||||
$string['calendar_upcoming:addinstance'] = 'Add a new upcoming events block';
|
||||
$string['calendar_upcoming:myaddinstance'] = 'Add a new upcoming events block to Dashboard';
|
||||
$string['gotocalendar'] = 'Go to calendar...';
|
||||
$string['pluginname'] = 'Upcoming events';
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
=== 3.4 ===
|
||||
|
||||
* block_calendar_upcoming::get_upcoming_content has been deprecated. Please
|
||||
update your code to use the new APIs. You can see an example of how these
|
||||
may be used in block_calendar_upcoming::get_content().
|
||||
@@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2017051500; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017050500; // Requires this Moodle version
|
||||
$plugin->version = 2017111300; // The current plugin version (Date: YYYYMMDDXX)
|
||||
$plugin->requires = 2017110800; // Requires this Moodle version
|
||||
$plugin->component = 'block_calendar_upcoming'; // Full name of the plugin (used for diagnostics)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user