<?php
-
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
- * Enable or disable maintenance mode
+ * Enable or disable maintenance mode.
*
* @package core
* @subpackage cli
define('CLI_SCRIPT', true);
-require(dirname(dirname(dirname(__FILE__))).'/config.php');
-require_once($CFG->libdir.'/clilib.php'); // cli only functions
+require(__DIR__.'/../../config.php');
+require_once("$CFG->libdir/clilib.php");
+require_once("$CFG->libdir/adminlib.php");
-// now get cli options
-list($options, $unrecognized) = cli_get_params(array('enable'=>false, 'disable'=>false, 'help'=>false),
+// Now get cli options.
+list($options, $unrecognized) = cli_get_params(array('enable'=>false, 'enablelater'=>0, 'enableold'=>false, 'disable'=>false, 'help'=>false),
array('h'=>'help'));
if ($unrecognized) {
Current status displayed if not option specified.
Options:
---enable Enable maintenance mode
+--enable Enable CLI maintenance mode
+--enablelater=MINUTES Number of minutes before entering CLI maintenance mode
+--enableold Enable legacy half-maintenance mode
--disable Disable maintenance mode
-h, --help Print out this help
Example:
-\$sudo -u www-data /usr/bin/php admin/cli/maintenance.php
+\$ sudo -u www-data /usr/bin/php admin/cli/maintenance.php
"; //TODO: localize - to be translated later when everything is finished
echo $help;
cli_heading(get_string('sitemaintenancemode', 'admin')." ($CFG->wwwroot)");
-if ($options['enable']) {
+if ($options['enablelater']) {
+ if (file_exists("$CFG->dataroot/climaintenance.html")) {
+ // Already enabled, sorry.
+ echo get_string('clistatusenabled', 'admin')."\n";
+ return 1;
+ }
+
+ $time = time() + ($options['enablelater']*60);
+ set_config('maintenance_later', $time);
+
+ echo get_string('clistatusenabledlater', 'admin', userdate($time))."\n";
+ return 0;
+
+} else if ($options['enable']) {
+ if (file_exists("$CFG->dataroot/climaintenance.html")) {
+ // The maintenance is already enabled, nothing to do.
+ } else {
+ enable_cli_maintenance_mode();
+ }
+ set_config('maintenance_enabled', 0);
+ unset_config('maintenance_later');
+ echo get_string('sitemaintenanceoncli', 'admin')."\n";
+ exit(0);
+
+} else if ($options['enableold']) {
set_config('maintenance_enabled', 1);
+ unset_config('maintenance_later');
echo get_string('sitemaintenanceon', 'admin')."\n";
exit(0);
+
} else if ($options['disable']) {
set_config('maintenance_enabled', 0);
+ unset_config('maintenance_later');
+ if (file_exists("$CFG->dataroot/climaintenance.html")) {
+ unlink("$CFG->dataroot/climaintenance.html");
+ }
echo get_string('sitemaintenanceoff', 'admin')."\n";
exit(0);
}
-if (!empty($CFG->maintenance_enabled)) {
+if (!empty($CFG->maintenance_enabled) or file_exists("$CFG->dataroot/climaintenance.html")) {
echo get_string('clistatusenabled', 'admin')."\n";
+
+} else if (isset($CFG->maintenance_later)) {
+ echo get_string('clistatusenabledlater', 'admin', userdate($CFG->maintenance_later))."\n";
+
} else {
echo get_string('clistatusdisabled', 'admin')."\n";
}
public function make_copy() {
$this->roleid = 0;
unset($this->role->id);
- $this->role->name .= ' ' . get_string('copyasnoun');
+ $this->role->name = role_get_name($this->role, null, ROLENAME_ORIGINAL) . ' ' . get_string('copyasnoun');
$this->role->shortname .= 'copy';
}
return $output;
}
+ /**
+ * Returns an array of roles of the allowed type.
+ *
+ * @param string $type Must be one of: assign, switch, or override.
+ * @return array
+ */
+ protected function get_allow_roles_list($type) {
+ global $DB;
+
+ if ($type !== 'assign' and $type !== 'switch' and $type !== 'override') {
+ debugging('Invalid role allowed type specified', DEBUG_DEVELOPER);
+ return array();
+ }
+
+ if (empty($this->roleid)) {
+ return array();
+ }
+
+ $sql = "SELECT r.*
+ FROM {role} r
+ JOIN {role_allow_{$type}} a ON a.allow{$type} = r.id
+ WHERE a.roleid = :roleid
+ ORDER BY r.sortorder ASC";
+ return $DB->get_records_sql($sql, array('roleid'=>$this->roleid));
+ }
+
+ /**
+ * Returns an array of roles with the allowed type.
+ *
+ * @param string $type Must be one of: assign, switch, or override.
+ * @return array Am array of role names with the allowed type
+ */
+ protected function get_allow_role_control($type) {
+ if ($roles = $this->get_allow_roles_list($type)) {
+ $roles = role_fix_names($roles, null, ROLENAME_ORIGINAL, true);
+ return implode(', ', $roles);
+ } else {
+ return get_string('none');
+ }
+ }
+
+ /**
+ * Returns information about the risks associated with a role.
+ *
+ * @return string
+ */
+ protected function get_role_risks_info() {
+ return '';
+ }
+
protected function print_field($name, $caption, $field) {
global $OUTPUT;
// Attempt to generate HTML like formslib.
$this->print_field('edit-description', get_string('customroledescription', 'role').' '.$OUTPUT->help_icon('customroledescription', 'role'), $this->get_description_field('description'));
$this->print_field('menuarchetype', get_string('archetype', 'role').' '.$OUTPUT->help_icon('archetype', 'role'), $this->get_archetype_field('archetype'));
$this->print_field('', get_string('maybeassignedin', 'role'), $this->get_assignable_levels_control());
+ $this->print_field('', get_string('allowassign', 'role'), $this->get_allow_role_control('assign'));
+ $this->print_field('', get_string('allowoverride', 'role'), $this->get_allow_role_control('override'));
+ $this->print_field('', get_string('allowswitch', 'role'), $this->get_allow_role_control('switch'));
+ if ($risks = $this->get_role_risks_info()) {
+ $this->print_field('', get_string('rolerisks', 'role'), $risks);
+ }
echo "</div>";
$this->print_show_hide_advanced_button();
// Do nothing.
}
+ /**
+ * Returns HTML risk icons.
+ *
+ * @return string
+ */
+ protected function get_role_risks_info() {
+ global $OUTPUT;
+
+ if (empty($this->roleid)) {
+ return '';
+ }
+
+ $risks = array();
+ $allrisks = get_all_risks();
+ foreach ($this->capabilities as $capability) {
+ $perm = $this->permissions[$capability->name];
+ if ($perm != CAP_ALLOW) {
+ continue;
+ }
+ foreach ($allrisks as $type=>$risk) {
+ if ($risk & (int)$capability->riskbitmask) {
+ $risks[$type] = $risk;
+ }
+ }
+ }
+
+ $risksurl = new moodle_url(get_docs_url(s(get_string('risks', 'role'))));
+ foreach ($risks as $type=>$risk) {
+ $pixicon = new pix_icon('/i/' . str_replace('risk', 'risk_', $type), get_string($type . 'short', 'admin'));
+ $risks[$type] = $OUTPUT->action_icon($risksurl, $pixicon, new popup_action('click', $risksurl));
+ }
+
+ return implode(' ', $risks);
+ }
+
+ /**
+ * Returns true if the row should be skipped.
+ *
+ * @param string $capability
+ * @return bool
+ */
+ protected function skip_row($capability) {
+ $perm = $this->permissions[$capability->name];
+ if ($perm == CAP_INHERIT) {
+ // Do not print empty rows in role overview, admins need to know quickly what is allowed and prohibited,
+ // if they want to see the list of all capabilities they can go to edit role page.
+ return true;
+ }
+ parent::skip_row($capability);
+ }
+
protected function add_permission_cells($capability) {
$perm = $this->permissions[$capability->name];
$permname = $this->allpermissions[$perm];
// Display completion status
-echo '<table class="generalbox boxaligncenter"><tbody>';
+echo '<table class="generaltable boxaligncenter"><tbody>';
// If not display logged in user, show user name
if ($USER->id != $user->id) {
echo '</td></tr></tbody></table>';
// Generate markup for criteria statuses
- echo '<table class="generalbox logtable boxaligncenter" id="criteriastatus" width="100%"><tbody>';
+ echo '<table class="generaltable logtable boxaligncenter" id="criteriastatus" width="100%"><tbody>';
echo '<tr class="ccheader">';
echo '<th class="c0 header" scope="col">'.get_string('criteriagroup', 'block_completionstatus').'</th>';
echo '<th class="c1 header" scope="col">'.get_string('criteria', 'completion').'</th>';
$this->title = get_string('pluginname','block_glossary_random');
}
- function applicable_formats() {
- return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
- }
-
function specialization() {
global $CFG, $DB;
$capabilities = array(
+ 'block/glossary_random:myaddinstance' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/my:manageblocks'
+ ),
+
'block/glossary_random:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
+++ /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/>.
-
-/**
- * This file keeps track of upgrades to the glossary random block
- *
- * Sometimes, changes between versions involve alterations to database structures
- * and other major things that may break installations.
- *
- * The upgrade function in this file will attempt to perform all the necessary
- * actions to upgrade your older installation to the current version.
- *
- * If there's something it cannot do itself, it will tell you what you need to do.
- *
- * The commands in here will all be database-neutral, using the methods of
- * database_manager class
- *
- * Please do not forget to use upgrade_set_timeout()
- * before any action that may take longer time to finish.
- *
- * @since 2.0
- * @package blocks
- * @copyright 2012 Mark Nelson <markn@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Handles upgrading instances of this block.
- *
- * @param int $oldversion
- * @param object $block
- */
-function xmldb_block_glossary_random_upgrade($oldversion, $block) {
- global $DB;
-
- // Moodle v2.4.0 release upgrade line
- // Put any upgrade step following this.
-
- if ($oldversion < 2012112901) {
- // Get the instances of this block.
- if ($blocks = $DB->get_records('block_instances', array('blockname' => 'glossary_random', 'pagetypepattern' => 'my-index'))) {
- // Loop through and remove them from the My Moodle page.
- foreach ($blocks as $block) {
- blocks_delete_instance($block);
- }
-
- }
-
- // Savepoint reached.
- upgrade_block_savepoint(true, 2012112901, 'glossary_random');
- }
-
-
- return true;
-}
\ No newline at end of file
$string['askinvisible'] = 'When users cannot edit or view the glossary, show this text (without link)';
$string['askviewglossary'] = 'When users can view the glossary but not add entries, show a link with this text';
$string['glossary_random:addinstance'] = 'Add a new random glossary entry block';
+$string['glossary_random:myaddinstance'] = 'Add a new random glossary entry block to the My Moodle page';
$string['intro'] = 'Make sure you have at least one glossary with at least one entry added to this course. Then you can adjust the following settings';
$string['invisible'] = '(to be continued)';
$string['lastmodified'] = 'Last modified entry';
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012112901; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version = 2012112902; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2012112900; // Requires this Moodle version
$plugin->component = 'block_glossary_random'; // Full name of the plugin (used for diagnostics)
}
function applicable_formats() {
- return array('all' => true, 'tag' => false, 'my' => false);
+ return array('all' => true, 'tag' => false);
}
function specialization() {
$capabilities = array(
+ 'block/mentees:myaddinstance' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/my:manageblocks'
+ ),
+
'block/mentees:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
+++ /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/>.
-
-/**
- * This file keeps track of upgrades to the mentees block
- *
- * Sometimes, changes between versions involve alterations to database structures
- * and other major things that may break installations.
- *
- * The upgrade function in this file will attempt to perform all the necessary
- * actions to upgrade your older installation to the current version.
- *
- * If there's something it cannot do itself, it will tell you what you need to do.
- *
- * The commands in here will all be database-neutral, using the methods of
- * database_manager class
- *
- * Please do not forget to use upgrade_set_timeout()
- * before any action that may take longer time to finish.
- *
- * @since 2.0
- * @package blocks
- * @copyright 2012 Mark Nelson <markn@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Handles upgrading instances of this block.
- *
- * @param int $oldversion
- * @param object $block
- */
-function xmldb_block_mentees_upgrade($oldversion, $block) {
- global $DB;
-
- // Moodle v2.4.0 release upgrade line
- // Put any upgrade step following this.
-
- if ($oldversion < 2012112901) {
- // Get the instances of this block.
- if ($blocks = $DB->get_records('block_instances', array('blockname' => 'mentees', 'pagetypepattern' => 'my-index'))) {
- // Loop through and remove them from the My Moodle page.
- foreach ($blocks as $block) {
- blocks_delete_instance($block);
- }
-
- }
-
- // Savepoint reached.
- upgrade_block_savepoint(true, 2012112901, 'mentees');
- }
-
-
- return true;
-}
\ No newline at end of file
$string['configtitleblankhides'] = 'Block title (no title if blank)';
$string['leaveblanktohide'] = 'leave blank to hide the title';
$string['mentees:addinstance'] = 'Add a new mentees block';
+$string['mentees:myaddinstance'] = 'Add a new mentees block to the My Moodle page';
$string['newmenteesblock'] = '(new Mentees block)';
$string['pluginname'] = 'Mentees';
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012112901; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version = 2012112902; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2012112900; // Requires this Moodle version
$plugin->component = 'block_mentees'; // Full name of the plugin (used for diagnostics)
$this->title = get_string('pluginname', 'block_news_items');
}
- function applicable_formats() {
- return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
- }
-
function get_content() {
global $CFG, $USER;
$capabilities = array(
+ 'block/news_items:myaddinstance' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/my:manageblocks'
+ ),
+
'block/news_items:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
+++ /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/>.
-
-/**
- * This file keeps track of upgrades to the latest news block
- *
- * Sometimes, changes between versions involve alterations to database structures
- * and other major things that may break installations.
- *
- * The upgrade function in this file will attempt to perform all the necessary
- * actions to upgrade your older installation to the current version.
- *
- * If there's something it cannot do itself, it will tell you what you need to do.
- *
- * The commands in here will all be database-neutral, using the methods of
- * database_manager class
- *
- * Please do not forget to use upgrade_set_timeout()
- * before any action that may take longer time to finish.
- *
- * @since 2.0
- * @package blocks
- * @copyright 2012 Mark Nelson <markn@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Handles upgrading instances of this block.
- *
- * @param int $oldversion
- * @param object $block
- */
-function xmldb_block_news_items_upgrade($oldversion, $block) {
- global $DB;
-
- // Moodle v2.4.0 release upgrade line
- // Put any upgrade step following this.
-
- if ($oldversion < 2012112901) {
- // Get the instances of this block.
- if ($blocks = $DB->get_records('block_instances', array('blockname' => 'news_items', 'pagetypepattern' => 'my-index'))) {
- // Loop through and remove them from the My Moodle page.
- foreach ($blocks as $block) {
- blocks_delete_instance($block);
- }
-
- }
-
- // Savepoint reached.
- upgrade_block_savepoint(true, 2012112901, 'news_items');
- }
-
-
- return true;
-}
\ No newline at end of file
*/
$string['news_items:addinstance'] = 'Add a new latest news block';
+$string['news_items:myaddinstance'] = 'Add a new latest news block to the My Moodle page';
$string['pluginname'] = 'Latest news';
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012112901; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version = 2012112902; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2012112900; // Requires this Moodle version
$plugin->component = 'block_news_items'; // Full name of the plugin (used for diagnostics)
$this->title = get_string('pluginname','block_online_users');
}
- function applicable_formats() {
- return array('all' => true, 'mod' => false, 'tag' => false, 'my' => false);
- }
-
function has_config() {
return true;
}
$capabilities = array(
+ 'block/online_users:myaddinstance' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/my:manageblocks'
+ ),
+
'block/online_users:addinstance' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
+++ /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/>.
-
-/**
- * This file keeps track of upgrades to the online users block
- *
- * Sometimes, changes between versions involve alterations to database structures
- * and other major things that may break installations.
- *
- * The upgrade function in this file will attempt to perform all the necessary
- * actions to upgrade your older installation to the current version.
- *
- * If there's something it cannot do itself, it will tell you what you need to do.
- *
- * The commands in here will all be database-neutral, using the methods of
- * database_manager class
- *
- * Please do not forget to use upgrade_set_timeout()
- * before any action that may take longer time to finish.
- *
- * @since 2.0
- * @package blocks
- * @copyright 2012 Mark Nelson <markn@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-/**
- * Handles upgrading instances of this block.
- *
- * @param int $oldversion
- * @param object $block
- */
-function xmldb_block_online_users_upgrade($oldversion, $block) {
- global $DB;
-
- // Moodle v2.4.0 release upgrade line
- // Put any upgrade step following this.
-
- if ($oldversion < 2012112901) {
- // Get the instances of this block.
- if ($blocks = $DB->get_records('block_instances', array('blockname' => 'online_users', 'pagetypepattern' => 'my-index'))) {
- // Loop through and remove them from the My Moodle page.
- foreach ($blocks as $block) {
- blocks_delete_instance($block);
- }
-
- }
-
- // Savepoint reached.
- upgrade_block_savepoint(true, 2012112901, 'online_users');
- }
-
-
- return true;
-}
\ No newline at end of file
$string['configtimetosee'] = 'Number of minutes determining the period of inactivity after which a user is no longer considered to be online.';
$string['online_users:addinstance'] = 'Add a new online users block';
+$string['online_users:myaddinstance'] = 'Add a new online users block to the My Moodle page';
$string['online_users:viewlist'] = 'View list of online users';
$string['periodnminutes'] = 'last {$a} minutes';
$string['pluginname'] = 'Online users';
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2012112901; // The current plugin version (Date: YYYYMMDDXX)
+$plugin->version = 2012112902; // The current plugin version (Date: YYYYMMDDXX)
$plugin->requires = 2012112900; // Requires this Moodle version
$plugin->component = 'block_online_users'; // Full name of the plugin (used for diagnostics)
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->set_url('/blocks/rss_client/editfeed.php', $urlparams);
-$PAGE->set_pagelayout('base');
+$PAGE->set_pagelayout('standard');
if ($rssid) {
$isadding = false;
$PAGE->set_title($strtitle);
$PAGE->set_heading($strtitle);
- $settingsurl = new moodle_url('/admin/settings.php?section=blocksettingrss_client');
$PAGE->navbar->add(get_string('blocks'));
- $PAGE->navbar->add(get_string('pluginname', 'block_rss_client'), $settingsurl);
- $PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'));
+ $PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
+ $PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds );
$PAGE->navbar->add($strtitle);
echo $OUTPUT->header();
$PAGE->set_title($strmanage);
$PAGE->set_heading($strmanage);
-$settingsurl = new moodle_url('/admin/settings.php?section=blocksettingrss_client');
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->navbar->add(get_string('blocks'));
-$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'), $settingsurl);
+$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds);
echo $OUTPUT->header();
$PAGE->set_title($strviewfeed);
$PAGE->set_heading($strviewfeed);
-$settingsurl = new moodle_url('/admin/settings.php?section=blocksettingrss_client');
$managefeeds = new moodle_url('/blocks/rss_client/managefeeds.php', $urlparams);
$PAGE->navbar->add(get_string('blocks'));
-$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'), $settingsurl);
-$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'));
+$PAGE->navbar->add(get_string('pluginname', 'block_rss_client'));
+$PAGE->navbar->add(get_string('managefeeds', 'block_rss_client'), $managefeeds);
$PAGE->navbar->add($strviewfeed);
echo $OUTPUT->header();
const STATE_SAVING = 2;
/** The cache is ready to use. */
const STATE_READY = 3;
+ /** The cache is currently updating itself */
+ const STATE_UPDATING = 4;
/** The cache encountered an error while initialising. */
const STATE_ERROR_INITIALISING = 9;
/** The cache has been disabled. */
*/
public function create_cache(cache_definition $definition) {
$class = $definition->get_cache_class();
- $stores = cache_helper::get_cache_stores($definition);
+ if ($this->is_initialising()) {
+ // Do nothing we just want the dummy store.
+ $stores = array();
+ } else {
+ $stores = cache_helper::get_cache_stores($definition);
+ }
if (count($stores) === 0) {
// Hmm no stores, better provide a dummy store to mimick functionality. The dev will be none the wiser.
$stores[] = $this->create_dummy_store($definition);
$id .= '::'.$aggregate;
}
if (!array_key_exists($id, $this->definitions)) {
- $instance = $this->create_config_instance();
- $definition = $instance->get_definition_by_id($id);
- if (!$definition) {
- $this->reset();
- $instance = $this->create_config_instance(true);
- $instance->update_definitions();
+ // This is the first time this definition has been requested.
+ if ($this->is_initialising()) {
+ // We're initialising the cache right now. Don't try to create another config instance.
+ // We'll just use an ad-hoc cache for the time being.
+ $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area);
+ } else {
+ // Load all the known definitions and find the desired one.
+ $instance = $this->create_config_instance();
$definition = $instance->get_definition_by_id($id);
if (!$definition) {
- throw new coding_exception('The requested cache definition does not exist.'. $id, $id);
+ // Oh-oh the definition doesn't exist.
+ // There are several things that could be going on here.
+ // We may be installing/upgrading a site and have hit a definition that hasn't been used before.
+ // Of the developer may be trying to use a newly created definition.
+ if ($this->is_updating()) {
+ // The cache is presently initialising and the requested cache definition has not been found.
+ // This means that the cache initialisation has requested something from a cache (I had recursive nightmares about this).
+ // To serve this purpose and avoid errors we are going to make use of an ad-hoc cache rather than
+ // search for the definition which would possibly cause an infitite loop trying to initialise the cache.
+ $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area);
+ if ($aggregate !== null) {
+ // If you get here you deserve a warning. We have to use an ad-hoc cache here, so we can't find the definition and therefor
+ // can't find any information about the datasource or any of its aggregated.
+ // Best of luck.
+ debugging('An unknown cache was requested during development with an aggregate that could not be loaded. Ad-hoc cache used instead.', DEBUG_DEVELOPER);
+ $aggregate = null;
+ }
+ } else {
+ // Either a typo of the developer has just created the definition and is using it for the first time.
+ $this->reset();
+ $instance = $this->create_config_instance(true);
+ $instance->update_definitions();
+ $definition = $instance->get_definition_by_id($id);
+ if (!$definition) {
+ throw new coding_exception('The requested cache definition does not exist.'. $id, $id);
+ } else {
+ debugging('Cache definitions reparsed causing cache reset in order to locate definition.
+ You should bump the version number to ensure definitions are reprocessed.', DEBUG_DEVELOPER);
+ }
+ $definition = cache_definition::load($id, $definition, $aggregate);
+ }
} else {
- debugging('Cache definitions reparsed causing cache reset in order to locate definition.
- You should bump the version number to ensure definitions are reprocessed.', DEBUG_DEVELOPER);
+ $definition = cache_definition::load($id, $definition, $aggregate);
}
}
- $this->definitions[$id] = cache_definition::load($id, $definition, $aggregate);
+ $this->definitions[$id] = $definition;
}
return $this->definitions[$id];
}
return true;
}
+ /**
+ * Informs the factory that the cache is currently updating itself.
+ *
+ * This forces the state to upgrading and can only be called once the cache is ready to use.
+ * Calling it ensure we don't try to reinstantite things when requesting cache definitions that don't exist yet.
+ */
+ public function updating_started() {
+ if ($this->state !== self::STATE_READY) {
+ return false;
+ }
+ $this->state = self::STATE_UPDATING;
+ return true;
+ }
+
+ /**
+ * Informs the factory that the upgrading has finished.
+ *
+ * This forces the state back to ready.
+ */
+ public function updating_finished() {
+ $this->state = self::STATE_READY;
+ }
+
/**
* Returns true if the cache API has been disabled.
*
return $this->state === self::STATE_DISABLED;
}
+ /**
+ * Returns true if the cache is currently initialising itself.
+ *
+ * This includes both initialisation and saving the cache config file as part of that initialisation.
+ *
+ * @return bool
+ */
+ public function is_initialising() {
+ return $this->state === self::STATE_INITIALISING || $this->state === self::STATE_SAVING;
+ }
+
+ /**
+ * Returns true if the cache is currently updating itself.
+ *
+ * @return bool
+ */
+ public function is_updating() {
+ return $this->state === self::STATE_UPDATING;
+ }
+
/**
* Disables as much of the cache API as possible.
*
* @param bool $coreonly If set to true only core definitions will be updated.
*/
public static function update_definitions($coreonly = false) {
- $config = self::instance();
+ $factory = cache_factory::instance();
+ $factory->updating_started();
+ $config = $factory->create_config_instance(true);
$config->write_definitions_to_cache(self::locate_definitions($coreonly));
+ $factory->updating_finished();
}
/**
echo '<form id="movecourses" action="category.php" method="post"><div>';
echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
- echo '<table border="0" cellspacing="2" cellpadding="4" class="generalbox boxaligncenter"><tr>';
+ echo '<table border="0" cellspacing="2" cellpadding="4" class="generaltable boxaligncenter"><tr>';
echo '<th class="header" scope="col">'.get_string('courses').'</th>';
if ($editingon) {
echo '<th class="header" scope="col">'.get_string('edit').'</th>';
echo $OUTPUT->paging_bar($totalcount, $page, $perpage, "$url&perpage=$perpage");
$table = new html_table();
- $table->classes = array('logtable','generalbox');
+ $table->classes = array('logtable','generaltable');
$table->align = array('right', 'left', 'left');
$table->head = array(
get_string('time'),
// NOTE: this is legacy stuff, module subtypes are very strongly discouraged!!
$gettypesfunc = $modname.'_get_types';
if (function_exists($gettypesfunc)) {
- if ($types = $gettypesfunc()) {
+ $types = $gettypesfunc();
+ if (is_array($types) && count($types) > 0) {
$group = new stdClass();
$group->name = $modname;
$group->icon = $OUTPUT->pix_icon('icon', '', $modname, array('class' => 'icon'));
$module->archetype = plugin_supports('mod', $modname, FEATURE_MOD_ARCHETYPE, MOD_ARCHETYPE_OTHER);
$modlist[$course->id][$modname] = $module;
}
- $return[$modname] = $modlist[$course->id][$modname];
+ if (isset($modlist[$course->id][$modname])) {
+ $return[$modname] = $modlist[$course->id][$modname];
+ } else {
+ debugging("Invalid module metadata configuration for {$modname}");
+ }
}
return $return;
} else if (!empty($blocklist) and confirm_sesskey()) {
echo "<input type=\"hidden\" name=\"blocklist\" value=\"$blocklist\" /></div>\n";
}
- echo "<table border=\"0\" cellspacing=\"2\" cellpadding=\"4\" class=\"generalbox boxaligncenter\">\n<tr>\n";
+ echo "<table border=\"0\" cellspacing=\"2\" cellpadding=\"4\" class=\"generaltable boxaligncenter\">\n<tr>\n";
echo "<th scope=\"col\">$strcourses</th>\n";
echo "<th scope=\"col\">$strcategory</th>\n";
echo "<th scope=\"col\">$strselect</th>\n";
// Cancel the edit if we lose focus or the escape key is pressed
thisevent = editor.on('blur', cancel_edittitle);
listenevents.push(thisevent);
- thisevent = Y.one('document').on('keyup', function(e) {
- if (e.keyCode == 27) {
+ thisevent = Y.one('document').on('keydown', function(e) {
+ if (e.keyCode === 27) {
+ e.preventDefault();
cancel_edittitle(e);
}
});
Y.extend(ROLE, Y.Base, {
users : [],
roleAssignmentPanel : null,
- panelsubmitevent : null,
rolesLoadedEvent : null,
escCloseEvent : null,
initializer : function(config) {
this.rolesLoadedEvent = this.on('assignablerolesloaded', function(){
this.rolesLoadedEvent.detach();
var panel = this._getRoleAssignmentPanel();
- this.panelsubmitevent = panel.on('submit', this.addRoleCallback, this);
- panel.hide().display(user);
+ panel.hide();
+ panel.submitevent = panel.on('submit', this.addRoleCallback, this);
+ panel.display(user);
}, this);
this._loadAssignableRoles();
},
addRoleCallback : function(e, roleid, userid) {
- this.panelsubmitevent.detach();
var panel = this._getRoleAssignmentPanel();
+ panel.submitevent.detach();
+ panel.submitevent = null;
Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
method:'POST',
data:'id='+this.get(COURSEID)+'&action=assign&sesskey='+M.cfg.sesskey+'&roleid='+roleid+'&user='+userid,
Y.extend(ROLEPANEL, Y.Base, {
user : null,
roles : [],
+ submitevent : null,
initializer : function() {
var i, m = this.get(MANIPULATOR);
var element = Y.Node.create('<div class="enrolpanel roleassign"><div class="container"><div class="header"><h2>'+M.str.role.assignroles+'</h2><div class="close"></div></div><div class="content"></div></div></div>');
this.roles = [];
this.user = null;
this.get('elementNode').removeClass('visible');
+ if (this.submitevent) {
+ this.submitevent.detach();
+ this.submitevent = null;
+ }
this.displayed = false;
return this;
},
$string['cliincorrectvalueretry'] = 'Incorrect value, please retry';
$string['clistatusdisabled'] = 'Status: disabled';
$string['clistatusenabled'] = 'Status: enabled';
+$string['clistatusenabledlater'] = 'status: CLI maintenance mode will be enabled on {$a}';
$string['clitypevalue'] = 'type value';
$string['clitypevaluedefault'] = 'type value, press Enter to use default value ({$a})';
$string['cliunknowoption'] = 'Unrecognised options:
$string['loglifetime'] = 'Keep logs for';
$string['longtimewarning'] = '<b>Please note that this process can take a long time.</b>';
$string['maintenancemode'] = 'In maintenance mode';
+$string['maintenancemodeisscheduled'] = 'Site is switching to maintenance mode in {$a} minutes';
$string['maintfileopenerror'] = 'Error opening maintenance files!';
$string['maintinprogress'] = 'Maintenance is in progress...';
$string['manageformats'] = 'Manage course formats';
$string['sitemaintenancemode'] = 'Maintenance mode';
$string['sitemaintenanceoff'] = 'Maintenance mode has been disabled and the site is running normally again';
$string['sitemaintenanceon'] = 'Your site is currently in maintenance mode (only admins can log in or use the site).';
+$string['sitemaintenanceoncli'] = 'Your site is currently in CLI maintenance mode, no web access is allowed.';
$string['sitemaintenancewarning'] = 'Your site is currently in maintenance mode (only admins can log in). To return this site to normal operation, <a href="maintenance.php">disable maintenance mode</a>.';
$string['sitemaintenancewarning2'] = 'Your site is currently in maintenance mode (only admins can log in). To return this site to normal operation, <a href="{$a}">disable maintenance mode</a>.';
$string['sitepolicies'] = 'Site policies';
$string['err_required'] = 'You must supply a value here.';
$string['general'] = 'General';
$string['hideadvanced'] = 'Hide advanced';
+$string['hideeditortoolbar'] = 'Hide editing tools';
$string['hour'] = 'Hour';
$string['minute'] = 'Minute';
$string['miscellaneoussettings'] = 'Miscellaneous settings';
$string['selectallornone'] = 'Select all/none';
$string['selected'] = 'Selected';
$string['showadvanced'] = 'Show advanced';
+$string['showeditortoolbar'] = 'Show editing tools';
$string['somefieldsrequired'] = 'There are required fields in this form marked {$a}.';
$string['time'] = 'Time';
$string['timeunit'] = 'Time unit';
$string['blockedmessages'] = '{$a} message(s) to/from blocked users';
$string['blockedusers'] = 'Blocked users ({$a})';
$string['blocknoncontacts'] = 'Prevent non-contacts from messaging me';
-$string['contactlistempty'] = 'Your contact list is empty';
+$string['contactlistempty'] = 'Contact list empty';
$string['contacts'] = 'Contacts';
$string['context'] = 'context';
$string['defaultmessageoutputs'] = 'Default message outputs';
$string['messaging'] = 'Messaging';
$string['messagingblockednoncontact'] = '{$a} will not be able to reply as you have blocked non-contacts';
$string['messagingdisabled'] = 'Messaging is disabled on this site, emails will be sent instead';
-$string['mycontacts'] = 'My contacts';
$string['newonlymsg'] = 'Show only new';
$string['newsearch'] = 'New search';
$string['noframesjs'] = 'Use more accessible interface';
$string['technicalinforightsummary'] = 'Right answer summary: {$a}';
$string['technicalinfostate'] = 'Question state: {$a}';
$string['unknownbehaviour'] = 'Unknown behaviour: {$a}.';
+$string['unknownorunhandledtype'] = 'Unknown or unhandled question type: {$a}';
$string['unknownquestion'] = 'Unknown question: {$a}.';
$string['unknownquestioncatregory'] = 'Unknown question category: {$a}.';
$string['unknownquestiontype'] = 'Unknown question type: {$a}.';
$string['role:review'] = 'Review permissions for others';
$string['roleprohibitheader'] = 'Prohibit role';
$string['roleprohibitinfo'] = 'Select a role to be added to the list of prohibited roles in context {$a->context}, capability {$a->cap}:';
+$string['rolerisks'] = 'Role risks';
$string['roles'] = 'Roles';
$string['roles_help'] = 'A role is a collection of permissions defined for the whole system that you can assign to specific users in specific contexts.';
$string['roles_link'] = 'roles';
return INSECURE_DATAROOT_WARNING;
}
+/**
+ * Enables CLI maintenance mode by creating new dataroot/climaintenance.html file.
+ */
+function enable_cli_maintenance_mode() {
+ global $CFG;
+
+ if (file_exists("$CFG->dataroot/climaintenance.html")) {
+ unlink("$CFG->dataroot/climaintenance.html");
+ }
+
+ if (isset($CFG->maintenance_message) and !html_is_blank($CFG->maintenance_message)) {
+ $data = $CFG->maintenance_message;
+ $data = bootstrap_renderer::early_error_content($data, null, null, null);
+ $data = bootstrap_renderer::plain_page(get_string('sitemaintenance', 'admin'), $data);
+
+ } else if (file_exists("$CFG->dataroot/climaintenance.template.html")) {
+ $data = file_get_contents("$CFG->dataroot/climaintenance.template.html");
+
+ } else {
+ $data = get_string('sitemaintenance', 'admin');
+ $data = bootstrap_renderer::early_error_content($data, null, null, null);
+ $data = bootstrap_renderer::plain_page(get_string('sitemaintenance', 'admin'), $data);
+ }
+
+ file_put_contents("$CFG->dataroot/climaintenance.html", $data);
+ chmod("$CFG->dataroot/climaintenance.html", $CFG->filepermissions);
+}
+
/// CLASS DEFINITIONS /////////////////////////////////////////////////////////
$PAGE->requires->js_init_call('M.util.init_colour_picker', array($this->get_id(), $this->previewconfig));
$content = html_writer::start_tag('div', array('class'=>'form-colourpicker defaultsnext'));
$content .= html_writer::tag('div', $OUTPUT->pix_icon('i/loading', get_string('loading', 'admin'), 'moodle', array('class'=>'loadingicon')), array('class'=>'admin_colourpicker clearfix'));
- $content .= html_writer::empty_tag('input', array('type'=>'text','id'=>$this->get_id(), 'name'=>$this->get_full_name(), 'value'=>$this->get_setting(), 'size'=>'12'));
+ $content .= html_writer::empty_tag('input', array('type'=>'text','id'=>$this->get_id(), 'name'=>$this->get_full_name(), 'value'=>$data, 'size'=>'12'));
if (!empty($this->previewconfig)) {
$content .= html_writer::empty_tag('input', array('type'=>'button','id'=>$this->get_id().'_preview', 'value'=>get_string('preview'), 'class'=>'admin_colourpicker_preview'));
}
$relroot = preg_replace('|^http.?://[^/]+|', '', $CFG->wwwroot);
- $css = "/** Unfortunately IE6/7 does not support more than 4096 selectors in one CSS file, which means we have to use some ugly hacks :-( **/";
+ $css = "/** Unfortunately IE6-9 does not support more than 4096 selectors in one CSS file, which means we have to use some ugly hacks :-( **/";
if ($slasharguments) {
$css .= "\n@import url($relroot/styles.php/$themename/$rev/plugins);";
$css .= "\n@import url($relroot/styles.php/$themename/$rev/parents);";
'mode' => cache_store::MODE_APPLICATION,
'simplekeys' => true, // The course id the groupings exist for.
'simpledata' => true, // Array of stdClass objects containing only strings.
- 'persist' => true, // Likely there will be a couple of calls to this.
+ 'persistent' => true, // Likely there will be a couple of calls to this.
'persistmaxsize' => 2, // The original cache used 1, we've increased that to two.
),
// Used to cache calendar subscriptions.
if ($fpoptions) {
$PAGE->requires->js_init_call('M.editor_tinymce.init_filepicker', array($elementid, $fpoptions), true);
}
+ $this->initialise_collapse_js();
}
protected function get_init_params($elementid, array $options=null) {
global $CFG;
return new moodle_url("$CFG->httpswwwroot/lib/editor/tinymce/tiny_mce/$this->version/");
}
+
+ /**
+ * Initialise javascript form elements
+ * @return void
+ */
+ public function initialise_collapse_js() {
+ global $PAGE;
+ // This method is called for every editor instance. Ensure it's only run once.
+ // Static is a clunky solution but the best we could find to keep everything simple and encapsulated.
+ static $isinitialised;
+ if ($isinitialised) {
+ return;
+ }
+
+ // Initialise language strings.
+ $PAGE->requires->strings_for_js(array('hideeditortoolbar', 'showeditortoolbar'), 'form');
+ $PAGE->requires->yui_module('moodle-editor_tinymce-collapse', 'M.editor_collapse.init');
+ $isinitialised = true;
+ }
}
--- /dev/null
+.mform .felement.feditor .toggle_editor_toolbar {background: #EEEEEE;border-color: #BBBBBB;border-radius: 4px 4px 0 0;border-style: solid solid none;border-width: 1px 1px 0;display: inline-block;font-size: 0.7em;padding: 3px 6px;width: 9em;}
+.mform .felement.feditor .mceStatusbar,
+.mform .felement.feditor iframe {min-width: 35em;}
\ No newline at end of file
--- /dev/null
+YUI.add('moodle-editor_tinymce-collapse', function(Y) {
+
+ var COLLAPSE = function() {
+ COLLAPSE.superclass.constructor.apply(this, arguments);
+ };
+
+ Y.extend(COLLAPSE, Y.Base, {
+
+ toggleNodeTemplate : null,
+ /**
+ * Set up basic values for static access.
+ */
+ init : function() {
+ this.initialise_toggles(10);
+ },
+
+ /**
+ * Has TinyMCE been loaded and the editors been initialised?
+ * Designed mainly for IE
+ * @return bool
+ */
+ editors_initialised : function() {
+ return typeof tinyMCE !== 'undefined';
+ },
+
+ initialise_toggles : function(refreshes) {
+ var editors_initialised = this.editors_initialised(), self = this, editor;
+ if (!editors_initialised && refreshes) {
+ setTimeout(function() {
+ self.initialise_toggles(refreshes - 1);
+ }, 100);
+ return;
+ }
+
+ // Create the toggle template for use later
+ this.toggleNodeTemplate = Y.Node.create('<a class="toggle_editor_toolbar" />');
+ this.toggleNodeTemplate.setContent(M.util.get_string('showeditortoolbar', 'form'));
+
+ // Delegate clicks of the toggle_editor_toolbar
+ Y.one('body').delegate('click', this.toggle_collapse_from_event, 'a.toggle_editor_toolbar', this);
+
+ // Set up editors which have already been created
+ for (editor in tinyMCE.editors) {
+ this.setup_collapse(tinyMCE.editors[editor]);
+ }
+
+ // Set up for future editors.
+ // I haven't yet found a way of directly delegating the editor.onInit event. Instead we have to listen for the
+ // tinyMCE.onAddEditor event, and then add a further event listener to the editor's onInit event.
+ // onAddEditor is triggered before the editor has been created.
+ // We use Y.Bind to ensure that context is maintained.
+ tinyMCE.onAddEditor.add(Y.bind(this.add_setup_collapse_listener, this));
+
+ },
+
+ /**
+ * Setup a listener for a new editor which will actually set the editor up
+ * @param {Manager} mgr
+ * @param {Editor} ed
+ */
+ add_setup_collapse_listener : function (mgr, ed) {
+ // Bind the editor.onInit function to set this editor up. This ensures we maintain our context (this)
+ ed.onInit.add(Y.bind(this.setup_collapse, this));
+ },
+
+ /**
+ * Setup the toggle system for the provided editor
+ *
+ * @param {Editor} ed The TinyMCE editor instance
+ */
+ setup_collapse : function(ed) {
+ var textarea = Y.Node(ed.getElement()),
+ editortable = Y.Node(ed.getContainer()).one('> table'),
+ thisToggleNode;
+
+ // Does this text area support collapsing at all?
+ if (!textarea.hasClass('collapsible')) {
+ return;
+ }
+
+ // Did we find an appropriate table to work with
+ if (!editortable) {
+ return;
+ }
+
+ // Add toggle button.
+ thisToggleNode = this.toggleNodeTemplate.cloneNode(true);
+ editortable.get('parentNode').insert(thisToggleNode, editortable);
+
+ // Toggle the toolbars initially.
+ if (Y.Node(ed.getElement()).hasClass('collapsed')) {
+ this.toggle_collapse(thisToggleNode, editortable, 0);
+ } else {
+ this.toggle_collapse(thisToggleNode, editortable, 1);
+ }
+ },
+
+ /**
+ * Toggle the specified editor toolbars.
+ *
+ * @param {Node} button The toggle button which we have to change the text for
+ * @param {Node} editortable The table which the tinyMCE editor is in
+ * @param {Boolean} newstate The intended toggle state
+ */
+ toggle_collapse : function(button, editortable, newstate) {
+ var toolbar = editortable.one('td.mceToolbar').ancestor('tr'),
+ statusbar = editortable.one('.mceStatusbar').ancestor('tr'),
+ editor, iframe, size;
+
+ // Check whether we have a state already.
+ if (typeof newstate === 'undefined') {
+ if (toolbar.getStyle('display') === 'none') {
+ newstate = 1;
+ } else {
+ newstate = 0;
+ }
+ }
+
+ // Toggle the various states and update the button text to suit
+ if (newstate === 0) {
+ toolbar.hide();
+ statusbar.hide();
+ button.setContent(M.util.get_string('showeditortoolbar', 'form'));
+ } else {
+ toolbar.show();
+ statusbar.show();
+ button.setContent(M.util.get_string('hideeditortoolbar', 'form'));
+ }
+
+ // TinyMCE renders the toolbar and path bar as part of the textarea. So toggling these items
+ // changes the required size of the rendered textarea. Frustrating but it's the way it's built.
+ // So we get TinyMCE to resize itself for us. Clunky but it works.
+
+ // Get the tinyMCE editor object for this text area.
+ editorid = editortable.ancestor('div').one('textarea').get('id');
+ editor = tinyMCE.getInstanceById(editorid);
+
+ // Somehow, this editor did not exist.
+ if (!editor) {
+ return;
+ }
+
+ // Resize editor to reflect presence of toolbar and path bar..
+ iframe = editor.getBody();
+ if (iframe) {
+ size = tinymce.DOM.getSize(iframe);
+ // If objects exist resize editor.
+ if (size) {
+ editor.theme.resizeTo(size.w, size.h);
+ }
+ }
+ },
+
+ toggle_collapse_from_event : function(thisevent) {
+ var button = thisevent.target.ancestor('a', true),
+ editortable = thisevent.target.ancestor('span', true).one('table.mceLayout');
+ this.toggle_collapse(button, editortable);
+ }
+ });
+
+ M.editor_collapse = M.editor_collapse || {};
+ M.editor_collapse.init = function(params) {
+ return new COLLAPSE(params);
+ };
+
+}, '@VERSION@', {requires:['base', 'node', 'dom']});
\ No newline at end of file
$zip_archive->close();
$zip_archive->open($archive, file_archive::OPEN);
$this->assertEquals(2, $zip_archive->count());
+ $zip_archive->close();
unlink($archive);
}
$zip_archive->close();
$zip_archive->open($archive, file_archive::OPEN);
$this->assertEquals(1, $zip_archive->count());
+ $zip_archive->close();
unlink($archive);
$zip_archive = new zip_archive();
$zip_archive->close();
$zip_archive->open($archive, file_archive::OPEN);
$this->assertEquals(1, $zip_archive->count());
+ $zip_archive->close();
+
+ unlink($archive);
}
}
case 'ISO-8859-6': $encoding = 'CP720'; break;
case 'ISO-8859-7': $encoding = 'CP737'; break;
case 'ISO-8859-8': $encoding = 'CP862'; break;
+ case 'UTF-8':
+ if ($winchar = get_string('localewincharset', 'langconfig')) {
+ // Most probably works only for zh_cn,
+ // if there are more problems we could add zipcharset to langconfig files.
+ $encoding = $winchar;
+ }
+ break;
}
}
$newname = @textlib::convert($name, $encoding, 'utf-8');
/** @var array options provided to initalize filepicker */
protected $_options = array('subdirs' => 0, 'maxbytes' => 0, 'maxfiles' => 0, 'changeformat' => 0,
'areamaxbytes' => FILE_AREA_MAX_BYTES_UNLIMITED, 'context' => null, 'noclean' => 0, 'trusttext' => 0,
- 'return_types' => 7);
+ 'return_types' => 7, 'collapsible' => 0, 'collapsed' => 0);
// $_options['return_types'] = FILE_INTERNAL | FILE_EXTERNAL | FILE_REFERENCE
/** @var array values for editor */
if (!is_null($this->getAttribute('onblur')) && !is_null($this->getAttribute('onchange'))) {
$editorrules = ' onblur="'.htmlspecialchars($this->getAttribute('onblur')).'" onchange="'.htmlspecialchars($this->getAttribute('onchange')).'"';
}
- $str .= '<div><textarea id="'.$id.'" name="'.$elname.'[text]" rows="'.$rows.'" cols="'.$cols.'"'.$editorrules.'>';
+ $str .= '<div><textarea id="'.$id.'" name="'.$elname.'[text]" rows="'.$rows.'" cols="'.$cols.'"';
+ $classes = array();
+ if (isset($this->_options['collapsed']) && $this->_options['collapsed']) {
+ $this->_options['collapsible'] = 1;
+ $classes[] = 'collapsed';
+ }
+ if (isset($this->_options['collapsible']) && $this->_options['collapsible']) {
+ $classes[] = 'collapsible';
+ }
+ $str .= ' class="' . implode(' ', $classes) . '"';
+ $str .= $editorrules.'>';
$str .= s($text);
$str .= '</textarea></div>';
});
this.overlay.render(Y.one(document.body));
- footerbtn.on('click', this.overlay.hide, this.overlay);
+ footerbtn.on('click', this.close, this);
var boundingBox = this.overlay.get("boundingBox");
},
display_callback : function(content) {
- content = '<div role="alert">' + content + '</div>';
- this.overlay.set('bodyContent', content);
+ var contentnode, heading;
+ contentnode = Y.Node.create('<div role="alert">' + content + '</div>');
+ this.overlay.set('bodyContent', contentnode);
+ heading = contentnode.one('h1');
+ if (heading) {
+ heading.set('tabIndex', 0);
+ heading.focus();
+ }
},
hideContent : function() {
protected $cache;
/** @var int get_string() counter */
protected $countgetstring = 0;
- /** @var int in-memory cache hits counter */
- protected $countmemcache = 0;
- /** @var int on-disk cache hits counter */
- protected $countdiskcache = 0;
/** @var bool use disk cache */
protected $usecache;
/** @var array limit list of translations */
if (!$disablecache and !$disablelocal) {
$string = $this->cache->get($cachekey);
if ($string) {
- $this->countdiskcache++;
return $string;
}
}
public function get_performance_summary() {
return array(array(
'langcountgetstring' => $this->countgetstring,
- 'langcountmemcache' => $this->countmemcache,
- 'langcountdiskcache' => $this->countdiskcache,
), array(
'langcountgetstring' => 'get_string calls',
- 'langcountmemcache' => 'strings mem cache hits',
- 'langcountdiskcache' => 'strings disk cache hits',
));
}
if (!empty($CFG->messaging)) {
$messageargs = null;
- if ($USER->id!=$user->id) {
- $messageargs = array('id'=>$user->id);
+ if ($USER->id != $user->id) {
+ $messageargs = array('user1' => $user->id);
}
$url = new moodle_url('/message/index.php',$messageargs);
$usernode->add(get_string('messages', 'message'), $url, self::TYPE_SETTING, null, 'messages');
if (!empty($CFG->additionalhtmltopofbody)) {
$output .= "\n".$CFG->additionalhtmltopofbody;
}
+ $output .= $this->maintenance_warning();
+ return $output;
+ }
+
+ /**
+ * Scheduled maintenance warning message.
+ *
+ * Note: This is a nasty hack to display maintenance notice, this should be moved
+ * to some general notification area once we have it.
+ *
+ * @return string
+ */
+ public function maintenance_warning() {
+ global $CFG;
+
+ $output = '';
+ if (isset($CFG->maintenance_later) and $CFG->maintenance_later > time()) {
+ $output .= $this->box_start('errorbox maintenancewarning');
+ $output .= get_string('maintenancemodeisscheduled', 'admin', (int)(($CFG->maintenance_later-time())/60));
+ $output .= $this->box_end();
+ }
return $output;
}
if (!isset($CFG->phpunit_dataroot)) {
phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, 'Missing $CFG->phpunit_dataroot in config.php, can not run tests!');
}
-// Ensure we access to phpunit_dataroot realpath always.
-$CFG->phpunit_dataroot = realpath($CFG->phpunit_dataroot);
-if (isset($CFG->dataroot) and $CFG->phpunit_dataroot === $CFG->dataroot) {
- phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, '$CFG->dataroot and $CFG->phpunit_dataroot must not be identical, can not run tests!');
-}
+// Create test dir if does not exists yet.
if (!file_exists($CFG->phpunit_dataroot)) {
mkdir($CFG->phpunit_dataroot, $CFG->directorypermissions);
}
phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, '$CFG->phpunit_dataroot directory can not be created, can not run tests!');
}
+// Ensure we access to phpunit_dataroot realpath always.
+$CFG->phpunit_dataroot = realpath($CFG->phpunit_dataroot);
+
+if (isset($CFG->dataroot) and $CFG->phpunit_dataroot === $CFG->dataroot) {
+ phpunit_bootstrap_error(PHPUNIT_EXITCODE_CONFIGERROR, '$CFG->dataroot and $CFG->phpunit_dataroot must not be identical, can not run tests!');
+}
+
if (!is_writable($CFG->phpunit_dataroot)) {
// try to fix permissions if possible
if (function_exists('posix_getuid')) {
}
}
+// Switch to CLI maintenance mode if required, we need to do it here after all the settings are initialised.
+if (isset($CFG->maintenance_later) and $CFG->maintenance_later <= time()) {
+ if (!file_exists("$CFG->dataroot/climaintenance.html")) {
+ require_once("$CFG->libdir/adminlib.php");
+ enable_cli_maintenance_mode();
+ }
+ unset_config('maintenance_later');
+ if (AJAX_SCRIPT) {
+ die;
+ } else if (!CLI_SCRIPT) {
+ redirect(new moodle_url('/'));
+ }
+}
// note: we can not block non utf-8 installations here, because empty mysql database
// might be converted to utf-8 in admin/index.php during installation
* @param string $meta meta tag
* @return string html page
*/
- protected static function plain_page($title, $content, $meta = '') {
+ public static function plain_page($title, $content, $meta = '') {
if (function_exists('get_string') && function_exists('get_html_lang')) {
$htmllang = get_html_lang();
} else {
$htmllang = '';
}
- return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" ' . $htmllang . '>
+ return '<!DOCTYPE html>
+<html ' . $htmllang . '>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
'.$meta.'
this.listenevents.push(thisevent);
// Grab global keyup events and handle them
- thisevent = Y.one('document').on('keyup', this.handle_key_press, this);
+ thisevent = Y.one('document').on('keydown', this.handle_key_press, this);
this.listenevents.push(thisevent);
// Add references to various elements we adjust
//if they have numerous contacts or are viewing course participants we might need to page through them
$page = optional_param('page', 0, PARAM_INT);
-$url = new moodle_url('/message/index.php');
+$url = new moodle_url('/message/index.php', array('user1' => $user1id));
if ($user2id !== 0) {
$url->param('user2', $user2id);
-}
-if ($user2id !== 0) {
//Switch view back to contacts if:
//1) theyve searched and selected a user
//2) they've viewed recent messages or notifications and clicked through to a user
- if ($viewing == MESSAGE_VIEW_SEARCH || $viewing == MESSAGE_VIEW_SEARCH || $viewing == MESSAGE_VIEW_RECENT_NOTIFICATIONS) {
+ if ($viewing == MESSAGE_VIEW_SEARCH || $viewing == MESSAGE_VIEW_RECENT_NOTIFICATIONS) {
$viewing = MESSAGE_VIEW_CONTACTS;
}
}
-$url->param('viewing', $viewing);
+
+if ($viewing != MESSAGE_VIEW_UNREAD_MESSAGES) {
+ $url->param('viewing', $viewing);
+}
$PAGE->set_url($url);
-$PAGE->set_context(context_user::instance($USER->id));
-$PAGE->navigation->extend_for_user($USER);
-$PAGE->set_pagelayout('course');
+$navigationurl = new moodle_url('/message/index.php', array('user1' => $user1id));
+navigation_node::override_active_url($navigationurl);
// Disable message notification popups while the user is viewing their messages
$PAGE->set_popup_notification_allowed(false);
-$context = context_system::instance();
-
$user1 = null;
$currentuser = true;
-$showcontactactionlinks = true;
+$showactionlinks = true;
if ($user1id != $USER->id) {
$user1 = $DB->get_record('user', array('id' => $user1id));
if (!$user1) {
print_error('invaliduserid');
}
$currentuser = false;//if we're looking at someone else's messages we need to lock/remove some UI elements
- $showcontactactionlinks = false;
+ $showactionlinks = false;
} else {
$user1 = $USER;
}
}
unset($user2id);
+$systemcontext = context_system::instance();
+
// Is the user involved in the conversation?
// Do they have the ability to read other user's conversations?
-if (!message_current_user_is_involved($user1, $user2) && !has_capability('moodle/site:readallmessages', $context)) {
+if (!message_current_user_is_involved($user1, $user2) && !has_capability('moodle/site:readallmessages', $systemcontext)) {
print_error('accessdenied','admin');
}
+$PAGE->set_context(context_user::instance($user1->id));
+$PAGE->set_pagelayout('course');
+$PAGE->navigation->extend_for_user($user1);
+
/// Process any contact maintenance requests there may be
if ($addcontact and confirm_sesskey()) {
add_to_log(SITEID, 'message', 'add contact', 'index.php?user1='.$addcontact.'&user2='.$USER->id, $addcontact);
//was a message sent? Do NOT allow someone looking at someone else's messages to send them.
$messageerror = null;
-if ($currentuser && !empty($user2) && has_capability('moodle/site:sendmessage', $context)) {
+if ($currentuser && !empty($user2) && has_capability('moodle/site:sendmessage', $systemcontext)) {
// Check that the user is not blocking us!!
if ($contact = $DB->get_record('message_contacts', array('userid' => $user2->id, 'contactid' => $user1->id))) {
- if ($contact->blocked and !has_capability('moodle/site:readallmessages', $context)) {
+ if ($contact->blocked and !has_capability('moodle/site:readallmessages', $systemcontext)) {
$messageerror = get_string('userisblockingyou', 'message');
}
}
}
$countunreadtotal = message_count_unread_messages($user1);
-if ($countunreadtotal == 0 && $viewing == MESSAGE_VIEW_UNREAD_MESSAGES && empty($user2)) {
- //default to showing the search
+if ($currentuser && $countunreadtotal == 0 && $viewing == MESSAGE_VIEW_UNREAD_MESSAGES && empty($user2)) {
+ // If the user has no unread messages, show the search box.
+ // We don't do this when a user is viewing another user's messages as search doesn't
+ // handle user A searching user B's messages properly.
$viewing = MESSAGE_VIEW_SEARCH;
}
list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts($user1, $user2);
-message_print_contact_selector($countunreadtotal, $viewing, $user1, $user2, $blockedusers, $onlinecontacts, $offlinecontacts, $strangers, $showcontactactionlinks, $page);
+message_print_contact_selector($countunreadtotal, $viewing, $user1, $user2, $blockedusers, $onlinecontacts, $offlinecontacts, $strangers, $showactionlinks, $page);
echo html_writer::start_tag('div', array('class' => 'messagearea mdl-align'));
if (!empty($user2)) {
$messagehistorylink .= html_writer::end_tag('div');
- message_print_message_history($user1, $user2, $search, $displaycount, $messagehistorylink, $viewingnewmessages);
+ message_print_message_history($user1, $user2, $search, $displaycount, $messagehistorylink, $viewingnewmessages, $showactionlinks);
echo html_writer::end_tag('div');
//send message form
- if ($currentuser && has_capability('moodle/site:sendmessage', $context)) {
+ if ($currentuser && has_capability('moodle/site:sendmessage', $systemcontext)) {
echo html_writer::start_tag('div', array('class' => 'mdl-align messagesend'));
if (!empty($messageerror)) {
echo html_writer::tag('span', $messageerror, array('id' => 'messagewarning'));
} else if ($viewing == MESSAGE_VIEW_SEARCH) {
message_print_search($advancedsearch, $user1);
} else if ($viewing == MESSAGE_VIEW_RECENT_CONVERSATIONS) {
- message_print_recent_conversations($user1);
+ message_print_recent_conversations($user1, false, $showactionlinks);
} else if ($viewing == MESSAGE_VIEW_RECENT_NOTIFICATIONS) {
message_print_recent_notifications($user1);
}
* @param array $onlinecontacts an array of $user1's online contacts
* @param array $offlinecontacts an array of $user1's offline contacts
* @param array $strangers an array of users who have messaged $user1 who aren't contacts
- * @param bool $showcontactactionlinks show action links (add/remove contact etc) next to the users in the contact selector
+ * @param bool $showactionlinks show action links (add/remove contact etc)
* @param int $page if there are so many users listed that they have to be split into pages what page are we viewing
* @return void
*/
-function message_print_contact_selector($countunreadtotal, $viewing, $user1, $user2, $blockedusers, $onlinecontacts, $offlinecontacts, $strangers, $showcontactactionlinks, $page=0) {
+function message_print_contact_selector($countunreadtotal, $viewing, $user1, $user2, $blockedusers, $onlinecontacts, $offlinecontacts, $strangers, $showactionlinks, $page=0) {
global $PAGE;
echo html_writer::start_tag('div', array('class' => 'contactselector mdl-align'));
$strunreadmessages = get_string('unreadmessages','message', $countunreadtotal);
}
- message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, count($blockedusers), $strunreadmessages);
+ message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, count($blockedusers), $strunreadmessages, $user1);
if ($viewing == MESSAGE_VIEW_UNREAD_MESSAGES) {
- message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $PAGE->url, 1, $showcontactactionlinks,$strunreadmessages, $user2);
+ message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $PAGE->url, 1, $showactionlinks,$strunreadmessages, $user2);
} else if ($viewing == MESSAGE_VIEW_CONTACTS || $viewing == MESSAGE_VIEW_SEARCH || $viewing == MESSAGE_VIEW_RECENT_CONVERSATIONS || $viewing == MESSAGE_VIEW_RECENT_NOTIFICATIONS) {
- message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $PAGE->url, 0, $showcontactactionlinks, $strunreadmessages, $user2);
+ message_print_contacts($onlinecontacts, $offlinecontacts, $strangers, $PAGE->url, 0, $showactionlinks, $strunreadmessages, $user2);
} else if ($viewing == MESSAGE_VIEW_BLOCKED) {
- message_print_blocked_users($blockedusers, $PAGE->url, $showcontactactionlinks, null, $user2);
+ message_print_blocked_users($blockedusers, $PAGE->url, $showactionlinks, null, $user2);
} else if (substr($viewing, 0, 7) == MESSAGE_VIEW_COURSE) {
$courseidtoshow = intval(substr($viewing, 7));
&& array_key_exists($courseidtoshow, $coursecontexts)
&& has_capability('moodle/course:viewparticipants', $coursecontexts[$courseidtoshow])) {
- message_print_participants($coursecontexts[$courseidtoshow], $courseidtoshow, $PAGE->url, $showcontactactionlinks, null, $page, $user2);
+ message_print_participants($coursecontexts[$courseidtoshow], $courseidtoshow, $PAGE->url, $showactionlinks, null, $page, $user2);
} else {
//shouldn't get here. User trying to access a course they're not in perhaps.
add_to_log(SITEID, 'message', 'view', 'index.php', $viewing);
}
}
- echo html_writer::start_tag('form', array('action' => 'index.php','method' => 'GET'));
- echo html_writer::start_tag('fieldset');
- $managebuttonclass = 'visible';
- if ($viewing == MESSAGE_VIEW_SEARCH) {
- $managebuttonclass = 'hiddenelement';
+ // Only show the search button if we're viewing our own messages.
+ // Search isn't currently able to deal with user A wanting to search user B's messages.
+ if ($showactionlinks) {
+ echo html_writer::start_tag('form', array('action' => 'index.php','method' => 'GET'));
+ echo html_writer::start_tag('fieldset');
+ $managebuttonclass = 'visible';
+ if ($viewing == MESSAGE_VIEW_SEARCH) {
+ $managebuttonclass = 'hiddenelement';
+ }
+ $strmanagecontacts = get_string('search','message');
+ echo html_writer::empty_tag('input', array('type' => 'hidden','name' => 'viewing','value' => MESSAGE_VIEW_SEARCH));
+ echo html_writer::empty_tag('input', array('type' => 'submit','value' => $strmanagecontacts,'class' => $managebuttonclass));
+ echo html_writer::end_tag('fieldset');
+ echo html_writer::end_tag('form');
}
- $strmanagecontacts = get_string('search','message');
- echo html_writer::empty_tag('input', array('type' => 'hidden','name' => 'viewing','value' => MESSAGE_VIEW_SEARCH));
- echo html_writer::empty_tag('input', array('type' => 'submit','value' => $strmanagecontacts,'class' => $managebuttonclass));
- echo html_writer::end_tag('fieldset');
- echo html_writer::end_tag('form');
echo html_writer::end_tag('div');
}
}
if($countonlinecontacts) {
- /// print out list of online contacts
+ // Print out list of online contacts.
if (empty($titletodisplay)) {
message_print_heading(get_string('onlinecontacts', 'message', $countonlinecontacts));
}
if ($countofflinecontacts) {
- /// print out list of offline contacts
+ // Print out list of offline contacts.
if (empty($titletodisplay)) {
message_print_heading(get_string('offlinecontacts', 'message', $countofflinecontacts));
}
- /// print out list of incoming contacts
+ // Print out list of incoming contacts.
if ($countstrangers) {
message_print_heading(get_string('incomingcontacts', 'message', $countstrangers));
* @param array $coursecontexts array of course contexts. Keyed on course id.
* @param int $countunreadtotal how many unread messages does the user have?
* @param int $countblocked how many users has the current user blocked?
+ * @param stdClass $user1 The user whose messages we are viewing.
* @param string $strunreadmessages a preconstructed message about the number of unread messages the user has
* @return void
*/
-function message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, $countblocked, $strunreadmessages) {
+function message_print_usergroup_selector($viewing, $courses, $coursecontexts, $countunreadtotal, $countblocked, $strunreadmessages, $user1 = null) {
$options = array();
if ($countunreadtotal>0) { //if there are unread messages
$options[MESSAGE_VIEW_UNREAD_MESSAGES] = $strunreadmessages;
}
- $str = get_string('mycontacts', 'message');
+ $str = get_string('contacts', 'message');
$options[MESSAGE_VIEW_CONTACTS] = $str;
$options[MESSAGE_VIEW_RECENT_CONVERSATIONS] = get_string('mostrecentconversations', 'message');
echo html_writer::start_tag('form', array('id' => 'usergroupform','method' => 'get','action' => ''));
echo html_writer::start_tag('fieldset');
+ if ( !empty($user1) && !empty($user1->id) ) {
+ echo html_writer::empty_tag('input', array('type' => 'hidden','name' => 'user1','value' => $user1->id));
+ }
echo html_writer::label(get_string('messagenavigation', 'message'), 'viewing');
echo html_writer::select($options, 'viewing', $viewing, false, array('id' => 'viewing','onchange' => 'this.form.submit()'));
echo html_writer::end_tag('fieldset');
* @param stdClass $user the current user
* @param bool $showicontext flag indicating whether or not to show text next to the action icons
*/
-function message_print_recent_conversations($user=null, $showicontext=false) {
+function message_print_recent_conversations($user1 = null, $showicontext = false, $showactionlinks = true) {
global $USER;
echo html_writer::start_tag('p', array('class' => 'heading'));
echo get_string('mostrecentconversations', 'message');
echo html_writer::end_tag('p');
- if (empty($user)) {
- $user = $USER;
+ if (empty($user1)) {
+ $user1 = $USER;
}
- $conversations = message_get_recent_conversations($user);
+ $conversations = message_get_recent_conversations($user1);
// Attach context url information to create the "View this conversation" type links
foreach($conversations as $conversation) {
- $conversation->contexturl = new moodle_url("/message/index.php?user2={$conversation->id}");
+ $conversation->contexturl = new moodle_url("/message/index.php?user1={$user1->id}&user2={$conversation->id}");
$conversation->contexturlname = get_string('thisconversation', 'message');
}
$showotheruser = true;
- message_print_recent_messages_table($conversations, $user, $showotheruser, $showicontext);
+ message_print_recent_messages_table($conversations, $user1, $showotheruser, $showicontext, false, $showactionlinks);
}
/**
* @param bool $forcetexttohtml Force text to go through @see text_to_html() via @see format_text()
* @return void
*/
-function message_print_recent_messages_table($messages, $user=null, $showotheruser=true, $showicontext=false, $forcetexttohtml=false) {
+function message_print_recent_messages_table($messages, $user = null, $showotheruser = true, $showicontext = false, $forcetexttohtml = false, $showactionlinks = true) {
global $OUTPUT;
static $dateformat;
echo html_writer::start_tag('div', array('class' => 'singlemessage'));
if ($showotheruser) {
- if ( $message->contactlistid ) {
- if ($message->blocked == 0) { /// not blocked
- $strcontact = message_contact_link($message->id, 'remove', true, null, $showicontext);
- $strblock = message_contact_link($message->id, 'block', true, null, $showicontext);
- } else { // blocked
+ $strcontact = $strblock = $strhistory = null;
+
+ if ($showactionlinks) {
+ if ( $message->contactlistid ) {
+ if ($message->blocked == 0) { // The other user isn't blocked.
+ $strcontact = message_contact_link($message->id, 'remove', true, null, $showicontext);
+ $strblock = message_contact_link($message->id, 'block', true, null, $showicontext);
+ } else { // The other user is blocked.
+ $strcontact = message_contact_link($message->id, 'add', true, null, $showicontext);
+ $strblock = message_contact_link($message->id, 'unblock', true, null, $showicontext);
+ }
+ } else {
$strcontact = message_contact_link($message->id, 'add', true, null, $showicontext);
- $strblock = message_contact_link($message->id, 'unblock', true, null, $showicontext);
+ $strblock = message_contact_link($message->id, 'block', true, null, $showicontext);
}
- } else {
- $strcontact = message_contact_link($message->id, 'add', true, null, $showicontext);
- $strblock = message_contact_link($message->id, 'block', true, null, $showicontext);
- }
- //should we show just the icon or icon and text?
- $histicontext = 'icon';
- if ($showicontext) {
- $histicontext = 'both';
+ //should we show just the icon or icon and text?
+ $histicontext = 'icon';
+ if ($showicontext) {
+ $histicontext = 'both';
+ }
+ $strhistory = message_history_link($user->id, $message->id, true, '', '', $histicontext);
}
- $strhistory = message_history_link($user->id, $message->id, true, '', '', $histicontext);
-
echo html_writer::start_tag('span', array('class' => 'otheruser'));
echo html_writer::start_tag('span', array('class' => 'pix'));
echo html_writer::start_tag('span', array('class' => 'contact'));
- $link = new moodle_url("/message/index.php?id=$message->id");
+ $link = new moodle_url("/message/index.php?user1={$user->id}&user2=$message->id");
$action = null;
echo $OUTPUT->action_link($link, fullname($message), $action, array('title' => get_string('sendmessageto', 'message', fullname($message))));
echo html_writer::end_tag('span');//end contact
- echo $strcontact.$strblock.$strhistory;
+ if ($showactionlinks) {
+ echo $strcontact.$strblock.$strhistory;
+ }
echo html_writer::end_tag('span');//end otheruser
}
$messagetoprint = null;
}
if (($contact = $DB->get_record('message_contacts', array('userid' => $USER->id, 'contactid' => $contactid))) !== false) {
- /// record already exists - we may be changing blocking status
+ // A record already exists. We may be changing blocking status.
if ($contact->blocked !== $blocked) {
- /// change to blocking status
+ // Blocking status has been changed.
$contact->blocked = $blocked;
return $DB->update_record('message_contacts', $contact);
} else {
- /// no changes to blocking status
+ // No change to blocking status.
return true;
}
} else {
- /// new contact record
+ // New contact record.
$contact = new stdClass();
$contact->userid = $USER->id;
$contact->contactid = $contactid;
$personsearchstring = $frm->combinedsearch;
}
- /// search for person
+ // Search for person.
if ($personsearch) {
if (optional_param('mycourses', 0, PARAM_BOOL)) {
$users = array();
foreach ($users as $user) {
if ( $user->contactlistid ) {
- if ($user->blocked == 0) { /// not blocked
+ if ($user->blocked == 0) { // User is not blocked.
$strcontact = message_contact_link($user->id, 'remove', true, null, $showicontext);
$strblock = message_contact_link($user->id, 'block', true, null, $showicontext);
} else { // blocked
$strblock = message_contact_link($user->id, 'block', true, null, $showicontext);
}
- //should we show just the icon or icon and text?
+ // Should we show just the icon or icon and text?
$histicontext = 'icon';
if ($showicontext) {
$histicontext = 'both';
if (($messages = message_search($keywords, $fromme, $tome, $courseid)) !== false) {
- /// get a list of contacts
+ // Get a list of contacts.
if (($contacts = $DB->get_records('message_contacts', array('userid' => $USER->id), '', 'contactid, blocked') ) === false) {
$contacts = array();
}
- /// print heading with number of results
+ // Print heading with number of results.
echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
$countresults = count($messages);
if ($countresults == MESSAGE_SEARCH_MAX_RESULTS) {
}
echo html_writer::end_tag('p');
- /// print table headings
+ // Print table headings.
echo html_writer::start_tag('table', array('class' => 'messagesearchresults', 'cellspacing' => '0'));
$headertdstart = html_writer::start_tag('td', array('class' => 'messagesearchresultscol'));
$strcontext = get_string('context', 'message');
foreach ($messages as $message) {
- /// ignore messages to and from blocked users unless $frm->includeblocked is set
+ // Ignore messages to and from blocked users unless $frm->includeblocked is set.
if (!optional_param('includeblocked', 0, PARAM_BOOL) and (
( isset($contacts[$message->useridfrom]) and ($contacts[$message->useridfrom]->blocked == 1)) or
( isset($contacts[$message->useridto] ) and ($contacts[$message->useridto]->blocked == 1))
continue;
}
- /// load up user to record
+ // Load user-to record.
if ($message->useridto !== $USER->id) {
$userto = $DB->get_record('user', array('id' => $message->useridto));
$tocontact = (array_key_exists($message->useridto, $contacts) and
$toblocked = false;
}
- /// load up user from record
+ // Load user-from record.
if ($message->useridfrom !== $USER->id) {
$userfrom = $DB->get_record('user', array('id' => $message->useridfrom));
$fromcontact = (array_key_exists($message->useridfrom, $contacts) and
$fromblocked = false;
}
- /// find date string for this message
+ // Find date string for this message.
$date = usergetdate($message->timecreated);
$datestring = $date['year'].$date['mon'].$date['mday'];
- /// print out message row
+ // Print out message row.
echo html_writer::start_tag('tr', array('valign' => 'top'));
echo html_writer::start_tag('td', array('class' => 'contact'));
echo message_get_fragment($message->smallmessage, $keywords);
echo html_writer::start_tag('div', array('class' => 'link'));
- //If the user clicks the context link display message sender on the left
- //EXCEPT if the current user is in the conversation. Current user == always on the left
+ // If the user clicks the context link display message sender on the left.
+ // EXCEPT if the current user is in the conversation. Current user == always on the left.
$leftsideuserid = $rightsideuserid = null;
if ($currentuser->id == $message->useridto) {
$leftsideuserid = $message->useridto;
}
/**
- * search a user's messages
+ * Search a user's messages
+ *
+ * Returns a list of posts found using an array of search terms
+ * eg word +word -word
*
* @param array $searchterms an array of search terms (strings)
* @param bool $fromme include messages from the user?
* @return mixed An array of messages or false if no matching messages were found
*/
function message_search($searchterms, $fromme=true, $tome=true, $courseid='none', $userid=0) {
-/// Returns a list of posts found using an array of search terms
-/// eg word +word -word
-///
global $CFG, $USER, $DB;
- // If user is searching all messages check they are allowed to before doing anything else
+ // If user is searching all messages check they are allowed to before doing anything else.
if ($courseid == SITEID && !has_capability('moodle/site:readallmessages', context_system::instance())) {
print_error('accessdenied','admin');
}
- /// If no userid sent then assume current user
+ // If no userid sent then assume current user.
if ($userid == 0) $userid = $USER->id;
- /// Some differences in SQL syntax
+ // Some differences in SQL syntax.
if ($DB->sql_regex_supported()) {
$REGEXP = $DB->sql_regex(true);
$NOTREGEXP = $DB->sql_regex(false);
$params = array();
$i = 0;
- //preprocess search terms to check whether we have at least 1 eligible search term
- //if we do we can drop words around it like 'a'
+ // Preprocess search terms to check whether we have at least 1 eligible search term.
+ // If we do we can drop words around it like 'a'.
$dropshortwords = false;
foreach ($searchterms as $searchterm) {
if (strlen($searchterm) >= 2) {
foreach ($searchterms as $searchterm) {
$i++;
- $NOT = false; /// Initially we aren't going to perform NOT LIKE searches, only MSSQL and Oracle
+ $NOT = false; // Initially we aren't going to perform NOT LIKE searches, only MSSQL and Oracle.
if ($dropshortwords && strlen($searchterm) < 2) {
continue;
}
- /// Under Oracle and MSSQL, trim the + and - operators and perform
- /// simpler LIKE search
+ // Under Oracle and MSSQL, trim the + and - operators and perform simpler LIKE search.
if (!$DB->sql_regex_supported()) {
if (substr($searchterm, 0, 1) == '-') {
$NOT = true;
$searchcond = implode(" AND ", $searchcond);
}
- /// There are several possibilities
- /// 1. courseid = SITEID : The admin is searching messages by all users
- /// 2. courseid = ?? : A teacher is searching messages by users in
- /// one of their courses - currently disabled
- /// 3. courseid = none : User is searching their own messages;
- /// a. Messages from user
- /// b. Messages to user
- /// c. Messages to and from user
+ // There are several possibilities
+ // 1. courseid = SITEID : The admin is searching messages by all users
+ // 2. courseid = ?? : A teacher is searching messages by users in
+ // one of their courses - currently disabled
+ // 3. courseid = none : User is searching their own messages;
+ // a. Messages from user
+ // b. Messages to user
+ // c. Messages to and from user
- if ($courseid == SITEID) { /// admin is searching all messages
+ if ($courseid == SITEID) { // Admin is searching all messages.
$m_read = $DB->get_records_sql("SELECT m.id, m.useridto, m.useridfrom, m.smallmessage, m.fullmessage, m.timecreated
FROM {message_read} m
WHERE $searchcond", $params, 0, MESSAGE_SEARCH_MAX_RESULTS);
WHERE $searchcond", $params, 0, MESSAGE_SEARCH_MAX_RESULTS);
} else if ($courseid !== 'none') {
- /// This has not been implemented due to security concerns
+ // This has not been implemented due to security concerns.
$m_read = array();
$m_unread = array();
* @param string $messagehistorylink the html for the message history link or false
* @param bool $viewingnewmessages are we currently viewing new messages?
*/
-function message_print_message_history($user1,$user2,$search='',$messagelimit=0, $messagehistorylink=false, $viewingnewmessages=false) {
+function message_print_message_history($user1, $user2 ,$search = '', $messagelimit = 0, $messagehistorylink = false, $viewingnewmessages = false, $showactionlinks = true) {
global $CFG, $OUTPUT;
echo $OUTPUT->box_start('center');
echo $OUTPUT->user_picture($user2, array('size' => 100, 'courseid' => SITEID));
echo html_writer::tag('div', fullname($user2), array('class' => 'heading'));
- if (isset($user2->iscontact) && isset($user2->isblocked)) {
- $incontactlist = $user2->iscontact;
- $isblocked = $user2->isblocked;
+ if ($showactionlinks && isset($user2->iscontact) && isset($user2->isblocked)) {
$script = null;
$text = true;
$icon = false;
- $strcontact = message_get_contact_add_remove_link($incontactlist, $isblocked, $user2, $script, $text, $icon);
- $strblock = message_get_contact_block_link($incontactlist, $isblocked, $user2, $script, $text, $icon);
+ $strcontact = message_get_contact_add_remove_link($user2->iscontact, $user2->isblocked, $user2, $script, $text, $icon);
+ $strblock = message_get_contact_block_link($user2->iscontact, $user2->isblocked, $user2, $script, $text, $icon);
$useractionlinks = $strcontact.' |'.$strblock;
echo html_writer::tag('div', $useractionlinks, array('class' => 'useractionlinks'));
$linkclass = 'messageselecteduser';
}
- /// are there any unread messages for this contact?
+ // Are there any unread messages for this contact?
if ($contact->messagecount > 0 ){
$fullnamelink = '<strong>'.$fullnamelink.' ('.$contact->messagecount.')</strong>';
}
global $DB, $USER, $CFG;
$this->resetAfterTest(true);
+ // Transactions used in tests, tell phpunit use alternative reset method.
+ $this->preventResetByRollback();
// Turn off all message processors (so nothing is really sent)
require_once($CFG->dirroot . '/message/lib.php');
if ($item->hasvalue == 0) {
continue;
}
- echo '<table width="100%" class="generalbox">';
+ echo '<table width="100%" class="generaltable">';
//get the class of item-typ
$itemobj = feedback_get_item_class($item->typ);
if ($item->hasvalue == 0) {
continue;
}
- echo '<table width="100%" class="generalbox">';
+ echo '<table width="100%" class="generaltable">';
//get the class from item-typ
$itemobj = feedback_get_item_class($item->typ);
$itemnr++;
$tmpactivity->sectionnum= $cm->sectionnum;
$tmpactivity->timestamp = $feedbackitem->timemodified;
+ $tmpactivity->content = new stdClass();
$tmpactivity->content->feedbackid = $feedbackitem->id;
$tmpactivity->content->feedbackuserid = $feedbackitem->userid;
- //TODO: add all necessary user fields, this is not enough for user_picture
- $tmpactivity->user->userid = $feedbackitem->userid;
+ $userfields = explode(',', user_picture::fields());
+ $tmpactivity->user = new stdClass();
+ foreach ($userfields as $userfield) {
+ if ($userfield == 'id') {
+ $tmpactivity->user->{$userfield} = $feedbackitem->userid; // aliased in SQL above
+ } else {
+ if (!empty($feedbackitem->{$userfield})) {
+ $tmpactivity->user->{$userfield} = $feedbackitem->{$userfield};
+ } else {
+ $tmpactivity->user->{$userfield} = null;
+ }
+ }
+ }
$tmpactivity->user->fullname = fullname($feedbackitem, $viewfullnames);
- $tmpactivity->user->picture = $feedbackitem->picture;
$activities[$index++] = $tmpactivity;
}
echo '</div>';
echo '<div class="user">';
- echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->userid}&course=$courseid\">"
+ echo "<a href=\"$CFG->wwwroot/user/view.php?id={$activity->user->id}&course=$courseid\">"
."{$activity->user->fullname}</a> - ".userdate($activity->timestamp);
echo '</div>';
*/
function forum_get_course_forum($courseid, $type) {
// How to set up special 1-per-course forums
- global $CFG, $DB, $OUTPUT;
+ global $CFG, $DB, $OUTPUT, $USER;
if ($forums = $DB->get_records_select("forum", "course = ? AND type = ?", array($courseid, $type), "id ASC")) {
// There should always only be ONE, but with the right combination of
$forum = new stdClass();
$forum->course = $courseid;
$forum->type = "$type";
+ if (!empty($USER->htmleditor)) {
+ $forum->introformat = $USER->htmleditor;
+ }
switch ($forum->type) {
case "news":
$forum->name = get_string("namenews", "forum");
<div class="boxaligncenter">
<form id="form" method="post" action="editcategories.php">
<div>
-<table class="generalbox" cellpadding="5">
+<table class="generaltable" cellpadding="5">
<tr valign="top">
<td align="right"><label for="name"><?php echo get_string("name") ?>:</label></td>
<td>
?>
<form method="post" action="editcategories.php">
-<table width="40%" class="boxaligncenter generalbox" cellpadding="5">
+<table width="40%" class="boxaligncenter generaltable" cellpadding="5">
<tr>
<th style="width:90%" align="center">
<?php p(get_string("categories","glossary")) ?></th>
$no = get_string("no");
echo '<form method="post" action="formats.php" id="form">';
-echo '<table width="90%" align="center" class="generalbox">';
+echo '<table width="90%" align="center" class="generaltable">';
?>
<tr>
<td colspan="3" align="center"><strong>
}
- function readquestion($lines) {
+ protected function readquestion($lines) {
/// Given an array of lines known to define a question in
/// this format, this function converts it into a question
/// object suitable for processing and insertion into Moodle.
echo '<div class="questionbankwindow ' . $bankclass . 'block">';
echo '<div class="header"><div class="title"><h2>';
echo get_string('questionbankcontents', 'quiz') .
- ' <a href="' . $thispageurl->out(true, array('qbanktool' => '1')) .
- '" id="showbankcmd">[' . get_string('show').
- ']</a>
- <a href="' . $thispageurl->out(true, array('qbanktool' => '0')) .
- '" id="hidebankcmd">[' . get_string('hide').
- ']</a>';
+ ' [<a href="' . $thispageurl->out(true, array('qbanktool' => '1')) .
+ '" id="showbankcmd">' . get_string('show').
+ '</a><a href="' . $thispageurl->out(true, array('qbanktool' => '0')) .
+ '" id="hidebankcmd">' . get_string('hide').
+ '</a>]';
echo '</h2></div></div><div class="content">';
echo '<span id="questionbank"></span>';
http://docs.moodle.org/dev/Quiz_UI_redesign/usability_testing_of_August_2008/Issues#Question_bank_.2F_question_adding_controls_visibility
it must be ensured that the question
bank window's title is prominent enough*/
-#page-mod-quiz-edit .questionbankwindow div.header {background-color:#009;color:#fff;background-image:none;padding-top:0.2em;font-weight:bold;}
-#page-mod-quiz-edit .questionbankwindow div.header a{text-decoration:underline;color:#FFF;}
+#page-mod-quiz-edit .questionbankwindow.block div.header {background-color:#009;background-image:none;padding-top:0.2em;font-weight:bold;border:0 none;}
+#page-mod-quiz-edit .questionbankwindow.block div.header div.title h2 {color:#FFF;text-align: center;}
#page-mod-quiz-edit .collapsed .container{display: none;}
+
+#page-mod-quiz-edit .questionbankwindow a#showbankcmd,
+#page-mod-quiz-edit .questionbankwindow a#hidebankcmd {color: #FFF;text-decoration:underline;}
+#page-mod-quiz-edit .questionbankwindow a#showbankcmd:hover,
+#page-mod-quiz-edit .questionbankwindow a#hidebankcmd:hover {color:#009;background-color:#fff;text-decoration:none;}
#page-mod-quiz-edit .questionbankwindow #showbankcmd{display:none;}
#page-mod-quiz-edit .collapsed #showbankcmd{display:inline;}
#page-mod-quiz-edit .questionbankwindow #hidebankcmd{display:inline;}
$result = scorm_get_toc($USER, $scorm, $cm->id, TOCJSLINK, $currentorg, $scoid, $mode, $attempt, true, true);
$sco = $result->sco;
+if ($scorm->lastattemptlock == 1 && $result->attemptleft == 0) {
+ echo $OUTPUT->header();
+ echo $OUTPUT->notification(get_string('exceededmaxattempts', 'scorm'));
+ echo $OUTPUT->footer();
+ exit;
+}
if (($mode == 'browse') && ($scorm->hidebrowse == 1)) {
$mode = 'normal';
$table = new html_table();
$table->head = array(get_string('contributions', 'wiki') . $OUTPUT->help_icon('contributions', 'wiki'));
- $table->attributes['class'] = 'wiki_editor generalbox';
+ $table->attributes['class'] = 'wiki_editor generaltable';
$table->data = array();
$table->rowclasses = array();
$table = new html_table();
$table->head = array(get_string('pageindex', 'wiki') . $OUTPUT->help_icon('pageindex', 'wiki'));
- $table->attributes['class'] = 'wiki_editor generalbox';
+ $table->attributes['class'] = 'wiki_editor generaltable';
$table->data[] = array($this->render_navigation_node($tree));
echo html_writer::table($table);
$table = new html_table();
$table->head = array(get_string('pagelist', 'wiki') . $OUTPUT->help_icon('pagelist', 'wiki'));
- $table->attributes['class'] = 'wiki_editor generalbox';
+ $table->attributes['class'] = 'wiki_editor generaltable';
$table->align = array('center');
foreach ($stdaux as $key => $elem) {
$table->data[] = array($key);
$table = new html_table();
$table->head = array(get_string('orphaned', 'wiki') . $OUTPUT->help_icon('orphaned', 'wiki'));
- $table->attributes['class'] = 'wiki_editor generalbox';
+ $table->attributes['class'] = 'wiki_editor generaltable';
$table->data = array();
$table->rowclasses = array();
$table = new html_table();
$table->head = array(get_string('updatedpages', 'wiki') . $OUTPUT->help_icon('updatedpages', 'wiki'));
- $table->attributes['class'] = 'wiki_editor generalbox';
+ $table->attributes['class'] = 'wiki_editor generaltable';
$table->data = array();
$table->rowclasses = array();
$this->process_essay($question, $questions);
break;
default:
- $this->error(get_string('unknownorunhandledtype', 'qformat_blackboard_six', $question->qtype));
+ $this->error(get_string('unknownorunhandledtype', 'question', $question->qtype));
break;
}
}
$string['pluginname'] = 'Blackboard V6+';
$string['pluginname_help'] = 'Blackboard V6+ format enables questions saved in all Blackboard export formats to be imported via a dat or zip file. For zip files, images import is supported.';
$string['unhandledpresblock'] = 'Unhandled presentation block';
-$string['unknownorunhandledtype'] = 'Unknown or unhandled question type: {$a}';
}
public function readquestion($qrec) {
+ global $OUTPUT;
$type = trim($qrec['@']['type']);
$question = $this->defaultquestion();
break;
break;
default:
- print("<p>Question type ".$type." import not supported for ".$question->questiontext."<p>");
+ echo $OUTPUT->notification(get_string('unknownorunhandledtype', 'question', $type));
$question = null;
}
}
protected function readquestion($lines) {
+ global $OUTPUT;
+
$text = implode(' ', $lines);
$text = str_replace(array('\t','\n','\r'), array('','',''), $text);
}
} else {
- echo "<p>I don't understand this question type (type = <strong>$type</strong>).</p>\n";
+ echo $OUTPUT->notification(get_string('unknownorunhandledtype', 'question', $type));
}
$question = $this->defaultquestion();
*/
class qformat_missingword extends qformat_default {
- function provide_import() {
+ public function provide_import() {
return true;
}
- function readquestion($lines) {
+ public function readquestion($lines) {
/// Given an array of lines known to define a question in
/// this format, this function converts it into a question
/// object suitable for processing and insertion into Moodle.
$answerstart = strpos($text, "{");
if ($answerstart === false) {
- if ($this->displayerrors) {
- echo "<p>$text<p>Could not find a {";
- }
+ $this->error(get_string('beginanswernotfound', 'qformat_missingword'), $text);
return false;
}
$answerfinish = strpos($text, "}");
if ($answerfinish === false) {
- if ($this->displayerrors) {
- echo "<p>$text<p>Could not find a }";
- }
+ $this->error(get_string('endanswernotfound', 'qformat_missingword'), $text);
return false;
}
$answerlength = $answerfinish - $answerstart;
$answertext = substr($text, $answerstart + 1, $answerlength - 1);
- /// Save the new question text
+ // Save the new question text.
$question->questiontext = substr_replace($text, "_____", $answerstart, $answerlength+1);
$question->name = $this->create_default_question_name($question->questiontext, get_string('questionname', 'question'));
-
/// Parse the answers
$answertext = str_replace("=", "~=", $answertext);
$answers = explode("~", $answertext);
$countanswers = count($answers);
switch ($countanswers) {
- case 0: // invalid question
- if ($this->displayerrors) {
- echo "<p>No answers found in $answertext";
- }
+ case 0: // Invalid question.
+ $this->error(get_string('noanswerfound', 'qformat_missingword'), $answertext);
return false;
case 1:
}
$question->answer[] = $answer;
$question->fraction[] = 1;
- $question->feedback[] = "";
+ $question->feedback[] = array('text' => '', 'format' => FORMAT_HTML);
return $question;
default:
$question->qtype = 'multichoice';
+ $question = $this->add_blank_combined_feedback($question);
+ $question->single = 1; // Only one answer allowed.
foreach ($answers as $key => $answer) {
$answer = trim($answer);
# $question->fraction[$key] = 0;
$question->fraction[$key] = $answeight;
}
- $question->answer[$key] = $answer;
- $question->feedback[$key] = $comment;
+ $question->answer[$key] = array('text' => $answer, 'format' => FORMAT_HTML);
+ $question->feedback[$key] = array('text' => $comment, 'format' => FORMAT_HTML);
}
return $question;
$string['pluginname'] = 'Missing word format';
$string['pluginname_help'] = 'Missing word format enables questions to be imported via text file.';
$string['pluginname_link'] = 'Missing word format';
+$string['beginanswernotfound'] = 'Could not find a required "{" character in imported file content.';
+$string['endanswernotfound'] = 'Could not find a required "}" character in imported file content.';
+$string['noanswerfound'] = 'No answers found in question';
--- /dev/null
+As soon as we begin to explore our body parts as infants
+we become students of {=anatomy and physiology ~reflexology
+~science ~experiment}, and in a sense we remain students for life.
--- /dev/null
+You can use the missing word format to import questions
+into both Moodle's Question bank and {=Lesson} activity.
--- /dev/null
+This is {=the best answer#comment on the best answer ~75%a good
+answer#comment on the good answer ~a wrong one#comment on the bad answer}
}
$expout .= "</ul>\n";
break;
- case SHORTANSWER:
+ case 'shortanswer':
$expout .= html_writer::start_tag('ul', array('class' => 'shortanswer'));
$expout .= html_writer::start_tag('li');
$expout .= html_writer::label(get_string('answer'), 'quest_'.$id, false, array('class' => 'accesshide'));
$expout .= html_writer::end_tag('li');
$expout .= html_writer::end_tag('ul');
break;
- case NUMERICAL:
+ case 'numerical':
$expout .= html_writer::start_tag('ul', array('class' => 'numerical'));
$expout .= html_writer::start_tag('li');
$expout .= html_writer::label(get_string('answer'), 'quest_'.$id, false, array('class' => 'accesshide'));
$expout .= html_writer::end_tag('li');
$expout .= html_writer::end_tag('ul');
break;
- case MATCH:
+ case 'match':
$expout .= html_writer::start_tag('ul', array('class' => 'match'));
// build answer list
break;
case 'description':
break;
- case 'multichoice':
- $expout .= "<!-- CLOZE type is not supported -->\n";
- break;
+ case 'multianswer':
default:
- echo $OUTPUT->notification("No handler for qtype $question->qtype for GIFT export" );
+ $expout .= "<!-- export of $question->qtype type is not supported -->\n";
}
// close off div
$expout .= "</div>\n\n\n";
$this->context = context::instance_by_id($record->contextid);
$this->editoroptions = array('subdirs' => 1, 'maxfiles' => EDITOR_UNLIMITED_FILES,
- 'context' => $this->context);
+ 'context' => $this->context, 'collapsed' => 1);
$this->fileoptions = array('subdirs' => 1, 'maxfiles' => -1, 'maxbytes' => -1);
$this->category = $category;
$mform->addRule('name', null, 'required', null, 'client');
$mform->addElement('editor', 'questiontext', get_string('questiontext', 'question'),
- array('rows' => 15), $this->editoroptions);
+ array('rows' => 15), $this->get_non_collabsible_editor_options());
$mform->setType('questiontext', PARAM_RAW);
$mform->addElement('text', 'defaultmark', get_string('defaultmark', 'question'),
$mform->addRule('defaultmark', null, 'required', null, 'client');
$mform->addElement('editor', 'generalfeedback', get_string('generalfeedback', 'question'),
- array('rows' => 10), $this->editoroptions);
+ array('rows' => 10), $this->get_non_collabsible_editor_options());
$mform->setType('generalfeedback', PARAM_RAW);
$mform->addHelpButton('generalfeedback', 'generalfeedback', 'question');
* in the question type class.
*/
public abstract function qtype();
+
+ /**
+ * Returns an array of editor options with collapsed options turned off.
+ * @return array
+ */
+ protected function get_non_collabsible_editor_options() {
+ return array_merge($this->editoroptions, array('collapsed' => 0));
+ }
}
if (!empty($infos)) {
echo '<h1 align="center">'.get_string($type, 'report_completion').'</h1>';
- echo '<table class="generalbox boxaligncenter">';
+ echo '<table class="generaltable boxaligncenter">';
echo '<tr class="ccheader">';
echo '<th class="c0 header" scope="col">'.get_string('course').'</th>';
echo '<th class="c1 header" scope="col">'.get_string('requiredcriteria', 'completion').'</th>';