resel.icon.src = result.icon;
resel.a.href = result.link;
resel.namespan.innerHTML = result.name;
+ if (!parseInt(result.visible, 10)) {
+ resel.a.className = 'dimmed';
+ }
if (result.groupingname) {
resel.groupingspan.innerHTML = '(' + result.groupingname + ')';
resel.icon.src = result.icon;
resel.a.href = result.link;
resel.namespan.innerHTML = result.name;
+ if (!parseInt(result.visible, 10)) {
+ resel.a.className = 'dimmed';
+ }
if (result.groupingname) {
resel.groupingspan.innerHTML = '(' + result.groupingname + ')';
throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
}
+ // Note the section visibility
+ $visible = get_fast_modinfo($this->course)->get_section_info($this->section)->visible;
+
$DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id));
// Rebuild the course cache after update action
rebuild_course_cache($this->course->id, true);
$sectionid = course_add_cm_to_section($this->course, $this->cm->id, $this->section);
- set_coursemodule_visible($this->cm->id, true);
+ set_coursemodule_visible($this->cm->id, $visible);
+ if (!$visible) {
+ $DB->set_field('course_modules', 'visibleold', 1, array('id' => $this->cm->id));
+ }
// retrieve the final info about this module.
$info = get_fast_modinfo($this->course);
delete_course_module($this->cm->id);
throw new moodle_exception('errorcreatingactivity', 'moodle', '', $this->module->name);
}
- $mod = $info->cms[$this->cm->id];
+ $mod = $info->get_cm($this->cm->id);
$mod->groupmodelink = $this->cm->groupmodelink;
$mod->groupmode = $this->cm->groupmode;
$resp->elementid = 'module-'.$mod->id;
$resp->commands = make_editing_buttons($mod, true, true, 0, $mod->sectionnum);
$resp->onclick = $mod->get_on_click();
+ $resp->visible = $mod->visible;
// if using groupings, then display grouping name
if (!empty($mod->groupingid) && has_capability('moodle/course:managegroups', $this->context)) {
array(0=>get_string('completiondisabled','completion'), 1=>get_string('completionenabled','completion')));
$mform->setDefault('enablecompletion', $courseconfig->enablecompletion);
- $mform->addElement('checkbox', 'completionstartonenrol', get_string('completionstartonenrol', 'completion'));
+ $mform->addElement('advcheckbox', 'completionstartonenrol', get_string('completionstartonenrol', 'completion'));
$mform->setDefault('completionstartonenrol', $courseconfig->completionstartonenrol);
$mform->disabledIf('completionstartonenrol', 'enablecompletion', 'eq', 0);
} else {
$mform->addHelpButton('groupingid', 'groupingsection', 'group');
}
- // Date and time conditions
+ // Available from/to defaults to midnight because then the display
+ // will be nicer where it tells users when they can access it (it
+ // shows only the date and not time).
+ $date = usergetdate(time());
+ $midnight = make_timestamp($date['year'], $date['mon'], $date['mday']);
+
+ // Date and time conditions.
$mform->addElement('date_time_selector', 'availablefrom',
- get_string('availablefrom', 'condition'), array('optional' => true));
+ get_string('availablefrom', 'condition'),
+ array('optional' => true, 'defaulttime' => $midnight));
$mform->addElement('date_time_selector', 'availableuntil',
- get_string('availableuntil', 'condition'), array('optional' => true));
+ get_string('availableuntil', 'condition'),
+ array('optional' => true, 'defaulttime' => $midnight));
// Conditions based on grades
$gradeoptions = array();
}
$o.= html_writer::end_tag('div');
- $o .= $this->section_availability_message($section);
+ $o .= $this->section_availability_message($section,
+ has_capability('moodle/course:viewhiddensections', $context));
return $o;
}
$o.= html_writer::end_tag('div');
$o.= $this->section_activity_summary($section, $course, null);
- $o.= $this->section_availability_message($section);
+ $context = context_course::instance($course->id);
+ $o .= $this->section_availability_message($section,
+ has_capability('moodle/course:viewhiddensections', $context));
$o .= html_writer::end_tag('div');
$o .= html_writer::end_tag('li');
}
/**
- * If section is not visible to current user, display the message about that
- * ('Not available until...', that sort of thing). Otherwise, returns blank.
+ * If section is not visible, display the message about that ('Not available
+ * until...', that sort of thing). Otherwise, returns blank.
+ *
+ * For users with the ability to view hidden sections, it shows the
+ * information even though you can view the section and also may include
+ * slightly fuller information (so that teachers can tell when sections
+ * are going to be unavailable etc). This logic is the same as for
+ * activities.
*
* @param stdClass $section The course_section entry from DB
+ * @param bool $canviewhidden True if user can view hidden sections
* @return string HTML to output
*/
- protected function section_availability_message($section) {
+ protected function section_availability_message($section, $canviewhidden) {
+ global $CFG;
$o = '';
- if (!$section->uservisible || $section->availableinfo) {
+ if (!$section->uservisible) {
$o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
- if (!empty($section->availableinfo)) {
- $o .= $section->availableinfo;
- } else {
- $o .= get_string('notavailable');
- }
+ // Note: We only get to this function if availableinfo is non-empty,
+ // so there is definitely something to print.
+ $o .= $section->availableinfo;
$o .= html_writer::end_tag('div');
+ } else if ($canviewhidden && !empty($CFG->enableavailability) && $section->visible) {
+ $ci = new condition_info_section($section);
+ $fullinfo = $ci->get_full_information();
+ if ($fullinfo) {
+ $o .= html_writer::start_tag('div', array('class' => 'availabilityinfo'));
+ $o .= get_string(
+ ($section->showavailability ? 'userrestriction_visible' : 'userrestriction_hidden'),
+ 'condition', $fullinfo);
+ $o .= html_writer::end_tag('div');
+ }
}
return $o;
}
continue;
}
// Show the section if the user is permitted to access it, OR if it's not available
- // but showavailability is turned on
+ // but showavailability is turned on (and there is some available info text).
$showsection = $thissection->uservisible ||
- ($thissection->visible && !$thissection->available && $thissection->showavailability);
+ ($thissection->visible && !$thissection->available && $thissection->showavailability
+ && !empty($thissection->availableinfo));
if (!$showsection) {
// Hidden section message is overridden by 'unavailable' control
// (showavailability option).
--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * PayPal CLI tool.
+ *
+ * Notes:
+ * - it is required to use the web server account when executing PHP CLI scripts
+ * - you need to change the "www-data" to match the apache user account
+ * - use "su" if "sudo" not available
+ *
+ * @package enrol_paypal
+ * @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");
+
+// Now get cli options.
+list($options, $unrecognized) = cli_get_params(array('verbose'=>false, 'help'=>false), array('v'=>'verbose', 'h'=>'help'));
+
+if ($unrecognized) {
+ $unrecognized = implode("\n ", $unrecognized);
+ cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
+}
+
+if ($options['help']) {
+ $help =
+ "Process PayPal expiration sync
+
+Options:
+-v, --verbose Print verbose progress information
+-h, --help Print out this help
+
+Example:
+\$ sudo -u www-data /usr/bin/php enrol/paypal/cli/sync.php
+";
+
+ echo $help;
+ die;
+}
+
+if (!enrol_is_enabled('paypal')) {
+ echo('enrol_paypal plugin is disabled'."\n");
+ exit(2);
+}
+
+if (empty($options['verbose'])) {
+ $trace = new null_progress_trace();
+} else {
+ $trace = new text_progress_trace();
+}
+
+/** @var $plugin enrol_paypal_plugin */
+$plugin = enrol_get_plugin('paypal');
+
+$result = $plugin->sync($trace);
+
+exit($result);
$string['enrolperiod_help'] = 'Length of time that the enrolment is valid, starting with the moment the user is enrolled. If disabled, the enrolment duration will be unlimited.';
$string['enrolstartdate'] = 'Start date';
$string['enrolstartdate_help'] = 'If enabled, users can be enrolled from this date onward only.';
+$string['expiredaction'] = 'Enrolment expiration action';
+$string['expiredaction_help'] = 'Select action to carry out when user enrolment expires. Please note that some user data and settings are purged from course during course unenrolment.';
$string['mailadmins'] = 'Notify admin';
$string['mailstudents'] = 'Notify students';
$string['mailteachers'] = 'Notify teachers';
}
return $actions;
}
+
+ public function cron() {
+ $trace = new text_progress_trace();
+ $this->process_expirations($trace);
+ }
+
+ /**
+ * Execute synchronisation.
+ * @param progress_trace $trace
+ * @return int exit code, 0 means ok
+ */
+ public function sync(progress_trace $trace) {
+ $this->process_expirations($trace);
+ return 0;
+ }
+
+ /**
+ * Do any enrolment expiration processing.
+ *
+ * @param progress_trace $trace
+ * @return bool true if any data processed, false if not
+ */
+ protected function process_expirations(progress_trace $trace) {
+ global $DB;
+
+ //TODO: this method should be moved to parent class once we refactor all existing enrols, see MDL-36504.
+
+ $processed = false;
+ $name = $this->get_name();
+
+ // Deal with expired accounts.
+ $action = $this->get_config('expiredaction', ENROL_EXT_REMOVED_KEEP);
+
+ if ($action == ENROL_EXT_REMOVED_UNENROL) {
+ $instances = array();
+ $sql = "SELECT ue.*, e.courseid, c.id AS contextid
+ FROM {user_enrolments} ue
+ JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = :enrol)
+ JOIN {context} c ON (c.instanceid = e.courseid AND c.contextlevel = :courselevel)
+ WHERE ue.timeend > 0 AND ue.timeend < :now";
+ $params = array('now'=>time(), 'courselevel'=>CONTEXT_COURSE, 'enrol'=>$name);
+
+ $rs = $DB->get_recordset_sql($sql, $params);
+ foreach ($rs as $ue) {
+ if (!$processed) {
+ $trace->output("Starting processing of enrol_$name expirations...");
+ $processed = true;
+ }
+ if (empty($instances[$ue->enrolid])) {
+ $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
+ }
+ $instance = $instances[$ue->enrolid];
+ if (!$this->roles_protected()) {
+ // Let's just guess what extra roles are supposed to be removed.
+ if ($instance->roleid) {
+ role_unassign($instance->roleid, $ue->userid, $ue->contextid);
+ }
+ }
+ // The unenrol cleans up all subcontexts if this is the only course enrolment for this user.
+ $this->unenrol_user($instance, $ue->userid);
+ $trace->output("Unenrolling expired user $ue->userid from course $instance->courseid", 1);
+ }
+ $rs->close();
+ unset($instances);
+
+ } else if ($action == ENROL_EXT_REMOVED_SUSPENDNOROLES) {
+ $instances = array();
+ $sql = "SELECT ue.*, e.courseid, c.id AS contextid
+ FROM {user_enrolments} ue
+ JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = :enrol)
+ JOIN {context} c ON (c.instanceid = e.courseid AND c.contextlevel = :courselevel)
+ WHERE ue.timeend > 0 AND ue.timeend < :now
+ AND ue.status = :useractive";
+ $params = array('now'=>time(), 'courselevel'=>CONTEXT_COURSE, 'useractive'=>ENROL_USER_ACTIVE, 'enrol'=>$name);
+ $rs = $DB->get_recordset_sql($sql, $params);
+ foreach ($rs as $ue) {
+ if (!$processed) {
+ $trace->output("Starting processing of enrol_$name expirations...");
+ $processed = true;
+ }
+ if (empty($instances[$ue->enrolid])) {
+ $instances[$ue->enrolid] = $DB->get_record('enrol', array('id'=>$ue->enrolid));
+ }
+ $instance = $instances[$ue->enrolid];
+
+ if (!$this->roles_protected()) {
+ // Let's just guess what roles should be removed.
+ $count = $DB->count_records('role_assignments', array('userid'=>$ue->userid, 'contextid'=>$ue->contextid));
+ if ($count == 1) {
+ role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$ue->contextid, 'component'=>'', 'itemid'=>0));
+
+ } else if ($count > 1 and $instance->roleid) {
+ role_unassign($instance->roleid, $ue->userid, $ue->contextid, '', 0);
+ }
+ }
+ // In any case remove all roles that belong to this instance and user.
+ role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$ue->contextid, 'component'=>'enrol_'.$name, 'itemid'=>$instance->id), true);
+ // Final cleanup of subcontexts if there are no more course roles.
+ if (0 == $DB->count_records('role_assignments', array('userid'=>$ue->userid, 'contextid'=>$ue->contextid))) {
+ role_unassign_all(array('userid'=>$ue->userid, 'contextid'=>$ue->contextid, 'component'=>'', 'itemid'=>0), true);
+ }
+
+ $this->update_user_enrol($instance, $ue->userid, ENROL_USER_SUSPENDED);
+ $trace->output("Suspending expired user $ue->userid in course $instance->courseid", 1);
+ }
+ $rs->close();
+ unset($instances);
+
+ } else {
+ // ENROL_EXT_REMOVED_KEEP means no changes.
+ }
+
+ if ($processed) {
+ $trace->output("...finished processing of enrol_$name expirations");
+ } else {
+ $trace->output("No expired enrol_$name enrolments detected");
+ }
+ $trace->finished();
+
+ return $processed;
+ }
}
$settings->add(new admin_setting_configcheckbox('enrol_paypal/mailadmins', get_string('mailadmins', 'enrol_paypal'), '', 0));
+ // Note: let's reuse the ext sync constants and strings here, internally it is very similar,
+ // it describes what should happen when users are not supposed to be enrolled any more.
+ $options = array(
+ ENROL_EXT_REMOVED_KEEP => get_string('extremovedkeep', 'enrol'),
+ ENROL_EXT_REMOVED_SUSPENDNOROLES => get_string('extremovedsuspendnoroles', 'enrol'),
+ ENROL_EXT_REMOVED_UNENROL => get_string('extremovedunenrol', 'enrol'),
+ );
+ $settings->add(new admin_setting_configselect('enrol_paypal/expiredaction', get_string('expiredaction', 'enrol_paypal'), get_string('expiredaction_help', 'enrol_paypal'), ENROL_EXT_REMOVED_SUSPENDNOROLES, $options));
+
//--- enrol instance defaults ----------------------------------------------------------------------------
$settings->add(new admin_setting_heading('enrol_paypal_defaults',
get_string('enrolinstancedefaults', 'admin'), get_string('enrolinstancedefaults_desc', 'admin')));
--- /dev/null
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * paypal enrolment plugin tests.
+ *
+ * @package enrol_paypal
+ * @category phpunit
+ * @copyright 2012 Petr Skoda {@link http://skodak.org}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+
+class enrol_paypal_testcase extends advanced_testcase {
+
+ protected function enable_plugin() {
+ $enabled = enrol_get_plugins(true);
+ $enabled['paypal'] = true;
+ $enabled = array_keys($enabled);
+ set_config('enrol_plugins_enabled', implode(',', $enabled));
+ }
+
+ protected function disable_plugin() {
+ $enabled = enrol_get_plugins(true);
+ unset($enabled['paypal']);
+ $enabled = array_keys($enabled);
+ set_config('enrol_plugins_enabled', implode(',', $enabled));
+ }
+
+ public function test_basics() {
+ $this->assertFalse(enrol_is_enabled('paypal'));
+ $plugin = enrol_get_plugin('paypal');
+ $this->assertInstanceOf('enrol_paypal_plugin', $plugin);
+ $this->assertEquals(ENROL_EXT_REMOVED_SUSPENDNOROLES, get_config('enrol_paypal', 'expiredaction'));
+ }
+
+ public function test_sync_nothing() {
+ $this->resetAfterTest();
+
+ $this->enable_plugin();
+ $paypalplugin = enrol_get_plugin('paypal');
+
+ // Just make sure the sync does not throw any errors when nothing to do.
+ $paypalplugin->sync(new null_progress_trace());
+ }
+
+ public function test_expired() {
+ global $DB;
+ $this->resetAfterTest();
+
+ /** @var enrol_paypal_plugin $paypalplugin */
+ $paypalplugin = enrol_get_plugin('paypal');
+ /** @var enrol_manual_plugin $manualplugin */
+ $manualplugin = enrol_get_plugin('manual');
+ $this->assertNotEmpty($manualplugin);
+
+ $now = time();
+ $trace = new null_progress_trace();
+ $this->enable_plugin();
+
+
+ // Prepare some data.
+
+ $studentrole = $DB->get_record('role', array('shortname'=>'student'));
+ $this->assertNotEmpty($studentrole);
+ $teacherrole = $DB->get_record('role', array('shortname'=>'teacher'));
+ $this->assertNotEmpty($teacherrole);
+ $managerrole = $DB->get_record('role', array('shortname'=>'manager'));
+ $this->assertNotEmpty($managerrole);
+
+ $user1 = $this->getDataGenerator()->create_user();
+ $user2 = $this->getDataGenerator()->create_user();
+ $user3 = $this->getDataGenerator()->create_user();
+ $user4 = $this->getDataGenerator()->create_user();
+
+ $course1 = $this->getDataGenerator()->create_course();
+ $course2 = $this->getDataGenerator()->create_course();
+ $context1 = context_course::instance($course1->id);
+ $context2 = context_course::instance($course2->id);
+
+ $data = array('roleid'=>$studentrole->id, 'courseid'=>$course1->id);
+ $id = $paypalplugin->add_instance($course1, $data);
+ $instance1 = $DB->get_record('enrol', array('id'=>$id));
+ $data = array('roleid'=>$studentrole->id, 'courseid'=>$course2->id);
+ $id = $paypalplugin->add_instance($course2, $data);
+ $instance2 = $DB->get_record('enrol', array('id'=>$id));
+ $data = array('roleid'=>$teacherrole->id, 'courseid'=>$course2->id);
+ $id = $paypalplugin->add_instance($course2, $data);
+ $instance3 = $DB->get_record('enrol', array('id'=>$id));
+
+ $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course2->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+
+ $manualplugin->enrol_user($maninstance1, $user3->id, $studentrole->id);
+
+ $this->assertEquals(1, $DB->count_records('user_enrolments'));
+ $this->assertEquals(1, $DB->count_records('role_assignments'));
+ $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+
+ $paypalplugin->enrol_user($instance1, $user1->id, $studentrole->id);
+ $paypalplugin->enrol_user($instance1, $user2->id, $studentrole->id);
+ $paypalplugin->enrol_user($instance1, $user3->id, $studentrole->id, 0, $now-60);
+
+ $paypalplugin->enrol_user($instance2, $user1->id, $studentrole->id, 0, 0);
+ $paypalplugin->enrol_user($instance2, $user2->id, $studentrole->id, 0, $now-60*60);
+ $paypalplugin->enrol_user($instance2, $user3->id, $studentrole->id, 0, $now+60*60);
+
+ $paypalplugin->enrol_user($instance3, $user1->id, $teacherrole->id, $now-60*60*24*7, $now-60);
+ $paypalplugin->enrol_user($instance3, $user4->id, $teacherrole->id);
+
+ role_assign($managerrole->id, $user3->id, $context1->id);
+
+ $this->assertEquals(9, $DB->count_records('user_enrolments'));
+ $this->assertEquals(9, $DB->count_records('role_assignments'));
+ $this->assertEquals(6, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+ $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
+ $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$managerrole->id)));
+
+ // Execute tests.
+
+ $paypalplugin->set_config('expiredaction', ENROL_EXT_REMOVED_KEEP);
+ $code = $paypalplugin->sync($trace);
+ $this->assertSame(0, $code);
+ $this->assertEquals(9, $DB->count_records('user_enrolments'));
+ $this->assertEquals(9, $DB->count_records('role_assignments'));
+
+
+ $paypalplugin->set_config('expiredaction', ENROL_EXT_REMOVED_SUSPENDNOROLES);
+ $paypalplugin->sync($trace);
+ $this->assertEquals(9, $DB->count_records('user_enrolments'));
+ $this->assertEquals(6, $DB->count_records('role_assignments'));
+ $this->assertEquals(4, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+ $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
+ $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context1->id, 'userid'=>$user3->id, 'roleid'=>$studentrole->id)));
+ $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context2->id, 'userid'=>$user2->id, 'roleid'=>$studentrole->id)));
+ $this->assertFalse($DB->record_exists('role_assignments', array('contextid'=>$context2->id, 'userid'=>$user1->id, 'roleid'=>$teacherrole->id)));
+ $this->assertTrue($DB->record_exists('role_assignments', array('contextid'=>$context2->id, 'userid'=>$user1->id, 'roleid'=>$studentrole->id)));
+
+
+ $paypalplugin->set_config('expiredaction', ENROL_EXT_REMOVED_UNENROL);
+ role_assign($studentrole->id, $user3->id, $context1->id);
+ role_assign($studentrole->id, $user2->id, $context2->id);
+ role_assign($teacherrole->id, $user1->id, $context2->id);
+ $this->assertEquals(9, $DB->count_records('user_enrolments'));
+ $this->assertEquals(9, $DB->count_records('role_assignments'));
+ $this->assertEquals(6, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+ $this->assertEquals(2, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
+ $paypalplugin->sync($trace);
+ $this->assertEquals(6, $DB->count_records('user_enrolments'));
+ $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$instance1->id, 'userid'=>$user3->id)));
+ $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$instance2->id, 'userid'=>$user2->id)));
+ $this->assertFalse($DB->record_exists('user_enrolments', array('enrolid'=>$instance3->id, 'userid'=>$user1->id)));
+ $this->assertEquals(5, $DB->count_records('role_assignments'));
+ $this->assertEquals(4, $DB->count_records('role_assignments', array('roleid'=>$studentrole->id)));
+ $this->assertEquals(1, $DB->count_records('role_assignments', array('roleid'=>$teacherrole->id)));
+ }
+}
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012112900; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version = 2012122300; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2012112900; // Requires this Moodle version
$plugin->component = 'enrol_paypal'; // Full name of the plugin (used for diagnostics)
+$plugin->cron = 60;
$string['cacheconfig'] = 'Configuration';
$string['cachedef_databasemeta'] = 'Database meta information';
$string['cachedef_eventinvalidation'] = 'Event invalidation';
+$string['cachedef_htmlpurifier'] = 'HTML Purifier - cleaned content';
$string['cachedef_locking'] = 'Locking';
$string['cachedef_questiondata'] = 'Question definitions';
$string['cachedef_string'] = 'Language string cache';
'datasource' => 'question_finder',
'datasourcefile' => 'question/engine/bank.php',
),
+
+ // HTML Purifier cache
+ // This caches the html purifier cleaned text. This is done because the text is usually cleaned once for every user
+ // and context combo. Text caching handles caching for the combonation, this cache is responsible for caching the
+ // cleaned text which is shareable.
+ 'htmlpurifier' => array(
+ 'mode' => cache_store::MODE_APPLICATION,
+ )
);
function purify_html($text, $options = array()) {
global $CFG;
- $type = !empty($options['allowid']) ? 'allowid' : 'normal';
static $purifiers = array();
+ static $caches = array();
+
+ $type = !empty($options['allowid']) ? 'allowid' : 'normal';
+
+ if (!array_key_exists($type, $caches)) {
+ $caches[$type] = cache::make('core', 'htmlpurifier', array('type' => $type));
+ }
+ $cache = $caches[$type];
+
+ $filteredtext = $cache->get($text);
+ if ($filteredtext !== false) {
+ return $filteredtext;
+ }
+
if (empty($purifiers[$type])) {
// make sure the serializer dir exists, it should be fine if it disappears later during cache reset
$multilang = (strpos($text, 'class="multilang"') !== false);
+ $filteredtext = $text;
if ($multilang) {
- $text = preg_replace('/<span(\s+lang="([a-zA-Z0-9_-]+)"|\s+class="multilang"){2}\s*>/', '<span xxxlang="${2}">', $text);
+ $filteredtext = preg_replace('/<span(\s+lang="([a-zA-Z0-9_-]+)"|\s+class="multilang"){2}\s*>/', '<span xxxlang="${2}">', $filteredtext);
}
- $text = $purifier->purify($text);
+ $filteredtext = $purifier->purify($filteredtext);
if ($multilang) {
- $text = preg_replace('/<span xxxlang="([a-zA-Z0-9_-]+)">/', '<span lang="${1}" class="multilang">', $text);
+ $filteredtext = preg_replace('/<span xxxlang="([a-zA-Z0-9_-]+)">/', '<span lang="${1}" class="multilang">', $filteredtext);
}
+ $cache->set($text, $filteredtext);
- return $text;
+ return $filteredtext;
}
/**
}
// Assign this select items 'nothing' value and lastindex (current value)
- var thisselect = Y.one('select#' + this.get('selectid'));
- thisselect.setData('nothing', this.get('nothing'));
- thisselect.setData('startindex', thisselect.get('selectedIndex'));
+ if (this.get('selectid')) {
+ var thisselect = Y.one('select#' + this.get('selectid'));
+ if (thisselect) {
+ if (this.get('nothing')) {
+ thisselect.setData('nothing', this.get('nothing'));
+ }
+ thisselect.setData('startindex', thisselect.get('selectedIndex'));
+ } else {
+ Y.log("Warning: A single_select element was renderered, but the output is not displayed on the page.");
+ }
+ }
},
/**
}
if ($type == 0) {
$chapterfile = reset($chapterfiles);
- if ($file = $fs->get_file_by_hash("$context->id/mod_book/importhtmltemp/0/$chapterfile->pathname")) {
+ if ($file = $fs->get_file_by_hash(sha1("$context->id/mod_book/importhtmltemp/0/$chapterfile->pathname"))) {
$htmlcontent = toolbook_importhtml_fix_encoding($file->get_content());
$htmlchapters = toolbook_importhtml_parse_headings(toolbook_importhtml_parse_body($htmlcontent));
// TODO: process h1 as main chapter and h2 as subchapters
$eventdata->contexturl = "{$CFG->wwwroot}/mod/forum/discuss.php?d={$discussion->id}#p{$post->id}";
$eventdata->contexturlname = $discussion->name;
+ // If forum_replytouser is not set then send mail using the noreplyaddress.
+ if (empty($CFG->forum_replytouser)) {
+ $eventdata->userfrom->email = $CFG->noreplyaddress;
+ }
+
$mailresult = message_send($eventdata);
if (!$mailresult){
mtrace("Error: mod/forum/lib.php forum_cron(): Could not send out mail for id $post->id to user $userto->id".
}
$attachment = $attachname='';
- $usetrueaddress = true;
// Directly email forum digests rather than sending them via messaging, use the
// site shortname as 'from name', the noreply address will be used by email_to_user.
- $mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml, $attachment, $attachname, $usetrueaddress, $CFG->forum_replytouser);
+ $mailresult = email_to_user($userto, $site->shortname, $postsubject, $posttext, $posthtml, $attachment, $attachname);
if (!$mailresult) {
mtrace("ERROR!");
// finally activate the chosen item
var scorm_first_url = tree.getRoot().children[0];
+ if (scorm_first_url == null) { // This is probably a single sco with no children (AICC Direct uses this).
+ scorm_first_url = tree.getRoot();
+ }
scorm_first_url.title = scoes_nav[launch_sco].url;
scorm_activate_item(scorm_first_url);
$string['savingerror'] = 'Saving error';
$string['searchcontent'] = 'Search in page content';
$string['searchresult'] = 'Search results:';
+$string['searchterms'] = 'Search terms';
$string['searchwikis'] = 'Search wikis';
$string['special'] = 'Special';
$string['tableofcontents'] = 'Table of contents';
$output = '<div class="wikisearch">';
$output .= '<form method="post" action="' . $CFG->wwwroot . '/mod/wiki/search.php" style="display:inline">';
$output .= '<fieldset class="invisiblefieldset">';
- $output .= '<label class="accesshide" for="searchwiki">' . get_string("searchwikis", "wiki") . '</label>';
+ $output .= '<legend class="accesshide">'. get_string('searchwikis', 'wiki') .'</legend>';
+ $output .= '<label class="accesshide" for="searchwiki">' . get_string("searchterms", "wiki") . '</label>';
$output .= '<input id="searchwiki" name="searchstring" type="text" size="18" value="' . s($search, true) . '" alt="search" />';
$output .= '<input name="courseid" type="hidden" value="' . $cm->course . '" />';
$output .= '<input name="cmid" type="hidden" value="' . $cm->id . '" />';
echo '<table class="list" summary="">';
-//checks were performed above that ensure that if we've got to here either the user
-//is viewing their own profile ($USER->id == $user->id) or $user is enrolled in the course
+// Show email if any of the following conditions match.
+// 1. User is viewing his own profile.
+// 2. Has allowed everyone to see email
+// 3. User has allowed course members to can see email and current user is in same course
+// 4. Has either course:viewhiddenuserfields or site:viewuseridentity capability.
if ($currentuser
- or $user->maildisplay == 1 //allow everyone to see email address
- or ($user->maildisplay == 2 && is_enrolled($coursecontext, $USER)) //fellow course members can see email. Already know $user is enrolled
- or has_capability('moodle/course:useremail', $coursecontext)) {
+ or $user->maildisplay == 1
+ or ($user->maildisplay == 2 && is_enrolled($coursecontext, $USER))
+ or has_capability('moodle/course:viewhiddenuserfields', $coursecontext)
+ or has_capability('moodle/site:viewuseridentity', $coursecontext)) {
print_row(get_string("email").":", obfuscate_mailto($user->email, ''));
}
defined('MOODLE_INTERNAL') || die();
-$version = 2013011100.01; // YYYYMMDD = weekly release date of this DEV branch
+$version = 2013011100.02; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes