Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/moodle/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
pcharsle committed Jul 20, 2012
2 parents 3e01e06 + 3294034 commit b0b6ead
Show file tree
Hide file tree
Showing 82 changed files with 1,256 additions and 289 deletions.
211 changes: 211 additions & 0 deletions admin/cli/mysql_collation.php
@@ -0,0 +1,211 @@
<?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/>.

/**
* MySQL collation conversion tool.
*
* @package core
* @copyright 2012 Petr Skoda (http://skodak.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

define('CLI_SCRIPT', true);

require(dirname(dirname(dirname(__FILE__))).'/config.php');
require_once($CFG->libdir.'/clilib.php'); // cli only functions

if ($DB->get_dbfamily() !== 'mysql') {
cli_error('This function is designed for MySQL databases only!');
}

// now get cli options
list($options, $unrecognized) = cli_get_params(array('help'=>false, 'list'=>false, 'collation'=>false, 'available'=>false),
array('h'=>'help', 'l'=>'list', 'a'=>'available'));

if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}

$help =
"MySQL collation conversions script.
It is strongly recommended to stop the web server before the conversion.
This script may be executed before the main upgrade - 1.9.x data for example.
Options:
--collation=COLLATION Convert MySQL tables to different collation
-l, --list Show table and column information
-a, --available Show list of available collations
-h, --help Print out this help
Example:
\$ sudo -u www-data /usr/bin/php admin/cli/mysql_collation.php --collation=utf8_general_ci
";

if (!empty($options['collation'])) {
$collations = mysql_get_collations();
$collation = clean_param($options['collation'], PARAM_ALPHANUMEXT);
$collation = strtolower($collation);
if (!isset($collations[$collation])) {
cli_error("Error: collation '$collation' is not available on this server!");
}

echo "Converting tables and columns to '$collation' for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
$rs = $DB->get_recordset_sql($sql);
$converted = 0;
$skipped = 0;
$errors = 0;
foreach ($rs as $table) {
echo str_pad($table->name, 40). " - ";

if ($table->collation === $collation) {
echo "NO CHANGE\n";
$skipped++;

} else {
$DB->change_database_structure("ALTER TABLE $table->name DEFAULT COLLATE = $collation");
echo "CONVERTED\n";
$converted++;
}

$sql = "SHOW FULL COLUMNS FROM $table->name WHERE collation IS NOT NULL";
$rs2 = $DB->get_recordset_sql($sql);
foreach ($rs2 as $column) {
$column = (object)array_change_key_case((array)$column, CASE_LOWER);
echo ' '.str_pad($column->field, 36). " - ";
if ($column->collation === $collation) {
echo "NO CHANGE\n";
$skipped++;
continue;
}

if ($column->type === 'tinytext' or $column->type === 'mediumtext' or $column->type === 'text' or $column->type === 'longtext') {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = (!is_null($column->default) and $column->default !== '') ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
$DB->change_database_structure($sql);

} else if (strpos($column->type, 'varchar') === 0) {
$notnull = ($column->null === 'NO') ? 'NOT NULL' : 'NULL';
$default = !is_null($column->default) ? "DEFAULT '$column->default'" : '';
// primary, unique and inc are not supported for texts
$sql = "ALTER TABLE $table->name MODIFY COLUMN $column->field $column->type COLLATE $collation $notnull $default";
$DB->change_database_structure($sql);
} else {
echo "ERROR (unknown column type: $column->type)\n";
$error++;
continue;
}
echo "CONVERTED\n";
$converted++;
}
$rs2->close();
}
$rs->close();
echo "Converted: $converted, skipped: $skipped, errors: $errors\n";
exit(0); // success

} else if (!empty($options['list'])) {
echo "List of tables for $CFG->wwwroot:\n";
$prefix = $DB->get_prefix();
$prefix = str_replace('_', '\\_', $prefix);
$sql = "SHOW TABLE STATUS WHERE Name LIKE BINARY '$prefix%'";
$rs = $DB->get_recordset_sql($sql);
$counts = array();
foreach ($rs as $table) {
if (isset($counts[$table->collation])) {
$counts[$table->collation]++;
} else {
$counts[$table->collation] = 1;
}
echo str_pad($table->name, 40);
echo $table->collation. "\n";
$collations = mysql_get_column_collations($table->name);
foreach ($collations as $columname=>$collation) {
if (isset($counts[$collation])) {
$counts[$collation]++;
} else {
$counts[$collation] = 1;
}
echo ' ';
echo str_pad($columname, 36);
echo $collation. "\n";
}
}
$rs->close();

echo "\n";
echo "Table collations summary for $CFG->wwwroot:\n";
foreach ($counts as $collation => $count) {
echo "$collation: $count\n";
}
exit(0); // success

} else if (!empty($options['available'])) {
echo "List of available MySQL collations for $CFG->wwwroot:\n";
$collations = mysql_get_collations();
foreach ($collations as $collation) {
echo " $collation\n";
}
die;

} else {
echo $help;
die;
}



// ========== Some functions ==============

function mysql_get_collations() {
global $DB;

$collations = array();
$sql = "SHOW COLLATION WHERE Collation LIKE 'utf8\_%' AND Charset = 'utf8'";
$rs = $DB->get_recordset_sql($sql);
foreach ($rs as $collation) {
$collations[$collation->collation] = $collation->collation;
}
$rs->close();

$collation = $DB->get_dbcollation();
if (isset($collations[$collation])) {
$collations[$collation] .= ' (default)';
}

return $collations;
}

function mysql_get_column_collations($tablename) {
global $DB;

$collations = array();
$sql = "SELECT column_name, collation_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = DATABASE() AND table_name = ? AND collation_name IS NOT NULL";
$rs = $DB->get_recordset_sql($sql, array($tablename));
foreach($rs as $record) {
$collations[$record->column_name] = $record->collation_name;
}
$rs->close();
return $collations;
}
35 changes: 30 additions & 5 deletions admin/roles/check.php
Expand Up @@ -104,20 +104,45 @@
break; break;
} }


// Get the list of the reported-on user's role assignments - must be after
// the page setup code above, or the language might be wrong.
$reportuser = $userselector->get_selected_user();
if (!is_null($reportuser)) {
$roleassignments = get_user_roles_with_special($context, $reportuser->id);
$rolenames = role_get_names($context);
}

echo $OUTPUT->header(); echo $OUTPUT->header();
// These are needed early because of tabs.php
$assignableroles = get_assignable_roles($context, ROLENAME_BOTH);
$overridableroles = get_overridable_roles($context, ROLENAME_BOTH);


// Print heading. // Print heading.
echo $OUTPUT->heading($title); echo $OUTPUT->heading($title);


// If a user has been chosen, show all the permissions for this user. // If a user has been chosen, show all the permissions for this user.
$reportuser = $userselector->get_selected_user();
if (!is_null($reportuser)) { if (!is_null($reportuser)) {
echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthwide'); echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthwide');
echo $OUTPUT->heading(get_string('permissionsforuser', 'role', fullname($reportuser)), 3);


if (!empty($roleassignments)) {
echo $OUTPUT->heading(get_string('rolesforuser', 'role', fullname($reportuser)), 3);
echo html_writer::start_tag('ul');

$systemcontext = context_system::instance();
foreach ($roleassignments as $ra) {
$racontext = context::instance_by_id($ra->contextid);
$link = html_writer::link($racontext->get_url(), $racontext->get_context_name());

$rolename = $rolenames[$ra->roleid]->localname;
if (has_capability('moodle/role:manage', $systemcontext)) {
$rolename = html_writer::link(new moodle_url('/admin/roles/define.php',
array('action' => 'view', 'roleid' => $ra->roleid)), $rolename);
}

echo html_writer::tag('li', get_string('roleincontext', 'role',
array('role' => $rolename, 'context' => $link)));
}
echo html_writer::end_tag('ul');
}

echo $OUTPUT->heading(get_string('permissionsforuser', 'role', fullname($reportuser)), 3);
$table = new check_capability_table($context, $reportuser, $contextname); $table = new check_capability_table($context, $reportuser, $contextname);
$table->display(); $table->display();
echo $OUTPUT->box_end(); echo $OUTPUT->box_end();
Expand Down
4 changes: 4 additions & 0 deletions admin/settings/grades.php
Expand Up @@ -58,6 +58,10 @@
GRADE_NAVMETHOD_TABS => new lang_string('tabs', 'grades'), GRADE_NAVMETHOD_TABS => new lang_string('tabs', 'grades'),
GRADE_NAVMETHOD_COMBO => new lang_string('combo', 'grades')))); GRADE_NAVMETHOD_COMBO => new lang_string('combo', 'grades'))));


$temp->add(new admin_setting_configtext('grade_export_userprofilefields', new lang_string('gradeexportuserprofilefields', 'grades'), new lang_string('gradeexportuserprofilefields_desc', 'grades'), 'firstname,lastname,idnumber,institution,department,email', PARAM_TEXT));

$temp->add(new admin_setting_configtext('grade_export_customprofilefields', new lang_string('gradeexportcustomprofilefields', 'grades'), new lang_string('gradeexportcustomprofilefields_desc', 'grades'), null, PARAM_TEXT));

$temp->add(new admin_setting_configcheckbox('recovergradesdefault', new lang_string('recovergradesdefault', 'grades'), new lang_string('recovergradesdefault_help', 'grades'), 0)); $temp->add(new admin_setting_configcheckbox('recovergradesdefault', new lang_string('recovergradesdefault', 'grades'), new lang_string('recovergradesdefault_help', 'grades'), 0));


$temp->add(new admin_setting_special_gradeexport()); $temp->add(new admin_setting_special_gradeexport());
Expand Down
1 change: 1 addition & 0 deletions auth/shibboleth/login.php
Expand Up @@ -63,6 +63,7 @@
$loginsite = get_string("loginsite"); $loginsite = get_string("loginsite");


$PAGE->set_url('/auth/shibboleth/login.php'); $PAGE->set_url('/auth/shibboleth/login.php');
$PAGE->set_context(context_system::instance());
$PAGE->navbar->add($loginsite); $PAGE->navbar->add($loginsite);
$PAGE->set_title("$site->fullname: $loginsite"); $PAGE->set_title("$site->fullname: $loginsite");
$PAGE->set_heading($site->fullname); $PAGE->set_heading($site->fullname);
Expand Down
16 changes: 12 additions & 4 deletions backup/moodle2/backup_stepslib.php
Expand Up @@ -323,7 +323,7 @@ protected function define_structure() {
$availability = new backup_nested_element('availability', array('id'), array( $availability = new backup_nested_element('availability', array('id'), array(
'sourcecmid', 'requiredcompletion', 'gradeitemid', 'grademin', 'grademax')); 'sourcecmid', 'requiredcompletion', 'gradeitemid', 'grademin', 'grademax'));
$availabilityfield = new backup_nested_element('availability_field', array('id'), array( $availabilityfield = new backup_nested_element('availability_field', array('id'), array(
'userfield', 'customfieldid', 'operator', 'value')); 'userfield', 'customfield', 'customfieldtype', 'operator', 'value'));


// attach format plugin structure to $module element, only one allowed // attach format plugin structure to $module element, only one allowed
$this->add_plugin_structure('format', $module, false); $this->add_plugin_structure('format', $module, false);
Expand All @@ -346,7 +346,11 @@ protected function define_structure() {
WHERE cm.id = ?', array(backup::VAR_MODID)); WHERE cm.id = ?', array(backup::VAR_MODID));


$availability->set_source_table('course_modules_availability', array('coursemoduleid' => backup::VAR_MODID)); $availability->set_source_table('course_modules_availability', array('coursemoduleid' => backup::VAR_MODID));
$availabilityfield->set_source_table('course_modules_avail_fields', array('coursemoduleid' => backup::VAR_MODID)); $availabilityfield->set_source_sql('
SELECT cmaf.*, uif.shortname AS customfield, uif.datatype AS customfieldtype
FROM {course_modules_avail_fields} cmaf
LEFT JOIN {user_info_field} uif ON uif.id = cmaf.customfieldid
WHERE cmaf.coursemoduleid = ?', array(backup::VAR_MODID));


// Define annotations // Define annotations
$module->annotate_ids('grouping', 'groupingid'); $module->annotate_ids('grouping', 'groupingid');
Expand Down Expand Up @@ -377,14 +381,18 @@ protected function define_structure() {
$avail = new backup_nested_element('availability', array('id'), array( $avail = new backup_nested_element('availability', array('id'), array(
'sourcecmid', 'requiredcompletion', 'gradeitemid', 'grademin', 'grademax')); 'sourcecmid', 'requiredcompletion', 'gradeitemid', 'grademin', 'grademax'));
$availfield = new backup_nested_element('availability_field', array('id'), array( $availfield = new backup_nested_element('availability_field', array('id'), array(
'userfield', 'customfieldid', 'operator', 'value')); 'userfield', 'operator', 'value', 'customfield', 'customfieldtype'));
$section->add_child($avail); $section->add_child($avail);
$section->add_child($availfield); $section->add_child($availfield);


// Define sources // Define sources
$section->set_source_table('course_sections', array('id' => backup::VAR_SECTIONID)); $section->set_source_table('course_sections', array('id' => backup::VAR_SECTIONID));
$avail->set_source_table('course_sections_availability', array('coursesectionid' => backup::VAR_SECTIONID)); $avail->set_source_table('course_sections_availability', array('coursesectionid' => backup::VAR_SECTIONID));
$availfield->set_source_table('course_sections_avail_fields', array('coursesectionid' => backup::VAR_SECTIONID)); $availfield->set_source_sql('
SELECT csaf.*, uif.shortname AS customfield, uif.datatype AS customfieldtype
FROM {course_sections_avail_fields} csaf
LEFT JOIN {user_info_field} uif ON uif.id = csaf.customfieldid
WHERE csaf.coursesectionid = ?', array(backup::VAR_SECTIONID));


// Aliases // Aliases
$section->set_source_alias('section', 'number'); $section->set_source_alias('section', 'number');
Expand Down
40 changes: 28 additions & 12 deletions backup/moodle2/restore_stepslib.php
Expand Up @@ -1139,18 +1139,26 @@ public function process_availability_field($data) {
$data = (object)$data; $data = (object)$data;
// Mark it is as passed by default // Mark it is as passed by default
$passed = true; $passed = true;
// Ok, if it is a profile field we need to check it exists $customfieldid = null;
if (!is_null($data->customfieldid)) {
if (!$DB->record_exists('user_info_field', array('id' => $data->customfieldid))) { // If a customfield has been used in order to pass we must be able to match an existing
$passed = false; // customfield by name (data->customfield) and type (data->customfieldtype)
} if (is_null($data->customfield) xor is_null($data->customfieldtype)) {
// xor is sort of uncommon. If either customfield is null or customfieldtype is null BUT not both.
// If one is null but the other isn't something clearly went wrong and we'll skip this condition.
$passed = false;
} else if (!is_null($data->customfield)) {
$params = array('shortname' => $data->customfield, 'datatype' => $data->customfieldtype);
$customfieldid = $DB->get_field('user_info_field', 'id', $params);
$passed = ($customfieldid !== false);
} }

if ($passed) { if ($passed) {
// Create the object to insert into the database // Create the object to insert into the database
$availfield = new stdClass(); $availfield = new stdClass();
$availfield->coursesectionid = $this->task->get_sectionid(); $availfield->coursesectionid = $this->task->get_sectionid();
$availfield->userfield = $data->userfield; $availfield->userfield = $data->userfield;
$availfield->customfieldid = $data->customfieldid; $availfield->customfieldid = $customfieldid;
$availfield->operator = $data->operator; $availfield->operator = $data->operator;
$availfield->value = $data->value; $availfield->value = $data->value;
$DB->insert_record('course_sections_avail_fields', $availfield); $DB->insert_record('course_sections_avail_fields', $availfield);
Expand Down Expand Up @@ -2637,18 +2645,26 @@ protected function process_availability_field($data) {
$data = (object)$data; $data = (object)$data;
// Mark it is as passed by default // Mark it is as passed by default
$passed = true; $passed = true;
// Ok, if it is a profile field we need to check it exists $customfieldid = null;
if (!is_null($data->customfieldid)) {
if (!$DB->record_exists('user_info_field', array('id' => $data->customfieldid))) { // If a customfield has been used in order to pass we must be able to match an existing
$passed = false; // customfield by name (data->customfield) and type (data->customfieldtype)
} if (!empty($data->customfield) xor !empty($data->customfieldtype)) {
// xor is sort of uncommon. If either customfield is null or customfieldtype is null BUT not both.
// If one is null but the other isn't something clearly went wrong and we'll skip this condition.
$passed = false;
} else if (!empty($data->customfield)) {
$params = array('shortname' => $data->customfield, 'datatype' => $data->customfieldtype);
$customfieldid = $DB->get_field('user_info_field', 'id', $params);
$passed = ($customfieldid !== false);
} }

if ($passed) { if ($passed) {
// Create the object to insert into the database // Create the object to insert into the database
$availfield = new stdClass(); $availfield = new stdClass();
$availfield->coursemoduleid = $this->task->get_moduleid(); // Lets add the availability cmid $availfield->coursemoduleid = $this->task->get_moduleid(); // Lets add the availability cmid
$availfield->userfield = $data->userfield; $availfield->userfield = $data->userfield;
$availfield->customfieldid = $data->customfieldid; $availfield->customfieldid = $customfieldid;
$availfield->operator = $data->operator; $availfield->operator = $data->operator;
$availfield->value = $data->value; $availfield->value = $data->value;
// Insert into the database // Insert into the database
Expand Down

0 comments on commit b0b6ead

Please sign in to comment.