diff --git a/admin/auth.php b/admin/auth.php
index 93711ee8324..934acd371ef 100644
--- a/admin/auth.php
+++ b/admin/auth.php
@@ -12,13 +12,13 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
$returnurl = new moodle_url('/admin/settings.php', array('section'=>'manageauths'));
$PAGE->set_url($returnurl);
-$action = optional_param('action', '', PARAM_ACTION);
+$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$auth = optional_param('auth', '', PARAM_PLUGIN);
get_enabled_auth_plugins(true); // fix the list of enabled auths
diff --git a/admin/category.php b/admin/category.php
index f9cd940e9ff..1d68207221c 100644
--- a/admin/category.php
+++ b/admin/category.php
@@ -32,7 +32,7 @@ $adminediting = optional_param('adminedit', -1, PARAM_BOOL);
/// no guest autologin
require_login(0, false);
-$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+$PAGE->set_context(context_system::instance());
$PAGE->set_url('/admin/category.php', array('category' => $category));
$PAGE->set_pagetype('admin-setting-' . $category);
$PAGE->set_pagelayout('admin');
diff --git a/admin/editors.php b/admin/editors.php
index fbb7be5aac4..1a8f530854a 100644
--- a/admin/editors.php
+++ b/admin/editors.php
@@ -9,11 +9,11 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/tablelib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=manageeditors";
-$action = optional_param('action', '', PARAM_ACTION);
+$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$editor = optional_param('editor', '', PARAM_PLUGIN);
// get currently installed and enabled auth plugins
diff --git a/admin/enrol.php b/admin/enrol.php
index ab14a23440a..9fc196f54c0 100644
--- a/admin/enrol.php
+++ b/admin/enrol.php
@@ -26,7 +26,7 @@
require_once('../config.php');
require_once($CFG->libdir.'/adminlib.php');
-$action = required_param('action', PARAM_ACTION);
+$action = required_param('action', PARAM_ALPHANUMEXT);
$enrol = required_param('enrol', PARAM_PLUGIN);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
@@ -34,7 +34,7 @@ $PAGE->set_url('/admin/enrol.php');
$PAGE->set_context(context_system::instance());
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
require_sesskey();
$enabled = enrol_get_plugins(true);
diff --git a/admin/environment.php b/admin/environment.php
index 1fc732ea064..5c74f7f6365 100644
--- a/admin/environment.php
+++ b/admin/environment.php
@@ -33,7 +33,7 @@ require_once($CFG->libdir.'/environmentlib.php');
require_once($CFG->libdir.'/componentlib.class.php');
// Parameters
-$action = optional_param('action', '', PARAM_ACTION);
+$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$version = optional_param('version', '', PARAM_FILE); //
$extraurlparams = array();
diff --git a/admin/filters.php b/admin/filters.php
index 0d7faa3c088..5c65c74085c 100644
--- a/admin/filters.php
+++ b/admin/filters.php
@@ -34,11 +34,11 @@
require_once(dirname(__FILE__) . '/../config.php');
require_once($CFG->libdir . '/adminlib.php');
- $action = optional_param('action', '', PARAM_ACTION);
+ $action = optional_param('action', '', PARAM_ALPHANUMEXT);
$filterpath = optional_param('filterpath', '', PARAM_PATH);
require_login();
- $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+ $systemcontext = context_system::instance();
require_capability('moodle/site:config', $systemcontext);
$returnurl = "$CFG->wwwroot/$CFG->admin/filters.php";
@@ -68,7 +68,7 @@
switch ($action) {
case 'setstate':
- if ($newstate = optional_param('newstate', '', PARAM_INTEGER)) {
+ if ($newstate = optional_param('newstate', '', PARAM_INT)) {
filter_set_global_state($filterpath, $newstate);
if ($newstate == TEXTFILTER_DISABLED) {
filter_set_applies_to_strings($filterpath, false);
diff --git a/admin/handlevirus.php b/admin/handlevirus.php
index 9e32cc0b653..d7cf3cd9900 100644
--- a/admin/handlevirus.php
+++ b/admin/handlevirus.php
@@ -49,7 +49,7 @@ while(!feof($fd)) {
$a->date = userdate($log->time);
$a->action = $action;
- $a->course = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id)));
+ $a->course = format_string($course->fullname, true, array('context' => context_course::instance($course->id)));
$a->user = fullname($user);
notify_user($user,$subject,$a);
diff --git a/admin/index.php b/admin/index.php
index d4a7d4e285b..410cbf6723b 100644
--- a/admin/index.php
+++ b/admin/index.php
@@ -104,10 +104,6 @@ if (!$version or !$release) {
print_error('withoutversion', 'debug'); // without version, stop
}
-// Turn off xmlstrictheaders during upgrade.
-$origxmlstrictheaders = !empty($CFG->xmlstrictheaders);
-$CFG->xmlstrictheaders = false;
-
if (!core_tables_exist()) {
$PAGE->set_pagelayout('maintenance');
$PAGE->set_popup_notification_allowed(false);
@@ -189,7 +185,7 @@ if (!core_tables_exist()) {
// and upgrade if possible.
$stradministration = get_string('administration');
-$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+$PAGE->set_context(context_system::instance());
if (empty($CFG->version)) {
print_error('missingconfigversion', 'debug');
@@ -380,13 +376,9 @@ if (during_initial_install()) {
upgrade_finished('upgradesettings.php');
}
-// Turn xmlstrictheaders back on now.
-$CFG->xmlstrictheaders = $origxmlstrictheaders;
-unset($origxmlstrictheaders);
-
// Check for valid admin user - no guest autologin
require_login(0, false);
-$context = get_context_instance(CONTEXT_SYSTEM);
+$context = context_system::instance();
require_capability('moodle/site:config', $context);
// check that site is properly customized
diff --git a/admin/licenses.php b/admin/licenses.php
index dfd843d009d..47d3929201c 100644
--- a/admin/licenses.php
+++ b/admin/licenses.php
@@ -24,11 +24,11 @@ require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/licenselib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
$returnurl = "$CFG->wwwroot/$CFG->admin/settings.php?section=managelicenses";
-$action = optional_param('action', '', PARAM_ACTION);
+$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$license = optional_param('license', '', PARAM_SAFEDIR);
////////////////////////////////////////////////////////////////////////////////
diff --git a/admin/message.php b/admin/message.php
index 45d9026c14e..88e8f856617 100644
--- a/admin/message.php
+++ b/admin/message.php
@@ -29,7 +29,7 @@ require_once($CFG->libdir.'/adminlib.php');
admin_externalpage_setup('managemessageoutputs');
// Require site configuration capability
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
// Get the submitted params
$disable = optional_param('disable', 0, PARAM_INT);
@@ -82,7 +82,7 @@ if ($disable || $enable || $uninstall) {
redirect($url);
}
// Page settings
-$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+$PAGE->set_context(context_system::instance());
// Grab the renderer
$renderer = $PAGE->get_renderer('core', 'message');
diff --git a/admin/mnet/access_control.php b/admin/mnet/access_control.php
index b9e436f7cc4..0354f150ac6 100644
--- a/admin/mnet/access_control.php
+++ b/admin/mnet/access_control.php
@@ -22,7 +22,7 @@ if (!extension_loaded('openssl')) {
print_error('requiresopenssl', 'mnet');
}
-$sitecontext = get_context_instance(CONTEXT_SYSTEM);
+$sitecontext = context_system::instance();
$sesskey = sesskey();
$formerror = array();
diff --git a/admin/mnet/delete.php b/admin/mnet/delete.php
index e3a7e3f07fb..c078b274c30 100644
--- a/admin/mnet/delete.php
+++ b/admin/mnet/delete.php
@@ -36,7 +36,7 @@ $hostid = required_param('hostid', PARAM_INT);
require_login();
-$context = get_context_instance(CONTEXT_SYSTEM);
+$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
$mnet = get_mnet_environment();
diff --git a/admin/mnet/index.php b/admin/mnet/index.php
index 54a0a276a5a..d81e8a92ad6 100644
--- a/admin/mnet/index.php
+++ b/admin/mnet/index.php
@@ -9,7 +9,7 @@
require_login();
admin_externalpage_setup('net');
- $context = get_context_instance(CONTEXT_SYSTEM);
+ $context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
diff --git a/admin/mnet/peers.php b/admin/mnet/peers.php
index e7c1daf821b..40759dbc0ed 100644
--- a/admin/mnet/peers.php
+++ b/admin/mnet/peers.php
@@ -34,7 +34,7 @@ require_once($CFG->dirroot.'/'.$CFG->admin.'/mnet/peer_forms.php');
require_login();
-$context = get_context_instance(CONTEXT_SYSTEM);
+$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, 'nopermissions');
/// Initialize variables.
diff --git a/admin/mnet/profilefields.php b/admin/mnet/profilefields.php
index 23443e90636..5f5fd6b1ec0 100644
--- a/admin/mnet/profilefields.php
+++ b/admin/mnet/profilefields.php
@@ -34,7 +34,7 @@ $hostid = required_param('hostid', PARAM_INT);
$mnet_peer = new mnet_peer();
$mnet_peer->set_id($hostid);
-$context = get_context_instance(CONTEXT_SYSTEM);
+$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, 'nopermissions');
admin_externalpage_setup('mnetpeers');
diff --git a/admin/mnet/services.php b/admin/mnet/services.php
index d496f47a6e6..cdc4fe3a5c2 100644
--- a/admin/mnet/services.php
+++ b/admin/mnet/services.php
@@ -33,7 +33,7 @@ $mnet = get_mnet_environment();
require_login();
admin_externalpage_setup('mnetpeers');
-$context = get_context_instance(CONTEXT_SYSTEM);
+$context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
$hostid = required_param('hostid', PARAM_INT);
diff --git a/admin/mnet/testclient.php b/admin/mnet/testclient.php
index f4d2c96053a..89734e39b14 100644
--- a/admin/mnet/testclient.php
+++ b/admin/mnet/testclient.php
@@ -24,7 +24,7 @@ if ($CFG->mnet_dispatcher_mode === 'off') {
require_login();
admin_externalpage_setup('mnettestclient');
-$context = get_context_instance(CONTEXT_SYSTEM);
+$context = context_system::instance();
require_capability('moodle/site:config', $context);
error_reporting(DEBUG_ALL);
diff --git a/admin/mnet/trustedhosts.php b/admin/mnet/trustedhosts.php
index 8f0bef15fdf..290c0ae9212 100644
--- a/admin/mnet/trustedhosts.php
+++ b/admin/mnet/trustedhosts.php
@@ -8,7 +8,7 @@
require_login();
admin_externalpage_setup('trustedhosts');
- $context = get_context_instance(CONTEXT_SYSTEM);
+ $context = context_system::instance();
require_capability('moodle/site:config', $context, $USER->id, true, "nopermissions");
diff --git a/admin/oacleanup.php b/admin/oacleanup.php
index 891a20af947..fe2e444472b 100644
--- a/admin/oacleanup.php
+++ b/admin/oacleanup.php
@@ -49,7 +49,7 @@ function online_assignment_cleanup($output=false) {
/// cycle through each course
foreach ($courses as $course) {
context_instance_preload($course);
- $context = get_context_instance(CONTEXT_COURSE, $course->id);
+ $context = context_course::instance($course->id);
if (empty($course->fullname)) {
$fullname = get_string('course').': '.$course->id;
diff --git a/admin/plugins.php b/admin/plugins.php
index 943f23a5ea8..8da3fd7a5fe 100644
--- a/admin/plugins.php
+++ b/admin/plugins.php
@@ -28,7 +28,7 @@ require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->libdir . '/pluginlib.php');
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
admin_externalpage_setup('pluginsoverview');
$fetchremote = optional_param('fetchremote', false, PARAM_BOOL);
diff --git a/admin/portfolio.php b/admin/portfolio.php
index 791c79f9489..77aa8ea13a7 100644
--- a/admin/portfolio.php
+++ b/admin/portfolio.php
@@ -5,7 +5,7 @@ require_once($CFG->libdir . '/portfoliolib.php');
require_once($CFG->libdir . '/portfolio/forms.php');
require_once($CFG->libdir . '/adminlib.php');
-$portfolio = optional_param('pf', '', PARAM_FORMAT);
+$portfolio = optional_param('pf', '', PARAM_ALPHANUMEXT);
$action = optional_param('action', '', PARAM_ALPHA);
$sure = optional_param('sure', '', PARAM_ALPHA);
@@ -35,7 +35,7 @@ if ($action == 'newon') {
admin_externalpage_setup($pagename);
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
$baseurl = "$CFG->wwwroot/$CFG->admin/portfolio.php";
$sesskeyurl = "$CFG->wwwroot/$CFG->admin/portfolio.php?sesskey=" . sesskey();
diff --git a/admin/purgecaches.php b/admin/purgecaches.php
index f437e8ac8a7..006bb0d9768 100644
--- a/admin/purgecaches.php
+++ b/admin/purgecaches.php
@@ -31,7 +31,7 @@ $confirm = optional_param('confirm', 0, PARAM_BOOL);
admin_externalpage_setup('purgecaches');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
if ($confirm) {
require_sesskey();
diff --git a/admin/qbehaviours.php b/admin/qbehaviours.php
index ce81b1369d2..1e72afad1aa 100644
--- a/admin/qbehaviours.php
+++ b/admin/qbehaviours.php
@@ -33,7 +33,7 @@ require_once($CFG->libdir . '/tablelib.php');
// Check permissions.
require_login();
-$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$systemcontext = context_system::instance();
require_capability('moodle/question:config', $systemcontext);
admin_externalpage_setup('manageqbehaviours');
diff --git a/admin/qtypes.php b/admin/qtypes.php
index cbe828fdf10..a37725cd837 100644
--- a/admin/qtypes.php
+++ b/admin/qtypes.php
@@ -33,7 +33,7 @@ require_once($CFG->libdir . '/tablelib.php');
// Check permissions.
require_login();
-$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$systemcontext = context_system::instance();
require_capability('moodle/question:config', $systemcontext);
$canviewreports = has_capability('report/questioninstances:view', $systemcontext);
diff --git a/admin/registration/forms.php b/admin/registration/forms.php
index 0126722d9f9..47a450f6126 100644
--- a/admin/registration/forms.php
+++ b/admin/registration/forms.php
@@ -203,7 +203,7 @@ class site_registration_form extends moodleform {
$cleanhuburl = clean_param($huburl, PARAM_ALPHANUMEXT);
$sitename = get_config('hub', 'site_name_' . $cleanhuburl);
if ($sitename === false) {
- $sitename = format_string($site->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, SITEID)));
+ $sitename = format_string($site->fullname, true, array('context' => context_course::instance(SITEID)));
}
$sitedescription = get_config('hub', 'site_description_' . $cleanhuburl);
if ($sitedescription === false) {
diff --git a/admin/repository.php b/admin/repository.php
index b3494cab5a5..0adfdc6e8e2 100644
--- a/admin/repository.php
+++ b/admin/repository.php
@@ -19,7 +19,7 @@ require_once($CFG->dirroot . '/repository/lib.php');
require_once($CFG->libdir . '/adminlib.php');
$repository = optional_param('repos', '', PARAM_ALPHANUMEXT);
-$action = optional_param('action', '', PARAM_ACTION);
+$action = optional_param('action', '', PARAM_ALPHANUMEXT);
$sure = optional_param('sure', '', PARAM_ALPHA);
$downloadcontents = optional_param('downloadcontents', false, PARAM_BOOL);
@@ -47,7 +47,7 @@ if ($action == 'newon') {
$visible = false;
}
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
admin_externalpage_setup($pagename);
$sesskeyurl = $CFG->wwwroot.'/'.$CFG->admin.'/repository.php?sesskey=' . sesskey();
diff --git a/admin/roles/allow.php b/admin/roles/allow.php
index 52078e7f181..37ac157b5eb 100644
--- a/admin/roles/allow.php
+++ b/admin/roles/allow.php
@@ -28,7 +28,7 @@ require_once(dirname(__FILE__) . '/../../config.php');
require_once($CFG->libdir . '/adminlib.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
-$mode = required_param('mode', PARAM_ACTION);
+$mode = required_param('mode', PARAM_ALPHANUMEXT);
$classformode = array(
'assign' => 'role_allow_assign_page',
'override' => 'role_allow_override_page',
@@ -41,7 +41,7 @@ if (!isset($classformode[$mode])) {
$baseurl = new moodle_url('/admin/roles/allow.php', array('mode'=>$mode));
admin_externalpage_setup('defineroles', '', array(), $baseurl);
-$syscontext = get_context_instance(CONTEXT_SYSTEM);
+$syscontext = context_system::instance();
require_capability('moodle/role:manage', $syscontext);
$controller = new $classformode[$mode]();
diff --git a/admin/roles/define.php b/admin/roles/define.php
index d2f4eb5f501..d889a1065f0 100644
--- a/admin/roles/define.php
+++ b/admin/roles/define.php
@@ -38,7 +38,7 @@
throw new moodle_exception('invalidaccess');
}
if ($action != 'add') {
- $roleid = required_param('roleid', PARAM_INTEGER);
+ $roleid = required_param('roleid', PARAM_INT);
} else {
$roleid = 0;
}
@@ -56,7 +56,7 @@
}
/// Check access permissions.
- $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+ $systemcontext = context_system::instance();
require_login();
require_capability('moodle/role:manage', $systemcontext);
admin_externalpage_setup('defineroles', '', array('action' => $action, 'roleid' => $roleid), $defineurl);
diff --git a/admin/roles/lib.php b/admin/roles/lib.php
index 212cd211c6f..11341d10cfe 100644
--- a/admin/roles/lib.php
+++ b/admin/roles/lib.php
@@ -604,7 +604,7 @@ class define_role_table_advanced extends capability_table_with_risks {
}
// Role name.
- $name = optional_param('name', null, PARAM_MULTILANG);
+ $name = optional_param('name', null, PARAM_TEXT);
if (!is_null($name)) {
$this->role->name = $name;
// Hack: short names of standard roles are equal to archetypes, empty name means localised via lang packs.
@@ -1270,7 +1270,7 @@ abstract class role_allow_role_page {
*/
protected function load_required_roles() {
/// Get all roles
- $this->roles = role_fix_names(get_all_roles(), get_context_instance(CONTEXT_SYSTEM), ROLENAME_ORIGINAL);
+ $this->roles = role_fix_names(get_all_roles(), context_system::instance(), ROLENAME_ORIGINAL);
}
/**
diff --git a/admin/roles/manage.php b/admin/roles/manage.php
index 85b1c0b240b..745681ee268 100644
--- a/admin/roles/manage.php
+++ b/admin/roles/manage.php
@@ -47,7 +47,7 @@
$defineurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/define.php';
/// Check access permissions.
- $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+ $systemcontext = context_system::instance();
require_login();
require_capability('moodle/role:manage', $systemcontext);
admin_externalpage_setup('defineroles');
diff --git a/admin/roles/usersroles.php b/admin/roles/usersroles.php
index 11b2c28caf9..d9d8cb5e8f7 100644
--- a/admin/roles/usersroles.php
+++ b/admin/roles/usersroles.php
@@ -36,9 +36,9 @@ $courseid = required_param('courseid', PARAM_INT);
$user = $DB->get_record('user', array('id' => $userid), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
-$usercontext = get_context_instance(CONTEXT_USER, $user->id);
-$coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
-$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$usercontext = context_user::instance($user->id);
+$coursecontext = context_course::instance($course->id);
+$systemcontext = context_system::instance();
$baseurl = new moodle_url('/admin/roles/usersroles.php', array('userid'=>$userid, 'courseid'=>$courseid));
diff --git a/admin/search.php b/admin/search.php
index 40fbeb4b56d..d60f09374d1 100644
--- a/admin/search.php
+++ b/admin/search.php
@@ -7,7 +7,7 @@ require_once($CFG->libdir.'/adminlib.php');
$query = trim(optional_param('query', '', PARAM_NOTAGS)); // Search string
-$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+$PAGE->set_context(context_system::instance());
admin_externalpage_setup('search', '', array('query' => $query)); // now hidden page
diff --git a/admin/settings.php b/admin/settings.php
index 3e66f24d48e..c8444c51bf1 100644
--- a/admin/settings.php
+++ b/admin/settings.php
@@ -9,7 +9,7 @@ $adminediting = optional_param('adminedit', -1, PARAM_BOOL);
/// no guest autologin
require_login(0, false);
-$PAGE->set_context(get_context_instance(CONTEXT_SYSTEM));
+$PAGE->set_context(context_system::instance());
$PAGE->set_url('/admin/settings.php', array('section' => $section));
$PAGE->set_pagetype('admin-setting-' . $section);
$PAGE->set_pagelayout('admin');
diff --git a/admin/settings/appearance.php b/admin/settings/appearance.php
index b0272b8c97e..9995af38048 100644
--- a/admin/settings/appearance.php
+++ b/admin/settings/appearance.php
@@ -185,6 +185,7 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
$setting = new admin_setting_configcheckbox('cachejs', new lang_string('cachejs', 'admin'), new lang_string('cachejs_help', 'admin'), 1);
$setting->set_updatedcallback('js_reset_all_caches');
$temp->add($setting);
+ $temp->add(new admin_setting_configcheckbox('modchooserdefault', new lang_string('modchooserdefault', 'admin'), new lang_string('configmodchooserdefault', 'admin'), 1));
$ADMIN->add('appearance', $temp);
// link to tag management interface
diff --git a/admin/settings/development.php b/admin/settings/development.php
index cb77515a84c..4d9cd84ab52 100644
--- a/admin/settings/development.php
+++ b/admin/settings/development.php
@@ -25,7 +25,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
$temp = new admin_settingpage('debugging', new lang_string('debugging', 'admin'));
$temp->add(new admin_setting_special_debug());
$temp->add(new admin_setting_configcheckbox('debugdisplay', new lang_string('debugdisplay', 'admin'), new lang_string('configdebugdisplay', 'admin'), ini_get_bool('display_errors')));
- $temp->add(new admin_setting_configcheckbox('xmlstrictheaders', new lang_string('xmlstrictheaders', 'admin'), new lang_string('configxmlstrictheaders', 'admin'), 0));
$temp->add(new admin_setting_configcheckbox('debugsmtp', new lang_string('debugsmtp', 'admin'), new lang_string('configdebugsmtp', 'admin'), 0));
$temp->add(new admin_setting_configcheckbox('perfdebug', new lang_string('perfdebug', 'admin'), new lang_string('configperfdebug', 'admin'), '7', '15', '7'));
$temp->add(new admin_setting_configcheckbox('debugstringids', new lang_string('debugstringids', 'admin'), new lang_string('debugstringids_desc', 'admin'), 0));
diff --git a/admin/settings/frontpage.php b/admin/settings/frontpage.php
index fd5fafa6f32..5a060a101bb 100644
--- a/admin/settings/frontpage.php
+++ b/admin/settings/frontpage.php
@@ -3,7 +3,7 @@
// This file defines everything related to frontpage
if (!during_initial_install()) { //do not use during installation
- $frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID);
+ $frontpagecontext = context_course::instance(SITEID);
if ($hassiteconfig or has_any_capability(array(
'moodle/course:update',
diff --git a/admin/settings/plugins.php b/admin/settings/plugins.php
index 638aa4009b7..ec274335398 100644
--- a/admin/settings/plugins.php
+++ b/admin/settings/plugins.php
@@ -264,13 +264,13 @@ if ($hassiteconfig) {
'portfolio_moderate_db_threshold',
new lang_string('moderatedbsizethreshold', 'portfolio'),
new lang_string('moderatedbsizethresholddesc', 'portfolio'),
- 20, PARAM_INTEGER, 3));
+ 20, PARAM_INT, 3));
$temp->add(new admin_setting_configtext(
'portfolio_high_db_threshold',
new lang_string('highdbsizethreshold', 'portfolio'),
new lang_string('highdbsizethresholddesc', 'portfolio'),
- 50, PARAM_INTEGER, 3));
+ 50, PARAM_INT, 3));
$ADMIN->add('portfoliosettings', $temp);
$ADMIN->add('portfoliosettings', new admin_externalpage('portfolionew', new lang_string('addnewportfolio', 'portfolio'), $url, 'moodle/site:config', true), '', $url);
diff --git a/admin/settings/top.php b/admin/settings/top.php
index 147a4e56edd..cd52953d029 100644
--- a/admin/settings/top.php
+++ b/admin/settings/top.php
@@ -5,7 +5,7 @@
// since they need to exist *before* settingpages and externalpages
// are added to them.
-$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$systemcontext = context_system::instance();
$hassiteconfig = has_capability('moodle/site:config', $systemcontext);
$ADMIN->add('root', new admin_externalpage('adminnotifications', new lang_string('notifications'), "$CFG->wwwroot/$CFG->admin/index.php"));
diff --git a/admin/settings/users.php b/admin/settings/users.php
index fa5968c5474..b7f1e257947 100644
--- a/admin/settings/users.php
+++ b/admin/settings/users.php
@@ -34,7 +34,7 @@ if ($hassiteconfig
$temp = new admin_settingpage('userpolicies', new lang_string('userpolicies', 'admin'));
if ($ADMIN->fulltree) {
if (!during_initial_install()) {
- $context = get_context_instance(CONTEXT_SYSTEM);
+ $context = context_system::instance();
$otherroles = array();
$guestroles = array();
diff --git a/admin/timezone.php b/admin/timezone.php
index e031be44bbe..8cfefc7b7a4 100644
--- a/admin/timezone.php
+++ b/admin/timezone.php
@@ -14,7 +14,7 @@
require_login();
- require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+ require_capability('moodle/site:config', context_system::instance());
$strtimezone = get_string("timezone");
$strsavechanges = get_string("savechanges");
diff --git a/admin/tool/bloglevelupgrade/index.php b/admin/tool/bloglevelupgrade/index.php
index bd2a5310b37..823f2109194 100644
--- a/admin/tool/bloglevelupgrade/index.php
+++ b/admin/tool/bloglevelupgrade/index.php
@@ -102,8 +102,8 @@ if ($CFG->bloglevel == BLOG_COURSE_LEVEL || $CFG->bloglevel == BLOG_GROUP_LEVEL)
function bloglevelupgrade_entries($blogentries, $forum, $cm, $groupid=-1) {
$count = 0;
- $forumcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
- $sitecontext = get_context_instance(CONTEXT_SYSTEM);
+ $forumcontext = context_module::instance($cm->id);
+ $sitecontext = context_system::instance();
foreach ($blogentries as $blogentry) {
$discussion = new stdClass();
diff --git a/admin/tool/capability/index.php b/admin/tool/capability/index.php
index 7a0f2d64a6e..3f9c58edd0c 100644
--- a/admin/tool/capability/index.php
+++ b/admin/tool/capability/index.php
@@ -29,12 +29,12 @@ require_once($CFG->libdir.'/adminlib.php');
// Check permissions.
require_login();
-$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$systemcontext = context_system::instance();
require_capability('moodle/role:manage', $systemcontext);
// Get URL parameters.
$capability = optional_param('capability', '', PARAM_CAPABILITY);
-$roleids = optional_param_array('roles', array('0'), PARAM_INTEGER);
+$roleids = optional_param_array('roles', array('0'), PARAM_INT);
// Clean the passed in list of role ids. If 'All' selected as an option, or
// if none were selected, do all roles.
diff --git a/admin/tool/dbtransfer/cli/migrate.php b/admin/tool/dbtransfer/cli/migrate.php
new file mode 100644
index 00000000000..0d32e2ae8a5
--- /dev/null
+++ b/admin/tool/dbtransfer/cli/migrate.php
@@ -0,0 +1,191 @@
+.
+
+/**
+ * This script migrates data from current database to another
+ *
+ * This script is not intended for beginners!
+ * Potential problems:
+ * - su to apache account or sudo before execution
+ * - already broken DB scheme or invalid data
+ *
+ * @package tool_dbtransfer
+ * @copyright 2012 Petr Skoda {@link http://skodak.org/}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define('CLI_SCRIPT', true);
+
+require(__DIR__.'/../../../../config.php');
+require_once($CFG->libdir.'/clilib.php');
+require_once(__DIR__.'/../locallib.php');
+
+$help =
+ "Database migration script.
+
+It is strongly recommended to turn off the web server
+or enable CLI maintenance mode before starting the migration.
+
+Options:
+--dbtype=TYPE Database type.
+--dblibrary=TYPE Database library. Defaults to 'native'.
+--dbhost=HOST Database host.
+--dbname=NAME Database name.
+--dbuser=USERNAME Database user.
+--dbpass=PASSWORD Database password.
+--dbport=NUMBER Database port.
+--prefix=STRING Table prefix for above database tables.
+--dbsocket=PATH Use database sockets. Available for some databases only.
+-h, --help Print out this help.
+
+Example:
+\$ sudo -u www-data /usr/bin/php admin/tool/dbtransfer/cli/migrate.php
+";
+
+// Now get cli options.
+list($options, $unrecognized) = cli_get_params(
+ array(
+ 'dbtype' => null,
+ 'dblibrary' => 'native',
+ 'dbhost' => null,
+ 'dbname' => null,
+ 'dbuser' => null,
+ 'dbpass' => null,
+ 'dbport' => null,
+ 'prefix' => null,
+ 'dbsocket' => null,
+ 'maintenance' => null,
+ 'list' => false,
+ 'help' => false,
+ ),
+ array(
+ 'm' => 'maintenance',
+ 'l' => 'list',
+ 'h' => 'help',
+ )
+);
+
+if ($options['help']) {
+ echo $help;
+ exit(0);
+}
+
+if (empty($CFG->version)) {
+ cli_error(get_string('missingconfigversion', 'debug'));
+}
+
+echo "\n".get_string('cliheading', 'tool_dbtransfer')."\n\n";
+
+$drivers = tool_dbtransfer_get_drivers();
+
+if (!isset($options['dbtype'])) {
+ $choose = array();
+ foreach ($drivers as $driver => $name) {
+ list($dbtype, $dblibrary) = explode('/', $driver);
+ $choose[$dbtype] = $dbtype;
+ }
+ $optionsstr = implode(', ', $choose);
+ cli_heading(get_string('databasetypehead', 'install')." ($optionsstr)");
+ $options['dbtype'] = cli_input(get_string('clitypevalue', 'admin'), '', $choose, true);
+}
+
+$choose = array();
+foreach ($drivers as $driver => $name) {
+ list($dbtype, $dblibrary) = explode('/', $driver);
+ if ($dbtype === $options['dbtype']) {
+ $choose[$dblibrary] = $dblibrary;
+ }
+}
+if (!isset($options['dblibrary']) or !isset($choose[$options['dblibrary']])) {
+ $optionsstr = implode(', ', $choose);
+ cli_heading('Database library'." ($optionsstr)"); // Note: no need to localise unless we add real PDO drivers.
+ $options['dblibrary'] = cli_input(get_string('clitypevalue', 'admin'), '', $choose, true);
+}
+
+if (!isset($options['dbhost'])) {
+ cli_heading(get_string('databasehost', 'install'));
+ $options['dbhost'] = cli_input(get_string('clitypevalue', 'admin'));
+}
+
+if (!isset($options['dbname'])) {
+ cli_heading(get_string('databasename', 'install'));
+ $options['dbname'] = cli_input(get_string('clitypevalue', 'admin'));
+}
+
+if (!isset($options['dbuser'])) {
+ cli_heading(get_string('databaseuser', 'install'));
+ $options['dbuser'] = cli_input(get_string('clitypevalue', 'admin'));
+}
+
+if (!isset($options['dbpass'])) {
+ cli_heading(get_string('databasepass', 'install'));
+ $options['dbpass'] = cli_input(get_string('clitypevalue', 'admin'));
+}
+
+if (!isset($options['prefix'])) {
+ cli_heading(get_string('dbprefix', 'install'));
+ $options['prefix'] = cli_input(get_string('clitypevalue', 'admin'));
+}
+
+if (!isset($options['dbport'])) {
+ cli_heading(get_string('dbport', 'install'));
+ $options['dbport'] = cli_input(get_string('clitypevalue', 'admin'));
+}
+
+if ($CFG->ostype !== 'WINDOWS') {
+ if (!isset($options['dbsocket'])) {
+ cli_heading(get_string('databasesocket', 'install'));
+ $options['dbsocket'] = cli_input(get_string('clitypevalue', 'admin'));
+ }
+}
+
+$a = (object)array('dbtypefrom' => $CFG->dbtype, 'dbtype' => $options['dbtype'],
+ 'dbname' => $options['dbname'], 'dbhost' => $options['dbhost']);
+cli_heading(get_string('transferringdbto', 'tool_dbtransfer', $a));
+
+// Try target DB connection.
+$problem = '';
+
+$targetdb = moodle_database::get_driver_instance($options['dbtype'], $options['dblibrary']);
+$dboptions = array();
+if ($options['dbport']) {
+ $dboptions['dbport'] = $options['dbport'];
+}
+if ($options['dbsocket']) {
+ $dboptions['dbsocket'] = $options['dbsocket'];
+}
+try {
+ $targetdb->connect($options['dbhost'], $options['dbuser'], $options['dbpass'], $options['dbname'],
+ $options['prefix'], $dboptions);
+ if ($targetdb->get_tables()) {
+ $problem .= get_string('targetdatabasenotempty', 'tool_dbtransfer');
+ }
+} catch (moodle_exception $e) {
+ $problem .= $e->debuginfo."\n\n";
+ $problem .= get_string('notargetconectexception', 'tool_dbtransfer');
+}
+
+if ($problem !== '') {
+ echo $problem."\n\n";
+ exit(1);
+}
+
+$feedback = new text_progress_trace();
+tool_dbtransfer_transfer_database($DB, $targetdb, $feedback);
+$feedback->finished();
+
+cli_heading(get_string('success'));
+exit(0);
diff --git a/admin/tool/dbtransfer/database_export_form.php b/admin/tool/dbtransfer/database_export_form.php
index 72b7c524699..1fb8b9c2ee3 100644
--- a/admin/tool/dbtransfer/database_export_form.php
+++ b/admin/tool/dbtransfer/database_export_form.php
@@ -17,19 +17,28 @@
/**
* Transfer form
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2008 Petr Skoda
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
-require_once $CFG->libdir.'/formslib.php';
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Definition of db export settings form.
+ *
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
class database_export_form extends moodleform {
-
- function definition() {
+ /**
+ * Define the export form.
+ */
+ public function definition() {
$mform = $this->_form;
$mform->addElement('header', 'database', get_string('dbexport', 'tool_dbtransfer'));
diff --git a/admin/tool/dbtransfer/database_transfer_form.php b/admin/tool/dbtransfer/database_transfer_form.php
index 9b699e911a8..d8a9923a017 100644
--- a/admin/tool/dbtransfer/database_transfer_form.php
+++ b/admin/tool/dbtransfer/database_transfer_form.php
@@ -17,55 +17,84 @@
/**
* Transfer form
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2008 Petr Skoda
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
-require_once $CFG->libdir.'/formslib.php';
+require_once($CFG->libdir.'/formslib.php');
+require_once(__DIR__.'/locallib.php');
+
+/**
+ * Definition of db transfer settings form.
+ *
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
class database_transfer_form extends moodleform {
- function definition() {
+ /**
+ * Define transfer form.
+ */
+ protected function definition() {
+ global $CFG;
+
$mform = $this->_form;
- $mform->addElement('header', 'database', get_string('dbtransfer', 'tool_dbtransfer'));
+ $mform->addElement('header', 'database', get_string('targetdatabase', 'tool_dbtransfer'));
- $supported = array (
- 'mysqli/native',
- 'pgsql/native',
- 'mssql/native',
- 'oci/native',
- 'sqlsrv/native',
- );
- $drivers = array();
- foreach($supported as $driver) {
- list($dbtype, $dblibrary) = explode('/', $driver);
- $targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary);
- if ($targetdb->driver_installed() !== true) {
- continue;
- }
- $drivers[$driver] = $driver;
- }
+ $drivers = tool_dbtransfer_get_drivers();
+ $drivers = array_reverse($drivers, true);
+ $drivers[''] = get_string('choosedots');
+ $drivers = array_reverse($drivers, true);
$mform->addElement('select', 'driver', get_string('dbtype', 'install'), $drivers);
- $mform->addElement('text', 'dbhost', get_string('dbhost', 'install'));
- $mform->addElement('text', 'dbname', get_string('database', 'install'));
- $mform->addElement('text', 'dbuser', get_string('user'));
- $mform->addElement('text', 'dbpass', get_string('password'));
+ $mform->addElement('text', 'dbhost', get_string('databasehost', 'install'));
+ $mform->addElement('text', 'dbname', get_string('databasename', 'install'));
+ $mform->addElement('text', 'dbuser', get_string('databaseuser', 'install'));
+ $mform->addElement('passwordunmask', 'dbpass', get_string('databasepass', 'install'));
$mform->addElement('text', 'prefix', get_string('dbprefix', 'install'));
$mform->addElement('text', 'dbport', get_string('dbport', 'install'));
- $mform->addElement('text', 'dbsocket', get_string('databasesocket', 'install'));
+ if ($CFG->ostype !== 'WINDOWS') {
+ $mform->addElement('text', 'dbsocket', get_string('databasesocket', 'install'));
+ } else {
+ $mform->addElement('hidden', 'dbsocket');
+ }
+ $mform->addRule('driver', get_string('required'), 'required', null);
$mform->addRule('dbhost', get_string('required'), 'required', null);
$mform->addRule('dbname', get_string('required'), 'required', null);
$mform->addRule('dbuser', get_string('required'), 'required', null);
$mform->addRule('dbpass', get_string('required'), 'required', null);
- $mform->addRule('prefix', get_string('required'), 'required', null);
+ if (!isset($drivers['mysqli/native'])) {
+ $mform->addRule('prefix', get_string('required'), 'required', null);
+ }
+
+ $mform->addElement('header', 'database', get_string('options', 'tool_dbtransfer'));
+
+ $mform->addElement('advcheckbox', 'enablemaintenance', get_string('enablemaintenance', 'tool_dbtransfer'));
+ $mform->addHelpButton('enablemaintenance', 'enablemaintenance', 'tool_dbtransfer');
$this->add_action_buttons(false, get_string('transferdata', 'tool_dbtransfer'));
}
+
+ /**
+ * Validate prefix is present for non-mysql drivers.
+ * @param array $data
+ * @param array $files
+ * @return array
+ */
+ public function validation($data, $files) {
+ $errors = parent::validation($data, $files);
+ if ($data['driver'] !== 'mysqli/native') {
+ // This is a bloody hack, let's pretend we do not need to look at db family...
+ if ($data['prefix'] === '') {
+ $errors['prefix'] = get_string('required');
+ }
+ }
+ return $errors;
+ }
}
diff --git a/admin/tool/dbtransfer/dbexport.php b/admin/tool/dbtransfer/dbexport.php
index 40f35ff0f25..f55b29d0312 100644
--- a/admin/tool/dbtransfer/dbexport.php
+++ b/admin/tool/dbtransfer/dbexport.php
@@ -17,9 +17,8 @@
/**
* Export
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2008 Petr Skoda
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -32,15 +31,15 @@ require_once('database_export_form.php');
require_login();
admin_externalpage_setup('tooldbexport');
-//create form
+// Create form.
$form = new database_export_form();
if ($data = $form->get_data()) {
- dbtransfer_export_xml_database($data->description, $DB);
+ tool_dbtransfer_export_xml_database($data->description, $DB);
die;
}
echo $OUTPUT->header();
-// TODO: add some more info here
+// TODO: add some more info here.
$form->display();
echo $OUTPUT->footer();
diff --git a/admin/tool/dbtransfer/index.php b/admin/tool/dbtransfer/index.php
index 2b1a2c5cf46..aa8b5b3b581 100644
--- a/admin/tool/dbtransfer/index.php
+++ b/admin/tool/dbtransfer/index.php
@@ -17,9 +17,8 @@
/**
* Transfer tool
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2008 Petr Skoda
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -32,8 +31,9 @@ require_once('database_transfer_form.php');
require_login();
admin_externalpage_setup('tooldbtransfer');
-// Create the form
+// Create the form.
$form = new database_transfer_form();
+$problem = '';
// If we have valid input.
if ($data = $form->get_data()) {
@@ -47,33 +47,63 @@ if ($data = $form->get_data()) {
if ($data->dbsocket) {
$dboptions['dbsocket'] = $data->dbsocket;
}
- if (!$targetdb->connect($data->dbhost, $data->dbuser, $data->dbpass, $data->dbname, $data->prefix, $dboptions)) {
- throw new dbtransfer_exception('notargetconectexception', null, "$CFG->wwwroot/$CFG->admin/tool/dbtransfer/");
- }
- if ($targetdb->get_tables()) {
- throw new dbtransfer_exception('targetdatabasenotempty', null, "$CFG->wwwroot/$CFG->admin/tool/dbtransfer/");
+ try {
+ $targetdb->connect($data->dbhost, $data->dbuser, $data->dbpass, $data->dbname, $data->prefix, $dboptions);
+ if ($targetdb->get_tables()) {
+ $problem .= get_string('targetdatabasenotempty', 'tool_dbtransfer');
+ }
+ } catch (moodle_exception $e) {
+ $problem .= get_string('notargetconectexception', 'tool_dbtransfer').'
'.$e->debuginfo;
}
- // Start output.
- echo $OUTPUT->header();
- $data->dbtype = $dbtype;
- echo $OUTPUT->heading(get_string('transferringdbto', 'tool_dbtransfer', $data));
+ if ($problem === '') {
+ // Scroll down to the bottom when finished.
+ $PAGE->requires->js_init_code("window.scrollTo(0, 5000000);");
- // Do the transfer.
- $feedback = new html_list_progress_trace();
- dbtransfer_transfer_database($DB, $targetdb, $feedback);
- $feedback->finished();
+ // Enable CLI maintenance mode if requested.
+ if ($data->enablemaintenance) {
+ $PAGE->set_pagelayout('maintenance');
+ tool_dbtransfer_create_maintenance_file();
+ }
- // Finish up.
- echo $OUTPUT->notification(get_string('success'), 'notifysuccess');
- echo $OUTPUT->continue_button("$CFG->wwwroot/$CFG->admin/");
- echo $OUTPUT->footer();
- die;
+ // Start output.
+ echo $OUTPUT->header();
+ $data->dbtype = $dbtype;
+ $data->dbtypefrom = $CFG->dbtype;
+ echo $OUTPUT->heading(get_string('transferringdbto', 'tool_dbtransfer', $data));
+
+ // Do the transfer.
+ $CFG->tool_dbransfer_migration_running = true;
+ try {
+ $feedback = new html_list_progress_trace();
+ tool_dbtransfer_transfer_database($DB, $targetdb, $feedback);
+ $feedback->finished();
+ } catch (Exception $e) {
+ if ($data->enablemaintenance) {
+ tool_dbtransfer_maintenance_callback();
+ }
+ unset($CFG->tool_dbransfer_migration_running);
+ throw $e;
+ }
+ unset($CFG->tool_dbransfer_migration_running);
+
+ // Finish up.
+ echo $OUTPUT->notification(get_string('success'), 'notifysuccess');
+ echo $OUTPUT->continue_button("$CFG->wwwroot/$CFG->admin/");
+ echo $OUTPUT->footer();
+ die;
+ }
}
// Otherwise display the settings form.
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('transferdbtoserver', 'tool_dbtransfer'));
-echo '
', get_string('transferdbintro', 'tool_dbtransfer'), "
\n\n";
+
+$info = format_text(get_string('transferdbintro', 'tool_dbtransfer'), FORMAT_MARKDOWN);
+echo $OUTPUT->box($info);
+
$form->display();
+if ($problem !== '') {
+ echo $OUTPUT->box($problem, 'generalbox error');
+}
echo $OUTPUT->footer();
diff --git a/admin/tool/dbtransfer/lang/en/tool_dbtransfer.php b/admin/tool/dbtransfer/lang/en/tool_dbtransfer.php
index 1279af58eee..a67a3e950f9 100644
--- a/admin/tool/dbtransfer/lang/en/tool_dbtransfer.php
+++ b/admin/tool/dbtransfer/lang/en/tool_dbtransfer.php
@@ -15,21 +15,29 @@
// along with Moodle. If not, see .
/**
- * Strings for component 'tool_generator', language 'en', branch 'MOODLE_22_STABLE'
+ * Strings for component 'tool_generator', language 'en'.
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2011 Petr Skoda
+ * @package tool_dbtransfer
+ * @copyright 2011 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-$string['dbexport'] = 'Database transfer';
-$string['dbtransfer'] = 'Database export';
+$string['clidriverlist'] = 'Available database drivers for migration';
+$string['cliheading'] = 'Database migration - make sure nobody is accessing the server during migration!';
+$string['climigrationnotice'] = 'Database migration in progress, please wait until the migration completes and server administrator updates configuration and deletes the $CFG->dataroot/climaintenance.html file.';
+$string['convertinglogdisplay'] = 'Converting log display actions';
+$string['dbexport'] = 'Database export';
+$string['dbtransfer'] = 'Database migration';
+$string['enablemaintenance'] = 'Enable maintenance mode';
+$string['enablemaintenance_help'] = 'This option enables maintanance mode during and after the database migration, it prevents access of all users until the migration is completed. Please note that administrator has to manually delete $CFG->dataroot/climaintenance.html file after updating config.php settings to resume normal operation.';
$string['exportdata'] = 'Export data';
$string['notargetconectexception'] = 'Can not connect target database, sorry.';
+$string['options'] = 'Options';
$string['pluginname'] = 'Database transfer';
+$string['targetdatabase'] = 'Target database';
+$string['targetdatabasenotempty'] = 'Target database must not contain any tables with given prefix!';
$string['transferdata'] = 'Transfer data';
-$string['transferdbintro'] = 'This script will transfer the entire contents of this database to another database server.';
+$string['transferdbintro'] = 'This script will transfer the entire contents of this database to another database server. It is often used for migration of data to different database type.';
$string['transferdbtoserver'] = 'Transfer this Moodle database to another server';
-$string['transferringdbto'] = 'Transferring this database to {$a->dbtype} database {$a->dbname} on {$a->dbhost}';
+$string['transferringdbto'] = 'Transferring this {$a->dbtypefrom} database to {$a->dbtype} database "{$a->dbname}" on "{$a->dbhost}"';
diff --git a/admin/tool/dbtransfer/locallib.php b/admin/tool/dbtransfer/locallib.php
index f36ceef614a..8b0b0622f54 100644
--- a/admin/tool/dbtransfer/locallib.php
+++ b/admin/tool/dbtransfer/locallib.php
@@ -17,9 +17,8 @@
/**
* Export db content to file.
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2008 Petr Skoda {@link http://skodak.org}
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
@@ -44,11 +43,16 @@ TODO:
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/dtllib.php');
-
-function dbtransfer_export_xml_database($description, $mdb) {
+/**
+ * Initiate database export.
+ * @param string $description
+ * @param moodle_database $mdb
+ * @return does not return, calls die()
+ */
+function tool_dbtransfer_export_xml_database($description, $mdb) {
@set_time_limit(0);
- session_get_instance()->write_close(); // release session
+ session_get_instance()->write_close(); // Release session.
header('Content-Type: application/xhtml+xml; charset=utf-8');
header('Content-Disposition: attachment; filename=database.xml');
@@ -61,16 +65,145 @@ function dbtransfer_export_xml_database($description, $mdb) {
$var = new file_xml_database_exporter('php://output', $mdb);
$var->export_database($description);
- // no more output
+ // No more output.
die;
}
-
-function dbtransfer_transfer_database($sourcedb, $targetdb, $feedback = null) {
+/**
+ * Initiate database transfer.
+ * @param moodle_database $sourcedb
+ * @param moodle_database $targetdb
+ * @param progress_trace $feedback
+ * @return void
+ */
+function tool_dbtransfer_transfer_database(moodle_database $sourcedb, moodle_database $targetdb, progress_trace $feedback = null) {
@set_time_limit(0);
- session_get_instance()->write_close(); // release session
+ session_get_instance()->write_close(); // Release session.
$var = new database_mover($sourcedb, $targetdb, true, $feedback);
$var->export_database(null);
+
+ tool_dbtransfer_rebuild_target_log_actions($targetdb, $feedback);
+}
+
+/**
+ * Very hacky function for rebuilding of log actions in target database.
+ * @param moodle_database $target
+ * @param progress_trace $feedback
+ * @return void
+ * @throws Exception on conversion error
+ */
+function tool_dbtransfer_rebuild_target_log_actions(moodle_database $target, progress_trace $feedback = null) {
+ global $DB, $CFG;
+ require_once("$CFG->libdir/upgradelib.php");
+
+ $feedback->output(get_string('convertinglogdisplay', 'tool_dbtransfer'));
+
+ $olddb = $DB;
+ $DB = $target;
+ try {
+ $DB->delete_records('log_display', array('component'=>'moodle'));
+ log_update_descriptions('moodle');
+ $plugintypes = get_plugin_types();
+ foreach ($plugintypes as $type => $location) {
+ $plugs = get_plugin_list($type);
+ foreach ($plugs as $plug => $fullplug) {
+ $component = $type.'_'.$plug;
+ $DB->delete_records('log_display', array('component'=>$component));
+ log_update_descriptions($component);
+ }
+ }
+ } catch (Exception $e) {
+ $DB = $olddb;
+ throw $e;
+ }
+ $DB = $olddb;
+ $feedback->output(get_string('done', 'core_dbtransfer', null), 1);
+}
+
+/**
+ * Returns list of fully working database drivers present in system.
+ * @return array
+ */
+function tool_dbtransfer_get_drivers() {
+ global $CFG;
+
+ $files = new RegexIterator(new DirectoryIterator("$CFG->libdir/dml"), '|^.*_moodle_database\.php$|');
+ $drivers = array();
+
+ foreach ($files as $file) {
+ $matches = null;
+ preg_match('|^([a-z0-9]+)_([a-z]+)_moodle_database\.php$|', $file->getFilename(), $matches);
+ if (!$matches) {
+ continue;
+ }
+ $dbtype = $matches[1];
+ $dblibrary = $matches[2];
+
+ if ($dbtype === 'sqlite3') {
+ // Blacklist unfinished drivers.
+ continue;
+ }
+
+ $targetdb = moodle_database::get_driver_instance($dbtype, $dblibrary, false);
+ if ($targetdb->driver_installed() !== true) {
+ continue;
+ }
+
+ $driver = $dbtype.'/'.$dblibrary;
+
+ $drivers[$driver] = $targetdb->get_name();
+ };
+
+ return $drivers;
+}
+
+/**
+ * Create CLI maintenance file to prevent all access.
+ */
+function tool_dbtransfer_create_maintenance_file() {
+ global $CFG;
+
+ register_shutdown_function('tool_dbtransfer_maintenance_callback');
+
+ $options = new stdClass();
+ $options->trusted = false;
+ $options->noclean = false;
+ $options->smiley = false;
+ $options->filter = false;
+ $options->para = true;
+ $options->newlines = false;
+
+ $message = format_text(get_string('climigrationnotice', 'tool_dbtransfer'), FORMAT_MARKDOWN, $options);
+ $message = bootstrap_renderer::early_error_content($message, '', '', array());
+ $html = <<
+
+
+$message
+
+OET;
+
+ file_put_contents("$CFG->dataroot/climaintenance.html", $html);
+ @chmod("$CFG->dataroot/climaintenance.html", $CFG->filepermissions);
+}
+
+/**
+ * This callback is responsible for unsetting maintenance mode
+ * if the migration is interrupted.
+ */
+function tool_dbtransfer_maintenance_callback() {
+ global $CFG;
+
+ if (empty($CFG->tool_dbransfer_migration_running)) {
+ // Migration was finished properly - keep the maintenance file in place.
+ return;
+ }
+
+ if (file_exists("$CFG->dataroot/climaintenance.html")) {
+ // Failed migration, revert to normal site operation.
+ unlink("$CFG->dataroot/climaintenance.html");
+ error_log('tool_dbtransfer: Interrupted database migration detected, switching off CLI maintenance mode.');
+ }
}
diff --git a/admin/tool/dbtransfer/settings.php b/admin/tool/dbtransfer/settings.php
index 13c45b880cc..47175423670 100644
--- a/admin/tool/dbtransfer/settings.php
+++ b/admin/tool/dbtransfer/settings.php
@@ -15,18 +15,19 @@
// along with Moodle. If not, see .
/**
- * Link to InnoDB conversion tool
+ * Add hidden links db transfer tool
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2011 Petr Skoda {@link http://skodak.org}
+ * @package tool_dbtransfer
+ * @copyright 2011 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($hassiteconfig) {
- // DB transfer related pages
- $ADMIN->add('experimental', new admin_externalpage('tooldbtransfer', get_string('dbtransfer', 'tool_dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/tool/dbtransfer/index.php', 'moodle/site:config', true));
- $ADMIN->add('experimental', new admin_externalpage('tooldbexport', get_string('dbexport', 'tool_dbtransfer'), $CFG->wwwroot.'/'.$CFG->admin.'/tool/dbtransfer/dbexport.php', 'moodle/site:config', true));
-}
\ No newline at end of file
+ $ADMIN->add('experimental', new admin_externalpage('tooldbtransfer', get_string('dbtransfer', 'tool_dbtransfer'),
+ $CFG->wwwroot.'/'.$CFG->admin.'/tool/dbtransfer/index.php', 'moodle/site:config', false));
+ // DB export/import is not ready yet - keep it hidden for now.
+ $ADMIN->add('experimental', new admin_externalpage('tooldbexport', get_string('dbexport', 'tool_dbtransfer'),
+ $CFG->wwwroot.'/'.$CFG->admin.'/tool/dbtransfer/dbexport.php', 'moodle/site:config', true));
+}
diff --git a/admin/tool/dbtransfer/version.php b/admin/tool/dbtransfer/version.php
index 61aa6ec612c..59bafe585cf 100644
--- a/admin/tool/dbtransfer/version.php
+++ b/admin/tool/dbtransfer/version.php
@@ -17,14 +17,13 @@
/**
* Version details.
*
- * @package tool
- * @subpackage dbtransfer
- * @copyright 2008 Petr Skoda
+ * @package tool_dbtransfer
+ * @copyright 2008 Petr Skoda {@link http://skodak.org/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012061700; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires = 2012061700; // Requires this Moodle version
-$plugin->component = 'tool_dbtransfer'; // Full name of the plugin (used for diagnostics)
+$plugin->version = 2012062200; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires = 2012061700; // Requires this Moodle version.
+$plugin->component = 'tool_dbtransfer'; // Full name of the plugin (used for diagnostics).
diff --git a/admin/tool/generator/index.php b/admin/tool/generator/index.php
index c747e311b99..577fefcf99d 100644
--- a/admin/tool/generator/index.php
+++ b/admin/tool/generator/index.php
@@ -28,7 +28,7 @@ require_once('locallib.php');
require_login();
-$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$systemcontext = context_system::instance();
require_capability('moodle/site:config', $systemcontext);
if (!is_siteadmin()) {
error('Only for admins');
diff --git a/admin/tool/generator/locallib.php b/admin/tool/generator/locallib.php
index 1eceb1aaee4..169f6436319 100644
--- a/admin/tool/generator/locallib.php
+++ b/admin/tool/generator/locallib.php
@@ -706,7 +706,7 @@ class generator {
shuffle($users);
$users_to_assign = array_slice($users, 0, $this->get('students_per_course'));
- $context = get_context_instance(CONTEXT_COURSE, $courseid);
+ $context = context_course::instance($courseid);
foreach ($users_to_assign as $random_user) {
role_assign(5, $random_user, $context->id);
diff --git a/admin/tool/health/index.php b/admin/tool/health/index.php
index cc178309ce7..3966865c242 100644
--- a/admin/tool/health/index.php
+++ b/admin/tool/health/index.php
@@ -39,7 +39,7 @@
$solution = optional_param('solution', 0, PARAM_PLUGIN);
require_login();
- require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+ require_capability('moodle/site:config', context_system::instance());
$site = get_site();
diff --git a/admin/tool/innodb/index.php b/admin/tool/innodb/index.php
index 3e57e904fdd..06f4f6a5299 100644
--- a/admin/tool/innodb/index.php
+++ b/admin/tool/innodb/index.php
@@ -33,7 +33,7 @@ admin_externalpage_setup('toolinnodb');
$confirm = optional_param('confirm', 0, PARAM_BOOL);
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
echo $OUTPUT->header();
echo $OUTPUT->heading('Convert all MySQL tables from MYISAM to InnoDB');
diff --git a/admin/tool/qeupgradehelper/convertquiz.php b/admin/tool/qeupgradehelper/convertquiz.php
index f4176fc4cee..d12fc992703 100644
--- a/admin/tool/qeupgradehelper/convertquiz.php
+++ b/admin/tool/qeupgradehelper/convertquiz.php
@@ -33,7 +33,7 @@ $quizid = required_param('quizid', PARAM_INT);
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
tool_qeupgradehelper_require_upgraded();
admin_externalpage_setup('qeupgradehelper', '', array(),
diff --git a/admin/tool/qeupgradehelper/cronsetup.php b/admin/tool/qeupgradehelper/cronsetup.php
index 58280a95b3f..2523ee5c565 100644
--- a/admin/tool/qeupgradehelper/cronsetup.php
+++ b/admin/tool/qeupgradehelper/cronsetup.php
@@ -30,7 +30,7 @@ require_once(dirname(__FILE__) . '/cronsetup_form.php');
require_once($CFG->libdir . '/adminlib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
admin_externalpage_setup('qeupgradehelper', '', array(),
tool_qeupgradehelper_url('cronsetup'));
diff --git a/admin/tool/qeupgradehelper/extracttestcase.php b/admin/tool/qeupgradehelper/extracttestcase.php
index d67fe6599a9..902418f1730 100644
--- a/admin/tool/qeupgradehelper/extracttestcase.php
+++ b/admin/tool/qeupgradehelper/extracttestcase.php
@@ -37,7 +37,7 @@ require_once($CFG->libdir . '/adminlib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
admin_externalpage_setup('qeupgradehelper', '', array(),
tool_qeupgradehelper_url('extracttestcase'));
diff --git a/admin/tool/qeupgradehelper/index.php b/admin/tool/qeupgradehelper/index.php
index 2fe264216e7..776645a73ce 100644
--- a/admin/tool/qeupgradehelper/index.php
+++ b/admin/tool/qeupgradehelper/index.php
@@ -32,7 +32,7 @@ require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/adminlib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
admin_externalpage_setup('qeupgradehelper');
$renderer = $PAGE->get_renderer('tool_qeupgradehelper');
diff --git a/admin/tool/qeupgradehelper/listpreupgrade.php b/admin/tool/qeupgradehelper/listpreupgrade.php
index e243dc3797d..ee15a094a80 100644
--- a/admin/tool/qeupgradehelper/listpreupgrade.php
+++ b/admin/tool/qeupgradehelper/listpreupgrade.php
@@ -30,7 +30,7 @@ require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/adminlib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
tool_qeupgradehelper_require_not_upgraded();
admin_externalpage_setup('qeupgradehelper', '', array(), tool_qeupgradehelper_url(''));
diff --git a/admin/tool/qeupgradehelper/listtodo.php b/admin/tool/qeupgradehelper/listtodo.php
index 6e923ecd762..83062ea7a52 100644
--- a/admin/tool/qeupgradehelper/listtodo.php
+++ b/admin/tool/qeupgradehelper/listtodo.php
@@ -30,7 +30,7 @@ require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/adminlib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
tool_qeupgradehelper_require_upgraded();
admin_externalpage_setup('qeupgradehelper', '', array(),
diff --git a/admin/tool/qeupgradehelper/listupgraded.php b/admin/tool/qeupgradehelper/listupgraded.php
index 8aa3dca78c0..187f75e984d 100644
--- a/admin/tool/qeupgradehelper/listupgraded.php
+++ b/admin/tool/qeupgradehelper/listupgraded.php
@@ -31,7 +31,7 @@ require_once(dirname(__FILE__) . '/locallib.php');
require_once($CFG->libdir . '/adminlib.php');
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
tool_qeupgradehelper_require_upgraded();
admin_externalpage_setup('qeupgradehelper', '', array(),
diff --git a/admin/tool/qeupgradehelper/resetquiz.php b/admin/tool/qeupgradehelper/resetquiz.php
index a3bf94a5ba0..1029cb23e24 100644
--- a/admin/tool/qeupgradehelper/resetquiz.php
+++ b/admin/tool/qeupgradehelper/resetquiz.php
@@ -32,7 +32,7 @@ $quizid = required_param('quizid', PARAM_INT);
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
+require_capability('moodle/site:config', context_system::instance());
tool_qeupgradehelper_require_upgraded();
admin_externalpage_setup('qeupgradehelper', '', array(),
diff --git a/admin/tool/unittest/coveragefile.php b/admin/tool/unittest/coveragefile.php
deleted file mode 100644
index d3c8737a4e8..00000000000
--- a/admin/tool/unittest/coveragefile.php
+++ /dev/null
@@ -1,71 +0,0 @@
-.
-
-/**
- * This script serves files from dataroot/codecoverage
- *
- * Syntax: coveragefile.php/path/to/file/file.html
- * coveragefile.php?file=path/to/file/file.html
- *
- * @package tool
- * @subpackage unittest
- * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-// disable moodle specific debug messages and any errors in output
-define('NO_DEBUG_DISPLAY', true);
-
-require(dirname(__FILE__) . '/../../../config.php');
-require_once($CFG->libdir . '/filelib.php');
-
-// basic security, require login + require site config cap
-require_login();
-require_capability('tool/unittest:execute', get_context_instance(CONTEXT_SYSTEM));
-
-// get file requested
-$relativepath = get_file_argument();
-
-// basic check, start by slash
-if (!$relativepath) {
- print_error('invalidargorconf');
-} else if ($relativepath{0} != '/') {
- print_error('pathdoesnotstartslash');
-}
-
-// determine which disk file is going to be served
-// and how it's going to be named
-$filepath = $CFG->dataroot . '/codecoverage' . $relativepath;
-$filename = basename($filepath);
-
-// extract relative path components
-$args = explode('/', ltrim($relativepath, '/'));
-
-// only serve from some controlled subdirs
-$alloweddirs = array('dbtest', 'unittest');
-if (!isset($args[0]) || !in_array($args[0], $alloweddirs)) {
- print_error('invalidarguments');
-}
-
-// only serve some controlled extensions/mimetypes
-if (!file_extension_in_typegroup($filepath, array('web_file', 'web_image'), true)) {
- print_error('invalidarguments');
-}
-
-// arrived here, send the file
-session_get_instance()->write_close(); // unlock session during fileserving
-send_file($filepath, $filename, 0, false);
-
diff --git a/admin/tool/unittest/db/install.php b/admin/tool/unittest/db/install.php
deleted file mode 100644
index 1923960d282..00000000000
--- a/admin/tool/unittest/db/install.php
+++ /dev/null
@@ -1,31 +0,0 @@
-.
-
-/**
- * Post installation and migration code.
- *
- * @package tool
- * @subpackage unittest
- * @copyright 2011 Petr Skoda {@link http://skodak.org}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die;
-
-function xmldb_tool_unittest_install() {
- global $CFG;
-
-}
diff --git a/admin/tool/unittest/ex_reporter.php b/admin/tool/unittest/ex_reporter.php
deleted file mode 100644
index 01476d29329..00000000000
--- a/admin/tool/unittest/ex_reporter.php
+++ /dev/null
@@ -1,297 +0,0 @@
-.
-
-/**
- * A SimpleTest report format for Moodle.
- *
- * @package tool
- * @subpackage unittest
- * @copyright © 2006 The Open University
- * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-if (!defined('MOODLE_INTERNAL')) {
- die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
-}
-
-require_once($CFG->libdir . '/simpletestlib/reporter.php');
-
-/**
- * Extended in-browser test displayer. HtmlReporter generates
- * only failure messages and a pass count. ExHtmlReporter also
- * generates pass messages and a time-stamp.
- *
- * @package SimpleTestEx
- */
-class ExHtmlReporter extends HtmlReporter {
-
- // Options set when the class is created.
- var $showpasses;
-
- // Lang strings. Set in the constructor.
- var $strrunonlyfolder;
- var $strrunonlyfile;
-
- var $strseparator;
-
- var $timestart;
-
- /**
- * Constructor.
- *
- * @param bool $showpasses Whether this reporter should output anything for passes.
- */
- function __construct($showpasses) {
- parent::__construct('UTF-8');
- $this->showpasses = $showpasses;
-
- $this->strrunonlyfolder = $this->get_string('runonlyfolder');
- $this->strrunonlyfile = $this->get_string('runonlyfile');
- $this->strseparator = get_separator();
- }
-
- /**
- * Called when a pass needs to be output.
- */
- function paintPass($message) {
- //(Implicitly call grandparent, as parent not implemented.)
- parent::paintPass($message);
- if ($this->showpasses) {
- $this->_paintPassFail('pass', $message);
- }
- }
-
- /**
- * Called when a fail needs to be output.
- */
- function paintFail($message) {
- // Explicitly call grandparent, not parent::paintFail.
- SimpleScorer::paintFail($message);
- $this->_paintPassFail('fail', $message, debug_backtrace());
- }
-
- /**
- * Called when a skip needs to be output.
- */
- function paintSkip($message) {
- // Explicitly call grandparent, not parent::paintFail.
- SimpleScorer::paintSkip($message);
- $this->_paintPassFail('skip', $message);
- }
-
- /**
- * Called when an error (uncaught exception or PHP error) needs to be output.
- */
- function paintError($message) {
- // Explicitly call grandparent, not parent::paintError.
- SimpleScorer::paintError($message);
- $this->_paintPassFail('exception', $message);
- }
-
- /**
- * Called when a caught exception needs to be output.
- */
- function paintException($exception) {
- // Explicitly call grandparent, not parent::paintException.
- SimpleScorer::paintException($exception);
-
- if (is_a($exception, 'moodle_exception') &&
- !get_string_manager()->string_exists($exception->errorcode, $exception->module)) {
- $exceptionmessage = 'Exception with missing language string {' .
- $exception->errorcode . '} from language file {' . $exception->module . '}';
-
- if (!empty($exception->a)) {
- if (is_string($exception->a)) {
- $data = $exception->a;
- } else {
- $data = array();
- foreach ((array)$exception->a as $name => $value) {
- $data[] = $name . ' => [' . $value . ']';
- }
- $data = implode(', ', $data);
- }
- $exceptionmessage .= ' with data {' . $data . '}';
- }
-
- } else {
- $exceptionmessage = $exception->getMessage();
- }
- $message = 'Unexpected exception of type [' . get_class($exception) .
- '] with message ['. $exceptionmessage .
- '] in ['. $exception->getFile() .
- ' line ' . $exception->getLine() . ']';
-
- $debuginfo = null;
- if (!empty($exception->debuginfo)) {
- $debuginfo = $exception->debuginfo;
- }
-
- $this->_paintPassFail('exception', $message, $exception->getTrace(), $debuginfo);
- }
-
- /**
- * Private method. Used by printPass/Fail/Skip/Error.
- */
- function _paintPassFail($passorfail, $message, $stacktrace = null, $debuginfo = null) {
- global $CFG, $OUTPUT;
-
- echo $OUTPUT->box_start($passorfail . ' generalbox ');
-
- $url = $this->_htmlEntities($this->_stripParameterFromUrl(qualified_me(), 'path'));
- echo '', $this->get_string($passorfail), ': ';
- $breadcrumb = $this->getTestList();
- array_shift($breadcrumb);
- $file = array_shift($breadcrumb);
- $pathbits = preg_split('/\/|\\\\/', substr($file, strlen($CFG->dirroot) + 1));
- $file = array_pop($pathbits);
- $folder = '';
- foreach ($pathbits as $pathbit) {
- $folder .= $pathbit . '/';
- echo "strrunonlyfolder\">$pathbit/";
- }
- echo "strrunonlyfile\">$file";
- echo $this->strseparator, implode($this->strseparator, $breadcrumb);
-
- echo '
', $this->_htmlEntities($message), "\n\n";
-
- if (!empty($debuginfo)) {
- print_object('Debug info:');
- print_object($debuginfo);
- }
-
- if ($stacktrace) {
- $dotsadded = false;
- $interestinglines = 0;
- $filteredstacktrace = array();
- foreach ($stacktrace as $frame) {
- if (empty($frame['file']) || (strpos($frame['file'], 'simpletestlib') === false &&
- strpos($frame['file'], 'simpletestcoveragelib') === false
- && strpos($frame['file'], 'tool/unittest') === false)) {
- $filteredstacktrace[] = $frame;
- $interestinglines += 1;
- $dotsadded = false;
- } else if (!$dotsadded) {
- $filteredstacktrace[] = array('line' => '...', 'file' => '...');
- $dotsadded = true;
- }
- }
- if ($interestinglines > 1 || ($passorfail == 'exception' && $interestinglines > 0)) {
- echo '' . format_backtrace($filteredstacktrace) . "
\n\n";
- }
- }
-
- echo $OUTPUT->box_end();
- flush();
- }
-
- /**
- * Called when a notice needs to be output.
- */
- function paintNotice($message) {
- $this->paintMessage($this->_htmlEntities($message));
- }
-
- /**
- * Paints a simple supplementary message.
- * @param string $message Text to display.
- */
- function paintMessage($message) {
- global $OUTPUT;
- if ($this->showpasses) {
- echo $OUTPUT->box_start();
- echo '', $this->get_string('notice'), ': ';
- $breadcrumb = $this->getTestList();
- array_shift($breadcrumb);
- echo implode($this->strseparator, $breadcrumb);
- echo $this->strseparator, '
', $message, "\n";
- echo $OUTPUT->box_end();
- flush();
- }
- }
-
- /**
- * Output anything that should appear above all the test output.
- */
- function paintHeader($test_name) {
- $this->timestart = time();
- // We do this the moodle way instead.
- }
-
- /**
- * Output anything that should appear below all the test output, e.g. summary information.
- */
- function paintFooter($test_name) {
- $summarydata = new stdClass;
- $summarydata->run = $this->getTestCaseProgress();
- $summarydata->total = $this->getTestCaseCount();
- $summarydata->passes = $this->getPassCount();
- $summarydata->fails = $this->getFailCount();
- $summarydata->exceptions = $this->getExceptionCount();
-
- if ($summarydata->fails == 0 && $summarydata->exceptions == 0) {
- $status = "passed";
- } else {
- $status = "failed";
- }
- echo '';
- echo $this->get_string('summary', $summarydata);
- echo '
';
-
- echo '',
- $this->get_string('runat', userdate($this->timestart)), ' ',
- $this->get_string('timetakes', format_time(time() - $this->timestart)), ' ',
- $this->get_string('version', SimpleTest::getVersion()),
- '
';
- }
-
- /**
- * Strip a specified parameter from the query string of a URL, if present.
- * Adds a separator to the end of the URL, so that a new parameter
- * can easily be appended. For example (assuming $param = 'frog'):
- *
- * http://example.com/index.php -> http://example.com/index.php?
- * http://example.com/index.php?frog=1 -> http://example.com/index.php?
- * http://example.com/index.php?toad=1 -> http://example.com/index.php?toad=1&
- * http://example.com/index.php?frog=1&toad=1 -> http://example.com/index.php?toad=1&
- *
- * @param string $url the URL to modify.
- * @param string $param the parameter to strip from the URL, if present.
- *
- * @return string The modified URL.
- */
- function _stripParameterFromUrl($url, $param) {
- $url = preg_replace('/(\?|&)' . $param . '=[^&]*&?/', '$1', $url);
- if (strpos($url, '?') === false) {
- $url = $url . '?';
- } else {
- $url = $url . '&';
- }
- return $url;
- }
-
- /**
- * Look up a lang string in the appropriate file.
- */
- function get_string($identifier, $a = NULL) {
- return get_string($identifier, 'tool_unittest', $a);
- }
-
- function _htmlEntities($message) {
- // Override subclass message that breaks UTF8.
- return s($message);
- }
-}
diff --git a/admin/tool/unittest/ex_simple_test.php b/admin/tool/unittest/ex_simple_test.php
deleted file mode 100644
index dd6ee8a4391..00000000000
--- a/admin/tool/unittest/ex_simple_test.php
+++ /dev/null
@@ -1,231 +0,0 @@
-.
-
-/**
- * A SimpleTest GroupTest that automatically finds all the
- * test files in a directory tree according to certain rules.
- *
- * @package tool
- * @subpackage unittest
- * @copyright © 2006 The Open University
- * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-if (!defined('MOODLE_INTERNAL')) {
- die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
-}
-
-require_once($CFG->libdir . '/simpletestlib/test_case.php');
-
-/**
- * This is a composite test class for finding test cases and
- * other RunnableTest classes in a directory tree and combining
- * them into a group test.
- * @package SimpleTestEx
- */
-class AutoGroupTest extends TestSuite {
-
- var $showsearch;
-
- function AutoGroupTest($showsearch, $test_name = null) {
- $this->TestSuite($test_name);
- $this->showsearch = $showsearch;
- }
-
- function run($reporter) {
- global $UNITTEST;
-
- $UNITTEST->running = true;
- $return = parent::run($reporter);
- unset($UNITTEST->running);
- return $return;
- }
-
- function setLabel($test_name) {
- //:HACK: there is no GroupTest::setLabel, so access parent::_label.
- $this->_label = $test_name;
- }
-
- function addIgnoreFolder($ignorefolder) {
- $this->ignorefolders[]=$ignorefolder;
- }
-
- function _recurseFolders($path) {
- if ($this->showsearch) {
- echo '' . basename(realpath($path)) . '';
- }
-
- $files = scandir($path);
- static $s_count = 0;
-
- foreach ($files as $file) {
- if ($file == '.' || $file == '..') {
- continue;
- }
- $file_path = $path . '/' . $file;
- if (is_dir($file_path)) {
- if ($file != 'CVS' && $file != '.git' && !in_array($file_path, $this->ignorefolders)) {
- $this->_recurseFolders($file_path);
- }
- } elseif (preg_match('/simpletest(\/|\\\\)test.*\.php$/', $file_path)) {
-
- $s_count++;
- // OK, found: this shows as a 'Notice' for any 'simpletest/test*.php' file.
- $this->add(new FindFileNotice($file_path, 'Found unit test file, '. $s_count));
-
- // addTestFile: Unfortunately this doesn't return fail/success (bool).
- $this->addTestFile($file_path, true);
- }
- }
-
- if ($this->showsearch) {
- echo '
';
- }
- return $s_count;
- }
-
- function findTestFiles($dir) {
- if ($this->showsearch) {
- echo 'Searching folder: ' . realpath($dir) . '
';
- }
- $path = $dir;
- $count = $this->_recurseFolders($path);
- if ($count <= 0) {
- $this->add(new BadAutoGroupTest($path, 'Search complete. No unit test files found'));
- } else {
- $this->add(new AutoGroupTestNotice($path, 'Search complete. Total unit test files found: '. $count));
- }
- if ($this->showsearch) {
- echo '
';
- }
- return $count;
- }
-
- function addTestFile($file, $internalcall = false) {
-
- if ($this->showsearch) {
- if ($internalcall) {
- echo '' . basename($file) . '';
- } else {
- echo 'Adding test file: ' . realpath($file) . '
';
- }
- // Make sure that syntax errors show up suring the search, otherwise you often
- // get blank screens because evil people turn down error_reporting elsewhere.
- error_reporting(E_ALL);
- }
- if (!is_file($file) ){
- parent::add(new BadTest($file, 'Not a file or does not exist'));
- }
- parent::addFile($file);
- }
-}
-
-
-/* ======================================================================= */
-// get_class_ex: Insert spaces to prettify the class-name.
-function get_class_ex($object) {
- return preg_replace('/(.?)([A-Z])/', '${1} ${2}', get_class($object));
-}
-
-
-/**
- * A failing test base-class for when a test suite has NOT loaded properly.
- * See class, simple_test.php: BadGroupTest.
- * @package SimpleTestEx
- */
-class BadTest {
-
- var $label;
- var $error;
-
- function BadTest($label, $error) {
- $this->label = $label;
- $this->error = $error;
- }
-
- function getLabel() {
- return $this->label;
- }
-
- function run(&$reporter) {
- $reporter->paintGroupStart(basename(__FILE__), $this->getSize());
- $reporter->paintFail(get_class_ex($this) .' [' . $this->getLabel() .
- '] with error [' . $this->error . ']');
- $reporter->paintGroupEnd($this->getLabel());
- return $reporter->getStatus();
- }
-
- /**
- * @return int the number of test cases starting.
- */
- function getSize() {
- return 0;
- }
-}
-
-/**
- * An informational notice base-class for when a test suite is being processed.
- * See class, simple_test.php: BadGroupTest.
- * @package SimpleTestEx
- */
-class Notice {
-
- var $label;
- var $status;
-
- function Notice($label, $error) {
- $this->label = $label;
- $this->status = $error;
- }
-
- function getLabel() {
- return $this->label;
- }
-
- function run(&$reporter) {
- $reporter->paintGroupStart(basename(__FILE__), $this->getSize());
- $reporter->paintNotice(get_class_ex($this) .
- ' ['. $this->getLabel() .'] with status [' . $this->status . ']');
- $reporter->paintGroupEnd($this->getLabel());
- return $reporter->getStatus();
- }
-
- function getSize() {
- return 0;
- }
-}
-
-/**
- * A failing folder test for when the test-user specifies an invalid directory
- * (run.php?folder=woops).
- * @package SimpleTestEx
- */
-class BadFolderTest extends BadTest { }
-
-/**
- * A failing auto test for when no unit test files are found.
- * @package SimpleTestEx
- */
-class BadAutoGroupTest extends BadTest { }
-
-/**
- * Auto group test notices - 1. Search complete. 2. A test file has been found.
- * @package SimpleTestEx
- */
-class AutoGroupTestNotice extends Notice { }
-
-class FindFileNotice extends Notice { }
diff --git a/admin/tool/unittest/index.php b/admin/tool/unittest/index.php
deleted file mode 100644
index db0bbc73580..00000000000
--- a/admin/tool/unittest/index.php
+++ /dev/null
@@ -1,150 +0,0 @@
-.
-
-/**
- * Run the unit tests.
- *
- * @package tool
- * @subpackage unittest
- * @copyright © 2006 The Open University
- * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-define('NO_OUTPUT_BUFFERING', true);
-
-require(dirname(__FILE__) . '/../../../config.php');
-require_once($CFG->libdir.'/adminlib.php');
-require_once('simpletestlib.php');
-require_once('simpletestcoveragelib.php');
-require_once('ex_simple_test.php');
-require_once('ex_reporter.php');
-
-// page parameters
-$path = optional_param('path', null, PARAM_PATH);
-$showpasses = optional_param('showpasses', false, PARAM_BOOL);
-$codecoverage = optional_param('codecoverage', false, PARAM_BOOL);
-$showsearch = optional_param('showsearch', false, PARAM_BOOL);
-
-admin_externalpage_setup('toolsimpletest', '', array('showpasses'=>$showpasses, 'showsearch'=>$showsearch));
-
-raise_memory_limit(MEMORY_EXTRA);
-
-$unittest = true;
-
-global $UNITTEST;
-$UNITTEST = new stdClass();
-
-// This limit is the time allowed per individual test function. Please do not
-// increase this value. If you get a PHP time limit when running unit tests,
-// find the unit test which is running slowly, and either make it faster,
-// split it into multiple tests, or call set_time_limit within that test.
-define('TIME_ALLOWED_PER_UNIT_TEST', 60);
-
-// Print the header.
-$strtitle = get_string('unittests', 'tool_unittest');
-
-if (!is_null($path)) {
- //trim so user doesn't get an error if they include a space on the end of the path (ie by pasting path)
- $path = trim($path);
-
- // Turn off xmlstrictheaders during the unit test run.
- $origxmlstrictheaders = !empty($CFG->xmlstrictheaders);
- $CFG->xmlstrictheaders = false;
- echo $OUTPUT->header();
- $CFG->xmlstrictheaders = $origxmlstrictheaders;
- unset($origxmlstrictheaders);
-
- // Create the group of tests.
- $test = new autogroup_test_coverage($showsearch, true, $codecoverage, 'Moodle Unit Tests Code Coverage Report', 'unittest');
-
- // OU specific. We use the _nonproject folder for stuff we want to
- // keep in CVS, but which is not really relevant. It does no harm
- // to leave this here.
- $test->addIgnoreFolder($CFG->dirroot . '/_nonproject');
-
- // Make the reporter, which is what displays the results.
- $reporter = new ExHtmlReporter($showpasses);
-
- if ($showsearch) {
- echo $OUTPUT->heading('Searching for test cases');
- }
- flush();
-
- // Work out what to test.
- if (substr($path, 0, 1) == '/') {
- $path = substr($path, 1);
- }
- $path = $CFG->dirroot . '/' . $path;
- if (substr($path, -1) == '/') {
- $path = substr($path, 0, -1);
- }
- $displaypath = substr($path, strlen($CFG->dirroot) + 1);
- $ok = true;
- if (is_file($path)) {
- $test->addTestFile($path);
- } else if (is_dir($path)){
- $test->findTestFiles($path);
- } else {
- echo $OUTPUT->box(get_string('pathdoesnotexist', 'tool_unittest', $path), 'errorbox');
- $ok = false;
- }
-
- // If we have something to test, do it.
- if ($ok) {
- if ($path == $CFG->dirroot) {
- $title = get_string('moodleunittests', 'tool_unittest', get_string('all', 'tool_unittest'));
- } else {
- $title = get_string('moodleunittests', 'tool_unittest', $displaypath);
- }
- echo $OUTPUT->heading($title);
- $test->run($reporter);
- }
-
- $formheader = get_string('retest', 'tool_unittest');
-} else {
- $displaypath = '';
- echo $OUTPUT->header();
- $formheader = get_string('rununittests', 'tool_unittest');
-}
-// Print the form for adjusting options.
-echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
-echo $OUTPUT->heading($formheader);
-echo '';
-echo $OUTPUT->box_end();
-
-// Print link to latest code coverage for this report type
-if (is_null($path) || !$codecoverage) {
- moodle_coverage_reporter::print_link_to_latest('unittest');
-}
-
-// Footer.
-echo $OUTPUT->footer();
diff --git a/admin/tool/unittest/lang/en/tool_unittest.php b/admin/tool/unittest/lang/en/tool_unittest.php
deleted file mode 100644
index ce4bb3679c1..00000000000
--- a/admin/tool/unittest/lang/en/tool_unittest.php
+++ /dev/null
@@ -1,86 +0,0 @@
-.
-
-/**
- * Strings for component 'tool_unittest', language 'en', branch 'MOODLE_22_STABLE'
- *
- * This file contains strings that were previously located in lang/en/simpletest.php
- *
- * @package tool
- * @subpackage unittest
- * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-$string['addconfigprefix'] = 'Add prefix to config file';
-$string['all'] = 'ALL';
-$string['codecoverageanalysis'] = 'Perform code coverage analysis.';
-$string['codecoveragecompletereport'] = '(view code coverage complete report)';
-$string['codecoveragedisabled'] = 'Cannot enable code coverage in this server (missing xdebug extension).';
-$string['codecoveragelatestdetails'] = '(on {$a->date}, with {$a->files} files, {$a->percentage} covered)';
-$string['codecoveragelatestreport'] = 'view latest code coverage complete report';
-$string['confignonwritable'] = 'The file config.php is not writeable by the web server. Either change its permissions, or edit it with the appropriate user account, and add the following line before the closing php tag:
-$CFG->unittestprefix = \'tst_\' // Change tst_ to a prefix of your choice, different from $CFG->prefix';
-$string['coveredlines'] = 'Covered lines';
-$string['coveredpercentage'] = 'Overall code coverage';
-$string['dbtest'] = 'Functional DB tests';
-$string['deletingnoninsertedrecord'] = 'Trying to delete a record that was not inserted by these unit tests (id {$a->id} in table {$a->table}).';
-$string['deletingnoninsertedrecords'] = 'Trying to delete records that were not inserted by these unit tests (from table {$a->table}).';
-$string['droptesttables'] = 'Drop test tables';
-$string['exception'] = 'Exception';
-$string['executablelines'] = 'Executable lines';
-$string['fail'] = 'Fail';
-$string['ignorefile'] = 'Ignore tests in the file';
-$string['ignorethisfile'] = 'Re-run the tests ignoring this test file.';
-$string['installtesttables'] = 'Install test tables';
-$string['moodleunittests'] = 'Moodle unit tests: {$a}';
-$string['notice'] = 'Notice';
-$string['onlytest'] = 'Only run tests in';
-$string['othertestpages'] = 'Other test pages';
-$string['pass'] = 'Pass';
-$string['pathdoesnotexist'] = 'The path \'{$a}\' does not exist.';
-$string['pluginname'] = 'Unit tests';
-$string['prefix'] = 'Unit test tables prefix';
-$string['prefixnotset'] = 'The unit test database table prefix is not configured. Fill and submit this form to add it to config.php.';
-$string['reinstalltesttables'] = 'Reinstall test tables';
-$string['retest'] = 'Re-run the tests';
-$string['retestonlythisfile'] = 'Re-run only this test file.';
-$string['runall'] = 'Run the tests from all the test files.';
-$string['runat'] = 'Run at {$a}.';
-$string['runonlyfile'] = 'Run only the tests in this file';
-$string['runonlyfolder'] = 'Run only the tests in this folder';
-$string['runtests'] = 'Run tests';
-$string['rununittests'] = 'Run the unit tests';
-$string['showpasses'] = 'Show passes as well as fails.';
-$string['showsearch'] = 'Show the search for test files.';
-$string['skip'] = 'Skip';
-$string['stacktrace'] = 'Stack trace:';
-$string['summary'] = '{$a->run}/{$a->total} test cases complete: {$a->passes} passes, {$a->fails} fails and {$a->exceptions} exceptions.';
-$string['tablesnotsetup'] = 'Unit test tables are not yet built. Do you want to build them now?.';
-$string['testdboperations'] = 'Test database operations';
-$string['testtablescsvfileunwritable'] = 'The test tables CSV file is not writable ({$a->filename})';
-$string['testtablesneedupgrade'] = 'The test DB tables need to be upgraded. Do you wish to proceed with the upgrade now?';
-$string['testtablesok'] = 'The test DB tables were successfully installed.';
-$string['thorough'] = 'Run a thorough test (may be slow).';
-$string['timetakes'] = 'Time taken: {$a}.';
-$string['totallines'] = 'Total lines';
-$string['uncaughtexception'] = 'Uncaught exception [{$a->getMessage()}] in [{$a->getFile()}:{$a->getLine()}] TESTS ABORTED.';
-$string['uncoveredlines'] = 'Uncovered lines';
-$string['unittest:execute'] = 'Execute unit tests';
-$string['unittestprefixsetting'] = 'Unit test prefix: {$a->unittestprefix} (Edit config.php to modify this).';
-$string['unittests'] = 'Unit tests';
-$string['updatingnoninsertedrecord'] = 'Trying to update a record that was not inserted by these unit tests (id {$a->id} in table {$a->table}).';
-$string['version'] = 'Using SimpleTest version {$a}.';
diff --git a/admin/tool/unittest/settings.php b/admin/tool/unittest/settings.php
deleted file mode 100644
index ee3406a7e87..00000000000
--- a/admin/tool/unittest/settings.php
+++ /dev/null
@@ -1,29 +0,0 @@
-.
-
-/**
- * Unittest settings
- *
- * @package tool
- * @subpackage unittest
- * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-
-defined('MOODLE_INTERNAL') || die;
-
-$ADMIN->add('development', new admin_externalpage('toolsimpletest', get_string('pluginname', 'tool_unittest'), "$CFG->wwwroot/$CFG->admin/tool/unittest/index.php", 'tool/unittest:execute', true));
diff --git a/admin/tool/unittest/simpletestcoveragelib.php b/admin/tool/unittest/simpletestcoveragelib.php
deleted file mode 100644
index 306bf2941e7..00000000000
--- a/admin/tool/unittest/simpletestcoveragelib.php
+++ /dev/null
@@ -1,606 +0,0 @@
-.
-
-/**
- * Extend simpletest to support code coverage analysis
- *
- * This package contains a collection of classes that, extending standard simpletest
- * ones, provide code coverage analysis to already existing tests. Also there are some
- * utility functions designed to make the coverage control easier.
- *
- * @package tool
- * @subpackage unittest
- * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Includes
- */
-require_once($CFG->libdir.'/tablelib.php');
-
-require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/unittest/simpletestlib.php');
-require_once($CFG->dirroot . '/' . $CFG->admin . '/tool/unittest/ex_simple_test.php');
-
-require_once($CFG->libdir . '/spikephpcoverage/src/CoverageRecorder.php');
-require_once($CFG->libdir . '/spikephpcoverage/src/reporter/HtmlCoverageReporter.php');
-
-/**
- * AutoGroupTest class extension supporting code coverage
- *
- * This class extends AutoGroupTest to add the funcitionalities
- * necessary to run code coverage, allowing its activation and
- * specifying included / excluded files to be analysed
- *
- * @package moodlecore
- * @subpackage simpletestcoverage
- * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class autogroup_test_coverage extends AutoGroupTest {
-
- private $performcoverage; // boolean
- private $coveragename; // title of the coverage report
- private $coveragedir; // dir, relative to dataroot/coverage where the report will be saved
- private $includecoverage; // paths to be analysed by the coverage report
- private $excludecoverage; // paths to be excluded from the coverage report
-
- function __construct($showsearch, $test_name = null,
- $performcoverage = false, $coveragename = 'Code Coverage Report',
- $coveragedir = 'report') {
- parent::__construct($showsearch, $test_name);
- $this->performcoverage = $performcoverage;
- $this->coveragename = $coveragename;
- $this->coveragedir = $coveragedir;
- $this->includecoverage = array();
- $this->excludecoverage = array();
- }
-
- public function addTestFile($file, $internalcall = false) {
- global $CFG;
-
- if ($this->performcoverage) {
- $refinfo = moodle_reflect_file($file);
- require_once($file);
- if ($refinfo->classes) {
- foreach ($refinfo->classes as $class) {
- $reflection = new ReflectionClass($class);
- if ($staticprops = $reflection->getStaticProperties()) {
- if (isset($staticprops['includecoverage']) && is_array($staticprops['includecoverage'])) {
- foreach ($staticprops['includecoverage'] as $toinclude) {
- $this->add_coverage_include_path($toinclude);
- }
- }
- if (isset($staticprops['excludecoverage']) && is_array($staticprops['excludecoverage'])) {
- foreach ($staticprops['excludecoverage'] as $toexclude) {
- $this->add_coverage_exclude_path($toexclude);
- }
- }
- }
- }
- // Automatically add the test dir itself, so nothing will be covered there
- $this->add_coverage_exclude_path(dirname($file));
- }
- }
- parent::addTestFile($file, $internalcall);
- }
-
- public function add_coverage_include_path($path) {
- global $CFG;
-
- $path = $CFG->dirroot . '/' . $path; // Convert to full path
- if (!in_array($path, $this->includecoverage)) {
- array_push($this->includecoverage, $path);
- }
- }
-
- public function add_coverage_exclude_path($path) {
- global $CFG;
-
- $path = $CFG->dirroot . '/' . $path; // Convert to full path
- if (!in_array($path, $this->excludecoverage)) {
- array_push($this->excludecoverage, $path);
- }
- }
-
- /**
- * Run the autogroup_test_coverage using one internally defined code coverage reporter
- * automatically generating the coverage report. Only supports one instrumentation
- * to be executed and reported.
- */
- public function run($simpletestreporter) {
- global $CFG;
-
- if (moodle_coverage_recorder::can_run_codecoverage() && $this->performcoverage) {
- // Testing with coverage
- $covreporter = new moodle_coverage_reporter($this->coveragename, $this->coveragedir);
- $covrecorder = new moodle_coverage_recorder($covreporter);
- $covrecorder->setIncludePaths($this->includecoverage);
- $covrecorder->setExcludePaths($this->excludecoverage);
- $covrecorder->start_instrumentation();
- parent::run($simpletestreporter);
- $covrecorder->stop_instrumentation();
- set_time_limit(60*10); // it may take a long time to generate the report
- $covrecorder->generate_report();
- moodle_coverage_reporter::print_summary_info(basename($this->coveragedir));
- } else {
- // Testing without coverage
- parent::run($simpletestreporter);
- }
- }
-
- /**
- * Run the autogroup_test_coverage tests using one externally defined code coverage reporter
- * allowing further process of coverage data once tests are over. Supports multiple
- * instrumentations (code coverage gathering sessions) to be executed.
- */
- public function run_with_external_coverage($simpletestreporter, $covrecorder) {
-
- if (moodle_coverage_recorder::can_run_codecoverage() && $this->performcoverage) {
- $covrecorder->setIncludePaths($this->includecoverage);
- $covrecorder->setExcludePaths($this->excludecoverage);
- $covrecorder->start_instrumentation();
- parent::run($simpletestreporter);
- $covrecorder->stop_instrumentation();
- } else {
- // Testing without coverage
- parent::run($simpletestreporter);
- }
- }
-}
-
-/**
- * CoverageRecorder class extension supporting multiple
- * coverage instrumentations to be accumulated
- *
- * This class extends CoverageRecorder class in order to
- * support multimple xdebug code coverage sessions to be
- * executed and get acummulated info about all them in order
- * to produce one unique report (default CoverageRecorder
- * resets info on each instrumentation (coverage session)
- *
- * @package moodlecore
- * @subpackage simpletestcoverage
- * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class moodle_coverage_recorder extends CoverageRecorder {
-
- public function __construct($reporter='new moodle_coverage_reporter()') {
- parent::__construct(array(), array(), $reporter);
- }
-
- /**
- * Stop gathering coverage data, saving it for later reporting
- */
- public function stop_instrumentation() {
- if(extension_loaded("xdebug")) {
- $lastcoveragedata = xdebug_get_code_coverage(); // Get last instrumentation coverage data
- xdebug_stop_code_coverage(); // Stop code coverage
- $this->coverageData = self::merge_coverage_data($this->coverageData, $lastcoveragedata); // Append lastcoveragedata
- $this->logger->debug("[moodle_coverage_recorder::stopInstrumentation()] Code coverage: " . print_r($this->coverageData, true),
- __FILE__, __LINE__);
- return true;
- } else {
- $this->logger->critical("[moodle_coverage_recorder::stopInstrumentation()] Xdebug not loaded.", __FILE__, __LINE__);
- }
- return false;
- }
-
- /**
- * Start gathering coverage data
- */
- public function start_instrumentation() {
- $this->startInstrumentation(); /// Simple lowercase wrap over Spike function
- }
-
- /**
- * Generate the code coverage report
- */
- public function generate_report() {
- $this->generateReport(); /// Simple lowercase wrap over Spike function
- }
-
- /**
- * Determines if the server is able to run code coverage analysis
- *
- * @return bool
- */
- static public function can_run_codecoverage() {
- // Only req is xdebug loaded. PEAR XML is already in place and available
- if(!extension_loaded("xdebug")) {
- return false;
- }
- return true;
- }
-
- /**
- * Merge two collections of complete code coverage data
- */
- protected static function merge_coverage_data($cov1, $cov2) {
-
- $result = array();
-
- // protection against empty coverage collections
- if (!is_array($cov1)) {
- $cov1 = array();
- }
- if (!is_array($cov2)) {
- $cov2 = array();
- }
-
- // Get all the files used in both coverage datas
- $files = array_unique(array_merge(array_keys($cov1), array_keys($cov2)));
-
- // Iterate, getting results
- foreach($files as $file) {
- // If file exists in both coverages, let's merge their lines
- if (array_key_exists($file, $cov1) && array_key_exists($file, $cov2)) {
- $result[$file] = self::merge_lines_coverage_data($cov1[$file], $cov2[$file]);
- // Only one of the coverages has the file
- } else if (array_key_exists($file, $cov1)) {
- $result[$file] = $cov1[$file];
- } else {
- $result[$file] = $cov2[$file];
- }
- }
- return $result;
- }
-
- /**
- * Merge two collections of lines of code coverage data belonging to the same file
- *
- * Merge algorithm obtained from Phing: http://phing.info
- */
- protected static function merge_lines_coverage_data($lines1, $lines2) {
-
- $result = array();
-
- reset($lines1);
- reset($lines2);
-
- while (current($lines1) && current($lines2)) {
- $linenr1 = key($lines1);
- $linenr2 = key($lines2);
-
- if ($linenr1 < $linenr2) {
- $result[$linenr1] = current($lines1);
- next($lines1);
- } else if ($linenr2 < $linenr1) {
- $result[$linenr2] = current($lines2);
- next($lines2);
- } else {
- if (current($lines1) < 0) {
- $result[$linenr2] = current($lines2);
- } else if (current($lines2) < 0) {
- $result[$linenr2] = current($lines1);
- } else {
- $result[$linenr2] = current($lines1) + current($lines2);
- }
- next($lines1);
- next($lines2);
- }
- }
-
- while (current($lines1)) {
- $result[key($lines1)] = current($lines1);
- next($lines1);
- }
-
- while (current($lines2)) {
- $result[key($lines2)] = current($lines2);
- next($lines2);
- }
-
- return $result;
- }
-}
-
-/**
- * HtmlCoverageReporter class extension supporting Moodle customizations
- *
- * This class extends the HtmlCoverageReporter class in order to
- * implement Moodle look and feel, inline reporting after executing
- * unit tests, proper linking and other tweaks here and there.
- *
- * @package moodlecore
- * @subpackage simpletestcoverage
- * @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class moodle_coverage_reporter extends HtmlCoverageReporter {
-
- public function __construct($heading='Coverage Report', $dir='report') {
- global $CFG;
- parent::__construct($heading, '', $CFG->dataroot . '/codecoverage/' . $dir);
- }
-
- /**
- * Writes one row in the index.html table to display filename
- * and coverage recording.
- *
- * Overrided to transform names and links to shorter format
- *
- * @param $fileLink link to html details file.
- * @param $realFile path to real PHP file.
- * @param $fileCoverage Coverage recording for that file.
- * @return string HTML code for a single row.
- * @access protected
- */
- protected function writeIndexFileTableRow($fileLink, $realFile, $fileCoverage) {
-
- global $CFG;
-
- $fileLink = str_replace($CFG->dirroot, '', $fileLink);
- $realFile = str_replace($CFG->dirroot, '', $realFile);
-
- return parent::writeIndexFileTableRow($fileLink, $realFile, $fileCoverage);;
- }
-
- /**
- * Mark a source code file based on the coverage data gathered
- *
- * Overrided to transform names and links to shorter format
- *
- * @param $phpFile Name of the actual source file
- * @param $fileLink Link to the html mark-up file for the $phpFile
- * @param &$coverageLines Coverage recording for $phpFile
- * @return boolean FALSE on failure
- * @access protected
- */
- protected function markFile($phpFile, $fileLink, &$coverageLines) {
- global $CFG;
-
- $fileLink = str_replace($CFG->dirroot, '', $fileLink);
-
- return parent::markFile($phpFile, $fileLink, $coverageLines);
- }
-
-
- /**
- * Update the grand totals
- *
- * Overrided to avoid the call to recordFileCoverageInfo()
- * because it has been already executed by writeIndexFile() and
- * cause files to be duplicated in the fileCoverage property
- */
- protected function updateGrandTotals(&$coverageCounts) {
- $this->grandTotalLines += $coverageCounts['total'];
- $this->grandTotalCoveredLines += $coverageCounts['covered'];
- $this->grandTotalUncoveredLines += $coverageCounts['uncovered'];
- }
-
- /**
- * Generate the static report
- *
- * Overrided to generate the serialised object to be displayed inline
- * with the test results.
- *
- * @param &$data Reference to Coverage Data
- */
- public function generateReport(&$data) {
- parent::generateReport($data);
-
- // head data
- $data = new stdClass();
- $data->time = time();
- $data->title = $this->heading;
- $data->output = $this->outputDir;
-
- // summary data
- $data->totalfiles = $this->grandTotalFiles;
- $data->totalln = $this->grandTotalLines;
- $data->totalcoveredln = $this->grandTotalCoveredLines;
- $data->totaluncoveredln = $this->grandTotalUncoveredLines;
- $data->totalpercentage = $this->getGrandCodeCoveragePercentage();
-
- // file details data
- $data->coveragedetails = $this->fileCoverage;
-
- // save serialised object
- file_put_contents($data->output . '/codecoverage.ser', serialize($data));
- }
-
- /**
- * Return the html contents for the summary for the last execution of the
- * given test type
- *
- * @param string $type of the test to return last execution summary (dbtest|unittest)
- * @return string html contents of the summary
- */
- static public function get_summary_info($type) {
- global $CFG, $OUTPUT;
-
- $serfilepath = $CFG->dataroot . '/codecoverage/' . $type . '/codecoverage.ser';
- if (file_exists($serfilepath) && is_readable($serfilepath)) {
- if ($data = unserialize(file_get_contents($serfilepath))) {
- // return one table with all the totals (we avoid individual file results here)
- $result = '';
- $table = new html_table();
- $table->align = array('right', 'left');
- $table->tablealign = 'center';
- $table->attributes['class'] = 'codecoveragetable';
- $table->id = 'codecoveragetable_' . $type;
- $table->rowclasses = array('label', 'value');
- $table->data = array(
- array(get_string('date') , userdate($data->time)),
- array(get_string('files') , format_float($data->totalfiles, 0)),
- array(get_string('totallines', 'tool_unittest') , format_float($data->totalln, 0)),
- array(get_string('executablelines', 'tool_unittest') , format_float($data->totalcoveredln + $data->totaluncoveredln, 0)),
- array(get_string('coveredlines', 'tool_unittest') , format_float($data->totalcoveredln, 0)),
- array(get_string('uncoveredlines', 'tool_unittest') , format_float($data->totaluncoveredln, 0)),
- array(get_string('coveredpercentage', 'tool_unittest'), format_float($data->totalpercentage, 2) . '%')
- );
-
- $url = $CFG->wwwroot . '/'.$CFG->admin.'/tool/unittest/coveragefile.php/' . $type . '/index.html';
- $result .= $OUTPUT->heading($data->title, 3, 'main codecoverageheading');
- $result .= $OUTPUT->heading('' . get_string('codecoveragecompletereport', 'tool_unittest') . '', 4, 'main codecoveragelink');
- $result .= html_writer::table($table);
-
- return $OUTPUT->box($result, 'generalbox boxwidthwide boxaligncenter codecoveragebox', '', true);
- }
- }
- return false;
- }
-
- /**
- * Print the html contents for the summary for the last execution of the
- * given test type
- *
- * @param string $type of the test to return last execution summary (dbtest|unittest)
- * @return string html contents of the summary
- */
- static public function print_summary_info($type) {
- echo self::get_summary_info($type);
- }
-
- /**
- * Return the html code needed to browse latest code coverage complete report of the
- * given test type
- *
- * @param string $type of the test to return last execution summary (dbtest|unittest)
- * @return string html contents of the summary
- */
- static public function get_link_to_latest($type) {
- global $CFG, $OUTPUT;
-
- $serfilepath = $CFG->dataroot . '/codecoverage/' . $type . '/codecoverage.ser';
- if (file_exists($serfilepath) && is_readable($serfilepath)) {
- if ($data = unserialize(file_get_contents($serfilepath))) {
- $info = new stdClass();
- $info->date = userdate($data->time);
- $info->files = format_float($data->totalfiles, 0);
- $info->percentage = format_float($data->totalpercentage, 2) . '%';
-
- $strlatestreport = get_string('codecoveragelatestreport', 'tool_unittest');
- $strlatestdetails = get_string('codecoveragelatestdetails', 'tool_unittest', $info);
-
- // return one link to latest complete report
- $result = '';
- $url = $CFG->wwwroot . '/'.$CFG->admin.'/tool/unittest/coveragefile.php/' . $type . '/index.html';
- $result .= $OUTPUT->heading('' . $strlatestreport . '', 3, 'main codecoveragelink');
- $result .= $OUTPUT->heading($strlatestdetails, 4, 'main codecoveragedetails');
- return $OUTPUT->box($result, 'generalbox boxwidthwide boxaligncenter codecoveragebox', '', true);
- }
- }
- return false;
- }
-
- /**
- * Print the html code needed to browse latest code coverage complete report of the
- * given test type
- *
- * @param string $type of the test to return last execution summary (dbtest|unittest)
- * @return string html contents of the summary
- */
- static public function print_link_to_latest($type) {
- echo self::get_link_to_latest($type);
- }
-}
-
-
-/**
- * Return information about classes and functions
- *
- * This function will parse any PHP file, extracting information about the
- * classes and functions defined within it, providing "File Reflection" as
- * PHP standard reflection classes don't support that.
- *
- * The idea and the code has been obtained from the Zend Framework Reflection API
- * http://framework.zend.com/manual/en/zend.reflection.reference.html
- *
- * Usage: $ref_file = moodle_reflect_file($file);
- *
- * @param string $file full path to the php file to introspect
- * @return object object with both 'classes' and 'functions' properties
- */
-function moodle_reflect_file($file) {
-
- $contents = file_get_contents($file);
- $tokens = token_get_all($contents);
-
- $functionTrapped = false;
- $classTrapped = false;
- $openBraces = 0;
-
- $classes = array();
- $functions = array();
-
- foreach ($tokens as $token) {
- /*
- * Tokens are characters representing symbols or arrays
- * representing strings. The keys/values in the arrays are
- *
- * - 0 => token id,
- * - 1 => string,
- * - 2 => line number
- *
- * Token ID's are explained here:
- * http://www.php.net/manual/en/tokens.php.
- */
-
- if (is_array($token)) {
- $type = $token[0];
- $value = $token[1];
- $lineNum = $token[2];
- } else {
- // It's a symbol
- // Maintain the count of open braces
- if ($token == '{') {
- $openBraces++;
- } else if ($token == '}') {
- $openBraces--;
- }
-
- continue;
- }
-
- switch ($type) {
- // Name of something
- case T_STRING:
- if ($functionTrapped) {
- $functions[] = $value;
- $functionTrapped = false;
- } elseif ($classTrapped) {
- $classes[] = $value;
- $classTrapped = false;
- }
- continue;
-
- // Functions
- case T_FUNCTION:
- if ($openBraces == 0) {
- $functionTrapped = true;
- }
- break;
-
- // Classes
- case T_CLASS:
- $classTrapped = true;
- break;
-
- // Default case: do nothing
- default:
- break;
- }
- }
-
- return (object)array('classes' => $classes, 'functions' => $functions);
-}
diff --git a/admin/tool/unittest/simpletestlib.php b/admin/tool/unittest/simpletestlib.php
deleted file mode 100644
index e60faf73ac5..00000000000
--- a/admin/tool/unittest/simpletestlib.php
+++ /dev/null
@@ -1,1371 +0,0 @@
-.
-
-/**
- * Utility functions to make unit testing easier.
- *
- * These functions, particularly the the database ones, are quick and
- * dirty methods for getting things done in test cases. None of these
- * methods should be used outside test code.
- *
- * Major Contirbutors
- * - T.J.Hunt@open.ac.uk
- *
- * @package tool
- * @subpackage unittest
- * @copyright © 2006 The Open University
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-/**
- * Includes
- */
-require_once($CFG->libdir . '/simpletestlib/simpletest.php');
-require_once($CFG->libdir . '/simpletestlib/unit_tester.php');
-require_once($CFG->libdir . '/simpletestlib/expectation.php');
-require_once($CFG->libdir . '/simpletestlib/reporter.php');
-require_once($CFG->libdir . '/simpletestlib/web_tester.php');
-require_once($CFG->libdir . '/simpletestlib/mock_objects.php');
-
-/**
- * Recursively visit all the files in the source tree. Calls the callback
- * function with the pathname of each file found.
- *
- * @param $path the folder to start searching from.
- * @param $callback the function to call with the name of each file found.
- * @param $fileregexp a regexp used to filter the search (optional).
- * @param $exclude If true, pathnames that match the regexp will be ingored. If false,
- * only files that match the regexp will be included. (default false).
- * @param array $ignorefolders will not go into any of these folders (optional).
- */
-function recurseFolders($path, $callback, $fileregexp = '/.*/', $exclude = false, $ignorefolders = array()) {
- $files = scandir($path);
-
- foreach ($files as $file) {
- $filepath = $path .'/'. $file;
- if (strpos($file, '.') === 0) {
- /// Don't check hidden files.
- continue;
- } else if (is_dir($filepath)) {
- if (!in_array($filepath, $ignorefolders)) {
- recurseFolders($filepath, $callback, $fileregexp, $exclude, $ignorefolders);
- }
- } else if ($exclude xor preg_match($fileregexp, $filepath)) {
- call_user_func($callback, $filepath);
- }
- }
-}
-
-/**
- * An expectation for comparing strings ignoring whitespace.
- *
- * @package moodlecore
- * @subpackage simpletestex
- * @copyright © 2006 The Open University
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class IgnoreWhitespaceExpectation extends SimpleExpectation {
- var $expect;
-
- function __construct($content, $message = '%s') {
- parent::__construct($message);
- $this->expect=$this->normalise($content);
- }
-
- function test($ip) {
- return $this->normalise($ip)==$this->expect;
- }
-
- function normalise($text) {
- return preg_replace('/\s+/m',' ',trim($text));
- }
-
- function testMessage($ip) {
- return "Input string [$ip] doesn't match the required value.";
- }
-}
-
-/**
- * An Expectation that two arrays contain the same list of values.
- *
- * @package moodlecore
- * @subpackage simpletestex
- * @copyright © 2006 The Open University
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class ArraysHaveSameValuesExpectation extends SimpleExpectation {
- var $expect;
-
- function __construct($expected, $message = '%s') {
- parent::__construct($message);
- if (!is_array($expected)) {
- trigger_error('Attempt to create an ArraysHaveSameValuesExpectation ' .
- 'with an expected value that is not an array.');
- }
- $this->expect = $this->normalise($expected);
- }
-
- function test($actual) {
- return $this->normalise($actual) == $this->expect;
- }
-
- function normalise($array) {
- sort($array);
- return $array;
- }
-
- function testMessage($actual) {
- return 'Array [' . implode(', ', $actual) .
- '] does not contain the expected list of values [' . implode(', ', $this->expect) . '].';
- }
-}
-
-
-/**
- * An Expectation that compares to objects, and ensures that for every field in the
- * expected object, there is a key of the same name in the actual object, with
- * the same value. (The actual object may have other fields to, but we ignore them.)
- *
- * @package moodlecore
- * @subpackage simpletestex
- * @copyright © 2006 The Open University
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class CheckSpecifiedFieldsExpectation extends SimpleExpectation {
- var $expect;
-
- function __construct($expected, $message = '%s') {
- parent::__construct($message);
- if (!is_object($expected)) {
- trigger_error('Attempt to create a CheckSpecifiedFieldsExpectation ' .
- 'with an expected value that is not an object.');
- }
- $this->expect = $expected;
- }
-
- function test($actual) {
- foreach ($this->expect as $key => $value) {
- if (isset($value) && isset($actual->$key) && $actual->$key == $value) {
- // OK
- } else if (is_null($value) && is_null($actual->$key)) {
- // OK
- } else {
- return false;
- }
- }
- return true;
- }
-
- function testMessage($actual) {
- $mismatches = array();
- foreach ($this->expect as $key => $value) {
- if (isset($value) && isset($actual->$key) && $actual->$key == $value) {
- // OK
- } else if (is_null($value) && is_null($actual->$key)) {
- // OK
- } else if (!isset($actual->$key)) {
- $mismatches[] = $key . ' (expected [' . $value . '] but was missing.';
- } else {
- $mismatches[] = $key . ' (expected [' . $value . '] got [' . $actual->$key . '].';
- }
- }
- return 'Actual object does not have all the same fields with the same values as the expected object (' .
- implode(', ', $mismatches) . ').';
- }
-}
-
-abstract class XMLStructureExpectation extends SimpleExpectation {
- /**
- * Parse a string as XML and return a DOMDocument;
- * @param $html
- * @return unknown_type
- */
- protected function load_xml($html) {
- $prevsetting = libxml_use_internal_errors(true);
- $parser = new DOMDocument();
- if (!$parser->loadXML('' . $html . '')) {
- $parser = new DOMDocument();
- }
- libxml_clear_errors();
- libxml_use_internal_errors($prevsetting);
- return $parser;
- }
-
- function testMessage($html) {
- $parsererrors = $this->load_xml($html);
- if (is_array($parsererrors)) {
- foreach ($parsererrors as $key => $message) {
- $parsererrors[$key] = $message->message;
- }
- return 'Could not parse XML [' . $html . '] errors were [' .
- implode('], [', $parsererrors) . ']';
- }
- return $this->customMessage($html);
- }
-}
-/**
- * An Expectation that looks to see whether some HMTL contains a tag with a certain attribute.
- *
- * @copyright 2009 Tim Hunt
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class ContainsTagWithAttribute extends XMLStructureExpectation {
- protected $tag;
- protected $attribute;
- protected $value;
-
- function __construct($tag, $attribute, $value, $message = '%s') {
- parent::__construct($message);
- $this->tag = $tag;
- $this->attribute = $attribute;
- $this->value = $value;
- }
-
- function test($html) {
- $parser = $this->load_xml($html);
- if (is_array($parser)) {
- return false;
- }
- $list = $parser->getElementsByTagName($this->tag);
-
- foreach ($list as $node) {
- if ($node->attributes->getNamedItem($this->attribute)->nodeValue === (string) $this->value) {
- return true;
- }
- }
- return false;
- }
-
- function customMessage($html) {
- return 'Content [' . $html . '] does not contain the tag [' .
- $this->tag . '] with attribute [' . $this->attribute . '="' . $this->value . '"].';
- }
-}
-
-/**
- * An Expectation that looks to see whether some HMTL contains a tag with an array of attributes.
- * All attributes must be present and their values must match the expected values.
- * A third parameter can be used to specify attribute=>value pairs which must not be present in a positive match.
- *
- * @copyright 2009 Nicolas Connault
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class ContainsTagWithAttributes extends XMLStructureExpectation {
- /**
- * @var string $tag The name of the Tag to search
- */
- protected $tag;
- /**
- * @var array $expectedvalues An associative array of parameters, all of which must be matched
- */
- protected $expectedvalues = array();
- /**
- * @var array $forbiddenvalues An associative array of parameters, none of which must be matched
- */
- protected $forbiddenvalues = array();
- /**
- * @var string $failurereason The reason why the test failed: nomatch or forbiddenmatch
- */
- protected $failurereason = 'nomatch';
-
- function __construct($tag, $expectedvalues, $forbiddenvalues=array(), $message = '%s') {
- parent::__construct($message);
- $this->tag = $tag;
- $this->expectedvalues = $expectedvalues;
- $this->forbiddenvalues = $forbiddenvalues;
- }
-
- function test($html) {
- $parser = $this->load_xml($html);
- if (is_array($parser)) {
- return false;
- }
-
- $list = $parser->getElementsByTagName($this->tag);
- $foundamatch = false;
-
- // Iterating through inputs
- foreach ($list as $node) {
- if (empty($node->attributes) || !is_a($node->attributes, 'DOMNamedNodeMap')) {
- continue;
- }
-
- // For the current expected attribute under consideration, check that values match
- $allattributesmatch = true;
-
- foreach ($this->expectedvalues as $expectedattribute => $expectedvalue) {
- if ($node->getAttribute($expectedattribute) === '' && $expectedvalue !== '') {
- $this->failurereason = 'nomatch';
- continue 2; // Skip this tag, it doesn't have all the expected attributes
- }
- if ($node->getAttribute($expectedattribute) !== (string) $expectedvalue) {
- $allattributesmatch = false;
- $this->failurereason = 'nomatch';
- }
- }
-
- if ($allattributesmatch) {
- $foundamatch = true;
-
- // Now make sure this node doesn't have any of the forbidden attributes either
- $nodeattrlist = $node->attributes;
-
- foreach ($nodeattrlist as $domattrname => $domattr) {
- if (array_key_exists($domattrname, $this->forbiddenvalues) && $node->getAttribute($domattrname) === (string) $this->forbiddenvalues[$domattrname]) {
- $this->failurereason = "forbiddenmatch:$domattrname:" . $node->getAttribute($domattrname);
- $foundamatch = false;
- }
- }
- }
- }
-
- return $foundamatch;
- }
-
- function customMessage($html) {
- $output = 'Content [' . $html . '] ';
-
- if (preg_match('/forbiddenmatch:(.*):(.*)/', $this->failurereason, $matches)) {
- $output .= "contains the tag $this->tag with the forbidden attribute=>value pair: [$matches[1]=>$matches[2]]";
- } else if ($this->failurereason == 'nomatch') {
- $output .= 'does not contain the tag [' . $this->tag . '] with attributes [';
- foreach ($this->expectedvalues as $var => $val) {
- $output .= "$var=\"$val\" ";
- }
- $output = rtrim($output);
- $output .= '].';
- }
-
- return $output;
- }
-}
-
-/**
- * An Expectation that looks to see whether some HMTL contains a tag with an array of attributes.
- * All attributes must be present and their values must match the expected values.
- * A third parameter can be used to specify attribute=>value pairs which must not be present in a positive match.
- *
- * @copyright 2010 The Open University
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class ContainsSelectExpectation extends XMLStructureExpectation {
- /**
- * @var string $tag The name of the Tag to search
- */
- protected $name;
- /**
- * @var array $expectedvalues An associative array of parameters, all of which must be matched
- */
- protected $choices;
- /**
- * @var array $forbiddenvalues An associative array of parameters, none of which must be matched
- */
- protected $selected;
- /**
- * @var string $failurereason The reason why the test failed: nomatch or forbiddenmatch
- */
- protected $enabled;
-
- function __construct($name, $choices, $selected = null, $enabled = null, $message = '%s') {
- parent::__construct($message);
- $this->name = $name;
- $this->choices = $choices;
- $this->selected = $selected;
- $this->enabled = $enabled;
- }
-
- function test($html) {
- $parser = $this->load_xml($html);
- if (is_array($parser)) {
- return false;
- }
-
- $list = $parser->getElementsByTagName('select');
-
- // Iterating through inputs
- foreach ($list as $node) {
- if (empty($node->attributes) || !is_a($node->attributes, 'DOMNamedNodeMap')) {
- continue;
- }
-
- if ($node->getAttribute('name') != $this->name) {
- continue;
- }
-
- if ($this->enabled === true && $node->getAttribute('disabled')) {
- continue;
- } else if ($this->enabled === false && $node->getAttribute('disabled') != 'disabled') {
- continue;
- }
-
- $options = $node->getElementsByTagName('option');
- reset($this->choices);
- foreach ($options as $option) {
- if ($option->getAttribute('value') != key($this->choices)) {
- continue 2;
- }
- if ($option->firstChild->wholeText != current($this->choices)) {
- continue 2;
- }
- if ($option->getAttribute('value') === $this->selected &&
- !$option->hasAttribute('selected')) {
- continue 2;
- }
- next($this->choices);
- }
- if (current($this->choices) !== false) {
- // The HTML did not contain all the choices.
- return false;
- }
- return true;
- }
- return false;
- }
-
- function customMessage($html) {
- if ($this->enabled === true) {
- $state = 'an enabled';
- } else if ($this->enabled === false) {
- $state = 'a disabled';
- } else {
- $state = 'a';
- }
- $output = 'Content [' . $html . '] does not contain ' . $state .
- '