MDL-14956 basic exception support in Moodle + other minor related refactoring

This commit is contained in:
skodak 2008-06-13 17:51:34 +00:00
parent 08d9fb369c
commit 251387d087
8 changed files with 364 additions and 333 deletions

View File

@ -145,12 +145,12 @@ $COURSE->id = 0;
/// Include some moodle libraries
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/setuplib.php');
require_once($CFG->libdir.'/moodlelib.php');
require_once($CFG->libdir.'/weblib.php');
require_once($CFG->libdir.'/deprecatedlib.php');
require_once($CFG->libdir.'/dmllib.php');
require_once($CFG->libdir.'/deprecatedlib.php');
require_once($CFG->libdir.'/moodlelib.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/environmentlib.php');
require_once($CFG->libdir.'/xmlize.php');
require_once($CFG->libdir.'/componentlib.class.php');

View File

@ -180,6 +180,7 @@ $string['filemismatch'] = 'Non-core filename mismatch. The file \"$a[0]\" should
$string['filternotinstalled'] = 'Filter $a is not currently installed';
$string['filternotactive'] = 'Filter $a is not currently active';
$string['forumblockingtoomanyposts'] = 'You have exceeded the posting threshold set for this forum.';
$string['generalexceptionmessage'] = 'Exception - $a';
$string['gradepubdisable'] = 'Grade publishing disabled';
$string['groupalready'] = 'User already belongs to group $a';
$string['groupexistforcourse'] = 'Group \"$a\" already exists for this course';
@ -282,6 +283,7 @@ $string['noinstances'] = 'There are no instances of $a in this course!';
$string['noguest'] = 'No guests here!';
$string['nologinas'] = 'You are not allowed to login as that user';
$string['noadmins'] = 'No administrators!';
$string['notlocalisederrormessage'] = '$a';
$string['nousers'] = 'No such user!';
$string['nonmeaningfulcontent'] = 'Non meaningful content';
$string['noparticipatorycms'] = 'Sorry, but you have no participatory course modules to report on.';

View File

@ -13,20 +13,20 @@ require_once($CFG->libdir . '/ddllib.php');
class ddllib_test extends UnitTestCase {
private $tables = array();
private $db;
private $tdb;
public function setUp() {
global $CFG, $DB, $UNITTEST;
if (isset($UNITTEST->func_test_db)) {
$this->db = $UNITTEST->func_test_db;
$this->tdb = $UNITTEST->func_test_db;
} else {
$this->db = $DB;
$this->tdb = $DB;
}
unset($CFG->xmldbreconstructprevnext); // remove this unhack ;-)
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
@ -78,26 +78,26 @@ class ddllib_test extends UnitTestCase {
}
public function tearDown() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
// drop custom test tables
for ($i=0; $i<3; $i++) {
$table = new xmldb_table('test_table_cust'.$i);
if ($dbmanager->table_exists($table)) {
$dbmanager->drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$dbman->drop_table($table, true, false);
}
}
// drop default tables
foreach ($this->tables as $table) {
if ($dbmanager->table_exists($table)) {
$dbmanager->drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$dbman->drop_table($table, true, false);
}
}
}
private function create_deftable($tablename) {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
if (!isset($this->tables[$tablename])) {
return null;
@ -105,17 +105,17 @@ class ddllib_test extends UnitTestCase {
$table = $this->tables[$tablename];
if ($dbmanager->table_exists($table)) {
$dbmanager->drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$dbman->drop_table($table, true, false);
}
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
return $table;
}
public function testTableExists() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
// first make sure it returns false if table does not exist
$table = $this->tables['test_table0'];
@ -124,36 +124,36 @@ class ddllib_test extends UnitTestCase {
ob_end_clean();
$this->assertFalse($result);
$this->assertFalse($dbmanager->table_exists('test_table0'));
$this->assertFalse($dbmanager->table_exists($table));
$this->assertFalse($dbman->table_exists('test_table0'));
$this->assertFalse($dbman->table_exists($table));
// create table and test again
$this->assertTrue($dbmanager->create_table($table, true, false));
$this->assertTrue($dbman->create_table($table, true, false));
$this->assertTrue($DB->get_records('test_table0') !== false);
$this->assertTrue($dbmanager->table_exists('test_table0'));
$this->assertTrue($dbmanager->table_exists($table));
$this->assertTrue($dbman->table_exists('test_table0'));
$this->assertTrue($dbman->table_exists($table));
// Test giving a string
$this->assertFalse($dbmanager->table_exists('nonexistenttable'));
$this->assertTrue($dbmanager->table_exists('test_table0'));
$this->assertFalse($dbman->table_exists('nonexistenttable'));
$this->assertTrue($dbman->table_exists('test_table0'));
}
public function testCreateTable() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
// Give a wrong table param (expect a debugging message)
$table = 'string';
ob_start(); // hide debug warning
$result = $dbmanager->create_table($table);
$result = $dbman->create_table($table);
ob_end_clean();
$this->assertFalse($result);
// create table and do basic column tests
$table = $this->tables['test_table1'];
$this->assertTrue($dbmanager->create_table($table));
$this->assertTrue($dbmanager->table_exists($table));
$this->assertTrue($dbman->create_table($table));
$this->assertTrue($dbman->table_exists($table));
$columns = $DB->get_columns('test_table1');
@ -168,51 +168,51 @@ class ddllib_test extends UnitTestCase {
}
public function testDropTable() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$this->assertTrue($dbmanager->drop_table($table, true, false));
$this->assertFalse($dbmanager->table_exists('test_table0'));
$this->assertTrue($dbman->drop_table($table, true, false));
$this->assertFalse($dbman->table_exists('test_table0'));
// Try dropping non-existent table
$table = new xmldb_table('nonexistenttable');
ob_start(); // hide debug warning
$result = $dbmanager->drop_table($table, true, false);
$result = $dbman->drop_table($table, true, false);
ob_end_clean();
$this->assertTrue($result);
// Give a wrong table param
$table = 'string';
ob_start(); // hide debug warning
$result = $dbmanager->drop_table($table, true, false);
$result = $dbman->drop_table($table, true, false);
ob_end_clean();
$this->assertFalse($result);
}
public function testAddEnumField() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table_cust0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
$enums = array('single', 'news', 'general');
/// Create a new field with complex specs (enums are good candidates)
$field = new xmldb_field('type1');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, $enums, 'general', 'course');
$this->assertTrue($dbmanager->add_field($table, $field));
$this->assertTrue($dbmanager->field_exists($table, 'type1'));
$this->assertTrue($dbman->add_field($table, $field));
$this->assertTrue($dbman->field_exists($table, 'type1'));
$field = new xmldb_field('type2');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, null, null, XMLDB_ENUM, $enums, 'general', 'course');
$this->assertTrue($dbmanager->add_field($table, $field));
$this->assertTrue($dbmanager->field_exists($table, 'type2'));
$this->assertTrue($dbman->add_field($table, $field));
$this->assertTrue($dbman->field_exists($table, 'type2'));
/// try inserting a good record
$record = new object();
@ -251,50 +251,50 @@ class ddllib_test extends UnitTestCase {
}
/// cleanup
$dbmanager->drop_field($table, $field);
$dbmanager->drop_table($table);
$dbman->drop_field($table, $field);
$dbman->drop_table($table);
}
public function testAddNumericField() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
/// Create a new field with complex specs (enums are good candidates)
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'type');
$this->assertTrue($dbmanager->add_field($table, $field));
$this->assertTrue($dbmanager->field_exists($table, 'onenumber'));
$this->assertTrue($dbman->add_field($table, $field));
$this->assertTrue($dbman->field_exists($table, 'onenumber'));
$columns = $DB->get_columns('test_table0');
$this->assertEqual($columns['onenumber']->meta_type, 'I');
$dbmanager->drop_field($table, $field);
$dbman->drop_field($table, $field);
}
public function testDropField() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$field = $table->getField('type');
$this->assertTrue($dbmanager->field_exists($table, $field));
$this->assertTrue($dbmanager->field_exists($table, 'type'));
$this->assertTrue($dbman->field_exists($table, $field));
$this->assertTrue($dbman->field_exists($table, 'type'));
$this->assertTrue($dbmanager->drop_field($table, $field));
$this->assertTrue($dbman->drop_field($table, $field));
$this->assertFalse($dbmanager->field_exists($table, 'type'));
$this->assertFalse($dbman->field_exists($table, 'type'));
}
public function testChangeFieldType() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table_cust0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('onenumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
$record = new object();
$recorf->course = 2;
@ -302,95 +302,95 @@ class ddllib_test extends UnitTestCase {
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, '0');
$this->assertTrue($dbmanager->change_field_type($table, $field));
$this->assertTrue($dbman->change_field_type($table, $field));
$columns = $DB->get_columns('test_table_cust0');
$this->assertEqual($columns['onenumber']->meta_type, 'C');
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$this->assertTrue($dbmanager->change_field_type($table, $field));
$this->assertTrue($dbman->change_field_type($table, $field));
$columns = $DB->get_columns('test_table_cust0');
$this->assertEqual($columns['onenumber']->meta_type, 'I');
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, "test'n drop");
$this->assertTrue($dbmanager->change_field_type($table, $field));
$this->assertTrue($dbman->change_field_type($table, $field));
$columns = $DB->get_columns('test_table_cust0');
$this->assertEqual($columns['onenumber']->meta_type, 'C');
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_FLOAT, '20,10', XMLDB_UNSIGNED, null, null, null, null, null);
$this->assertTrue($dbmanager->change_field_type($table, $field));
$this->assertTrue($dbman->change_field_type($table, $field));
$columns = $DB->get_columns('test_table_cust0');
$this->assertEqual($columns['onenumber']->meta_type, 'N');
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null, 'test');
$this->assertTrue($dbmanager->change_field_type($table, $field));
$this->assertTrue($dbman->change_field_type($table, $field));
$columns = $DB->get_columns('test_table_cust0');
$this->assertEqual($columns['onenumber']->meta_type, 'C');
$field = new xmldb_field('onenumber');
$field->set_attributes(XMLDB_TYPE_NUMBER, '20,10', XMLDB_UNSIGNED, null, null, null, null, null);
$this->assertTrue($dbmanager->change_field_type($table, $field));
$this->assertTrue($dbman->change_field_type($table, $field));
$columns = $DB->get_columns('test_table_cust0');
$this->assertEqual($columns['onenumber']->meta_type, 'N');
$dbmanager->drop_table($table, true, false);
$dbman->drop_table($table, true, false);
}
public function testChangeFieldPrecision() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
// TODO: verify the precision is changed in db
$table = $this->create_deftable('test_table1');
$field = new xmldb_field('intro');
$field->set_attributes(XMLDB_TYPE_TEXT, 'big', null, XMLDB_NOTNULL, null, null, null, null);
$this->assertTrue($dbmanager->change_field_precision($table, $field));
$this->assertTrue($dbman->change_field_precision($table, $field));
$field = new xmldb_field('secondname');
$field->set_attributes(XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null, null, null);
$this->assertTrue($dbmanager->change_field_precision($table, $field));
$this->assertTrue($dbman->change_field_precision($table, $field));
$field = new xmldb_field('grade');
$field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null, null, null);
$this->assertTrue($dbmanager->change_field_precision($table, $field));
$this->assertTrue($dbman->change_field_precision($table, $field));
$field = new xmldb_field('course');
$field->set_attributes(XMLDB_TYPE_INTEGER, '5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$this->assertTrue($dbmanager->change_field_precision($table, $field));
$this->assertTrue($dbman->change_field_precision($table, $field));
}
public function testChangeFieldSign() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
// TODO: verify the signed is changed in db
$table = $this->create_deftable('test_table1');
$field = new xmldb_field('grade');
$field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', XMLDB_UNSIGNED, null, null, null, null, null);
$this->assertTrue($dbmanager->change_field_unsigned($table, $field));
$this->assertTrue($dbman->change_field_unsigned($table, $field));
$field = new xmldb_field('grade');
$field->set_attributes(XMLDB_TYPE_NUMBER, '10,2', null, null, null, null, null, null);
$this->assertTrue($dbmanager->change_field_unsigned($table, $field));
$this->assertTrue($dbman->change_field_unsigned($table, $field));
}
public function testChangeFieldNullability() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table_cust0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
$record = new object();
$record->name = NULL;
@ -402,7 +402,7 @@ class ddllib_test extends UnitTestCase {
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
$this->assertTrue($dbmanager->change_field_notnull($table, $field));
$this->assertTrue($dbman->change_field_notnull($table, $field));
$this->assertTrue($DB->insert_record('test_table_cust0', $record, false));
@ -411,30 +411,30 @@ class ddllib_test extends UnitTestCase {
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
$this->assertTrue($dbmanager->change_field_notnull($table, $field));
$this->assertTrue($dbman->change_field_notnull($table, $field));
ob_start(); // hide debug warning
$result = $DB->insert_record('test_table_cust0', $record, false);
ob_end_clean();
$this->assertFalse($result);
$dbmanager->drop_table($table, true, false);
$dbman->drop_table($table, true, false);
}
public function testChangeFieldDefault() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table_cust0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('number', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$table->add_field('name', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'Moodle');
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
$field = new xmldb_field('name');
$field->set_attributes(XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'Moodle2');
$this->assertTrue($dbmanager->change_field_default($table, $field));
$this->assertTrue($dbman->change_field_default($table, $field));
$record = new object();
$record->number = 666;
@ -446,7 +446,7 @@ class ddllib_test extends UnitTestCase {
$field = new xmldb_field('number');
$field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 666);
$this->assertTrue($dbmanager->change_field_default($table, $field));
$this->assertTrue($dbman->change_field_default($table, $field));
$record = new object();
$record->name = 'something';
@ -455,19 +455,19 @@ class ddllib_test extends UnitTestCase {
$record = $DB->get_record('test_table_cust0', array('id'=>$id));
$this->assertEqual($record->number, '666');
$dbmanager->drop_table($table, true, false);
$dbman->drop_table($table, true, false);
}
public function testAddUniqueIndex() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table_cust0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('number', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$table->add_field('name', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, 'Moodle');
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
$record = new object();
$record->number = 666;
@ -476,126 +476,126 @@ class ddllib_test extends UnitTestCase {
$index = new xmldb_index('number-name');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('number', 'name'));
$this->assertTrue($dbmanager->add_index($table, $index));
$this->assertTrue($dbman->add_index($table, $index));
ob_start(); // hide debug warning
$result = $DB->insert_record('test_table_cust0', $record, false);
ob_end_clean();
$this->assertFalse($result);
$dbmanager->drop_table($table, true, false);
$dbman->drop_table($table, true, false);
}
public function testAddNonUniqueIndex() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$index = new xmldb_index('secondname');
$index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'name'));
$this->assertTrue($dbmanager->add_index($table, $index));
$this->assertTrue($dbman->add_index($table, $index));
}
public function testFindIndexName() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$index = new xmldb_index('secondname');
$index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'name'));
$dbmanager->add_index($table, $index);
$dbman->add_index($table, $index);
//DBM Systems name their indices differently - do not test the actual index name
$result = $dbmanager->find_index_name($table, $index);
$result = $dbman->find_index_name($table, $index);
$this->assertTrue(!empty($result));
$nonexistentindex = new xmldb_index('nonexistentindex');
$nonexistentindex->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('name'));
$this->assertFalse($dbmanager->find_index_name($table, $nonexistentindex));
$this->assertFalse($dbman->find_index_name($table, $nonexistentindex));
}
public function testDropIndex() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$index = new xmldb_index('secondname');
$index->set_attributes(XMLDB_INDEX_NOTUNIQUE, array('course', 'name'));
$dbmanager->add_index($table, $index);
$dbman->add_index($table, $index);
$this->assertTrue($dbmanager->drop_index($table, $index));
$this->assertFalse($dbmanager->find_index_name($table, $index));
$this->assertTrue($dbman->drop_index($table, $index));
$this->assertFalse($dbman->find_index_name($table, $index));
}
public function testAddUniqueKey() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$key = new xmldb_key('id-course-grade');
$key->set_attributes(XMLDB_KEY_UNIQUE, array('id', 'course', 'grade'));
$this->assertTrue($dbmanager->add_key($table, $key));
$this->assertTrue($dbman->add_key($table, $key));
}
public function testAddForeignUniqueKey() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$this->create_deftable('test_table0');
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'test_table0', array('id'));
$this->assertTrue($dbmanager->add_key($table, $key));
$this->assertTrue($dbman->add_key($table, $key));
}
public function testDropKey() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$this->create_deftable('test_table0');
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN_UNIQUE, array('course'), 'test_table0', array('id'));
$dbmanager->add_key($table, $key);
$dbman->add_key($table, $key);
$this->assertTrue($dbmanager->drop_key($table, $key));
$this->assertTrue($dbman->drop_key($table, $key));
}
public function testAddForeignKey() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$this->create_deftable('test_table0');
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN, array('course'), 'test_table0', array('id'));
$this->assertTrue($dbmanager->add_key($table, $key));
$this->assertTrue($dbman->add_key($table, $key));
}
public function testDropForeignKey() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table1');
$this->create_deftable('test_table0');
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_FOREIGN, array('course'), 'test_table0', array('id'));
$dbmanager->add_key($table, $key);
$dbman->add_key($table, $key);
$this->assertTrue($dbmanager->drop_key($table, $key));
$this->assertTrue($dbman->drop_key($table, $key));
}
public function testChangeFieldEnum() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = new xmldb_table('test_table_cust0');
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
$table->add_field('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
$table->add_field('type', XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general'), 'general');
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$dbmanager->create_table($table, true, false);
$dbman->create_table($table, true, false);
// Removing an enum value
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, null, null);
$this->assertTrue($dbmanager->change_field_enum($table, $field));
$this->assertTrue($dbman->change_field_enum($table, $field));
$record = new object();
$record->course = 666;
@ -605,7 +605,7 @@ class ddllib_test extends UnitTestCase {
// Adding an enum value
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
$this->assertTrue($dbmanager->change_field_enum($table, $field));
$this->assertTrue($dbman->change_field_enum($table, $field));
$record = new object();
$record->course = 666;
@ -616,19 +616,19 @@ class ddllib_test extends UnitTestCase {
ob_end_clean();
$this->assertFalse($result);
$dbmanager->drop_table($table, true, false);
$dbman->drop_table($table, true, false);
}
public function testRenameField() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$field = new xmldb_field('type');
$field->set_attributes(XMLDB_TYPE_CHAR, '20', null, XMLDB_NOTNULL, null, XMLDB_ENUM,
array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general', 'course');
$this->assertTrue($dbmanager->rename_field($table, $field, 'newfieldname'));
$this->assertTrue($dbman->rename_field($table, $field, 'newfieldname'));
$columns = $DB->get_columns('test_table0');
@ -637,45 +637,45 @@ class ddllib_test extends UnitTestCase {
}
public function testRenameTable() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$this->assertFalse($dbmanager->table_exists('test_table_cust0'));
$this->assertTrue($dbmanager->rename_table($table, 'test_table_cust0'));
$this->assertTrue($dbmanager->table_exists('test_table_cust0'));
$this->assertFalse($dbman->table_exists('test_table_cust0'));
$this->assertTrue($dbman->rename_table($table, 'test_table_cust0'));
$this->assertTrue($dbman->table_exists('test_table_cust0'));
$table->setName('test_table_cust0');
$dbmanager->drop_table($table);
$dbman->drop_table($table);
}
public function testFieldExists() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
// String params
// Give a nonexistent table as first param
$this->assertFalse($dbmanager->field_exists('nonexistenttable', 'id'));
$this->assertFalse($dbman->field_exists('nonexistenttable', 'id'));
// Give a nonexistent field as second param
$this->assertFalse($dbmanager->field_exists('test_table0', 'nonexistentfield'));
$this->assertFalse($dbman->field_exists('test_table0', 'nonexistentfield'));
// Correct string params
$this->assertTrue($dbmanager->field_exists('test_table0', 'id'));
$this->assertTrue($dbman->field_exists('test_table0', 'id'));
// Object params
$realfield = $table->getField('id');
// Give a nonexistent table as first param
$nonexistenttable = new xmldb_table('nonexistenttable');
$this->assertFalse($dbmanager->field_exists($nonexistenttable, $realfield));
$this->assertFalse($dbman->field_exists($nonexistenttable, $realfield));
// Give a nonexistent field as second param
$nonexistentfield = new xmldb_field('nonexistentfield');
$this->assertFalse($dbmanager->field_exists($table, $nonexistentfield));
$this->assertFalse($dbman->field_exists($table, $nonexistentfield));
// Correct string params
$this->assertTrue($dbmanager->field_exists($table, $realfield));
$this->assertTrue($dbman->field_exists($table, $realfield));
}
public function testIndexExists() {
@ -683,135 +683,135 @@ class ddllib_test extends UnitTestCase {
}
public function testFindCheckConstraintName() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$field = $table->getField('type');
$result = $dbmanager->find_check_constraint_name($table, $field);
$result = $dbman->find_check_constraint_name($table, $field);
$this->assertTrue(!empty($result));
}
public function testCheckConstraintExists() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$field = $table->getField('type');
$this->assertTrue($dbmanager->check_constraint_exists($table, $field), 'type');
$this->assertTrue($dbman->check_constraint_exists($table, $field), 'type');
}
public function testFindKeyName() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$key = $table->getKey('primary');
$invalid_key = 'invalid_key';
ob_start(); // hide debug warning
$result = $dbmanager->find_key_name($table, $invalid_key);
$result = $dbman->find_key_name($table, $invalid_key);
ob_end_clean();
$this->assertFalse($result);
// With Mysql, the return value is actually "mdl_test_id_pk"
$result = $dbmanager->find_key_name($table, $key);
$result = $dbman->find_key_name($table, $key);
$this->assertTrue(!empty($result));
}
public function testFindSequenceName() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
// give invalid table param
$table = 'invalid_table';
ob_start(); // hide debug warning
$result = $dbmanager->find_sequence_name($table);
$result = $dbman->find_sequence_name($table);
ob_end_clean();
$this->assertFalse($result);
// give nonexistent table param
$table = new xmldb_table("nonexistenttable");
ob_start(); // hide debug warning
$result = $dbmanager->find_sequence_name($table);
$result = $dbman->find_sequence_name($table);
ob_end_clean();
$this->assertFalse($result);
// Give existing and valid table param
$table = $this->create_deftable('test_table0');
//TODO: this returns stuff depending on db internals
// $this->assertEqual(false, $dbmanager->find_sequence_name($table));
// $this->assertEqual(false, $dbman->find_sequence_name($table));
}
public function testDeleteTablesFromXmldbFile() {
global $CFG;
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$this->create_deftable('test_table1');
$this->assertTrue($dbmanager->table_exists('test_table1'));
$this->assertTrue($dbman->table_exists('test_table1'));
// feed nonexistent file
ob_start(); // hide debug warning
$result = $dbmanager->delete_tables_from_xmldb_file('fpsoiudfposui', false);
$result = $dbman->delete_tables_from_xmldb_file('fpsoiudfposui', false);
ob_end_clean();
$this->assertFalse($result);
// Real file but invalid xml file
ob_start(); // hide debug warning
$result = $dbmanager->delete_tables_from_xmldb_file($CFG->libdir . '/ddl/simpletest/fixtures/invalid.xml', false);
$result = $dbman->delete_tables_from_xmldb_file($CFG->libdir . '/ddl/simpletest/fixtures/invalid.xml', false);
ob_end_clean();
$this->assertFalse($result);
// Check that the table has not been deleted from DB
$this->assertTrue($dbmanager->table_exists('test_table1'));
$this->assertTrue($dbman->table_exists('test_table1'));
// Real and valid xml file
$this->assertTrue($dbmanager->delete_tables_from_xmldb_file($CFG->libdir . '/ddl/simpletest/fixtures/xmldb_table.xml', false));
$this->assertTrue($dbman->delete_tables_from_xmldb_file($CFG->libdir . '/ddl/simpletest/fixtures/xmldb_table.xml', false));
// Check that the table has been deleted from DB
$this->assertFalse($dbmanager->table_exists('test_table1'));
$this->assertFalse($dbman->table_exists('test_table1'));
}
public function testInstallFromXmldbFile() {
global $CFG;
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
// feed nonexistent file
ob_start(); // hide debug warning
$result = $dbmanager->install_from_xmldb_file('fpsoiudfposui', false);
$result = $dbman->install_from_xmldb_file('fpsoiudfposui', false);
ob_end_clean();
$this->assertFalse($result);
// Real but invalid xml file
ob_start(); // hide debug warning
$result = $dbmanager->install_from_xmldb_file($CFG->libdir.'/ddl/simpletest/fixtures/invalid.xml', false);
$result = $dbman->install_from_xmldb_file($CFG->libdir.'/ddl/simpletest/fixtures/invalid.xml', false);
ob_end_clean();
$this->assertFalse($result);
// Check that the table has not yet been created in DB
$this->assertFalse($dbmanager->table_exists('test_table1'));
$this->assertFalse($dbman->table_exists('test_table1'));
// Real and valid xml file
$this->assertTrue($dbmanager->install_from_xmldb_file($CFG->libdir.'/ddl/simpletest/fixtures/xmldb_table.xml', false));
$this->assertTrue($dbmanager->table_exists('test_table1'));
$this->assertTrue($dbman->install_from_xmldb_file($CFG->libdir.'/ddl/simpletest/fixtures/xmldb_table.xml', false));
$this->assertTrue($dbman->table_exists('test_table1'));
}
public function testCreateTempTable() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
// Feed incorrect table param
ob_start(); // hide debug warning
$result = $dbmanager->create_temp_table('test_table1');
$result = $dbman->create_temp_table('test_table1');
ob_end_clean();
$this->assertFalse($result);
$table = $this->tables['test_table1'];
// New table
$this->assertTrue($dbmanager->create_temp_table($table));
$this->assertTrue($dbmanager->table_exists('test_table1', true));
$this->assertTrue($dbman->create_temp_table($table));
$this->assertTrue($dbman->table_exists('test_table1', true));
// Delete
$this->assertTrue($dbmanager->drop_temp_table($table));
$this->assertFalse($dbmanager->table_exists('test_table1', true));
$this->assertTrue($dbman->drop_temp_table($table));
$this->assertFalse($dbman->table_exists('test_table1', true));
}
@ -819,24 +819,24 @@ class ddllib_test extends UnitTestCase {
/*
public function testRenameIndex() {
// unsupported!
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$index = new xmldb_index('course');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('course'));
$this->assertTrue($dbmanager->rename_index($table, $index, 'newindexname'));
$this->assertTrue($dbman->rename_index($table, $index, 'newindexname'));
}
public function testRenameKey() {
//unsupported
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = $this->create_deftable('test_table0');
$key = new xmldb_key('course');
$key->set_attributes(XMLDB_KEY_UNIQUE, array('course'));
$this->assertTrue($dbmanager->rename_key($table, $key, 'newkeyname'));
$this->assertTrue($dbman->rename_key($table, $key, 'newkeyname'));
}
*/

View File

@ -424,81 +424,33 @@ function get_current_group($courseid, $full = false) {
}
/**
* Print an error page displaying an error message.
* Old method, don't call directly in new code - use print_error instead.
*
*
* @uses $SESSION
* @uses $CFG
* @param string $message The message to display to the user about the error.
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
* @return terminates script, does not return!
*/
function error($message, $link='') {
global $CFG, $SESSION, $THEME, $UNITTEST;
global $UNITTEST;
$message = clean_text($message); // In case nasties are in here
/**
* TODO VERY DIRTY HACK USED FOR UNIT TESTING UNTIL PROPER EXCEPTION HANDLING IS IMPLEMENTED
*/
// If unittest running, throw exception instead
if (!empty($UNITTEST->running)) {
// Errors in unit test become exceptions, so you can unit test
// code that might call error().
throw new Exception('error() call: '. $message.($link!=='' ? ' ['.$link.']' : ''));
throw new moodle_exception('notlocalisederrormessage', 'error', $link, $message);
}
debugging('error() is a deprecated function, please call print_error() instead of error()', DEBUG_DEVELOPER);
if (defined('FULLME') && FULLME == 'cron') {
// Errors in cron should be mtrace'd.
mtrace($message);
die;
}
if (! defined('HEADER_PRINTED')) {
//header not yet printed
@header('HTTP/1.0 404 Not Found');
print_header(get_string('error'));
} else {
print_container_end_all(false, $THEME->open_header_containers);
}
echo '<br />';
print_simple_box($message, '', '', '', '', 'errorbox');
debugging('Stack trace:', DEBUG_DEVELOPER);
// in case we are logging upgrade in admin/index.php stop it
if (function_exists('upgrade_log_finish')) {
upgrade_log_finish();
}
if (empty($link) and !defined('ADMIN_EXT_HEADER_PRINTED')) {
if ( !empty($SESSION->fromurl) ) {
$link = $SESSION->fromurl;
unset($SESSION->fromurl);
} else {
$link = $CFG->wwwroot .'/';
}
}
if (!empty($link)) {
print_continue($link);
}
print_footer();
for ($i=0;$i<512;$i++) { // Padding to help IE work with 404
echo ' ';
}
die;
_print_normal_error('notlocalisederrormessage', 'error', $message, $link, debug_backtrace(), true); // show debug warning
}
/// removed functions
//////////////////////////
/// removed functions ////
//////////////////////////
function addslashes_object($dataobject) {
error('addslashes() not available anymore');
}

View File

@ -10,18 +10,18 @@ if (!defined('MOODLE_INTERNAL')) {
class dmllib_test extends UnitTestCase {
private $tables = array();
private $db;
private $tdb;
function setUp() {
global $CFG, $DB, $UNITTEST;
if (isset($UNITTEST->func_test_db)) {
$this->db = $UNITTEST->func_test_db;
$this->tdb = $UNITTEST->func_test_db;
} else {
$this->db = $DB;
$this->tdb = $DB;
}
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
$table = new xmldb_table("testtable");
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
@ -50,28 +50,28 @@ class dmllib_test extends UnitTestCase {
$table->add_index('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
$table->setComment("This is a test'n drop table. You can drop it safely");
if ($dbmanager->table_exists($table)) {
$dbmanager->drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$dbman->drop_table($table, true, false);
}
$dbmanager->create_table($table);
$dbman->create_table($table);
$this->tables[$table->getName()] = $table;
}
function tearDown() {
$dbmanager = $this->db->get_manager();
$dbman = $this->tdb->get_manager();
foreach ($this->tables as $table) {
if ($dbmanager->table_exists($table)) {
$dbmanager->drop_table($table, true, false);
if ($dbman->table_exists($table)) {
$dbman->drop_table($table, true, false);
}
}
$this->tables = array();
}
function test_fix_sql_params() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
// Malformed table placeholder
$sql = "SELECT * FROM [testtable]";
@ -94,78 +94,73 @@ class dmllib_test extends UnitTestCase {
$params = array('param1' => 'first record', 'param2' => 1);
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(false);
} catch (Exception $e) {
$this->assertEqual('error() call: ERROR: Mixed types of sql query parameters!!', $e->getMessage());
$this->assertTrue($e instanceof moodle_exception);
}
// Mixed param types (question and dollar)
$sql = "SELECT * FROM {testtable} WHERE name = ?, rsstype = \$1";
$params = array('param1' => 'first record', 'param2' => 1);
$exception_caught = false;
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(false);
} catch (Exception $e) {
$exception_caught = true;
$this->assertTrue($e instanceof moodle_exception);
}
$this->assertTrue($exception_caught);
// Too many params in sql
$sql = "SELECT * FROM {testtable} WHERE name = ?, rsstype = ?, course = ?";
$params = array('first record', 1);
$exception_caught = false;
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(false);
} catch (Exception $e) {
$exception_caught = true;
$this->assertTrue($e instanceof moodle_exception);
}
$this->assertTrue($exception_caught);
// Too many params in array: no error
$params[] = 1;
$params[] = time();
$exception_caught = false;
$sqlarray = null;
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(true);
} catch (Exception $e) {
$exception_caught = true;
$this->assertTrue(false);
}
$this->assertFalse($exception_caught);
$this->assertTrue($sqlarray[0]);
// Named params missing from array
$sql = "SELECT * FROM {testtable} WHERE name = :name, rsstype = :rsstype";
$params = array('wrongname' => 'first record', 'rsstype' => 1);
$exception_caught = false;
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(false);
} catch (Exception $e) {
$exception_caught = true;
$this->assertTrue($e instanceof moodle_exception);
}
$this->assertTrue($exception_caught);
// Duplicate named param in query
$sql = "SELECT * FROM {testtable} WHERE name = :name, rsstype = :name";
$params = array('name' => 'first record', 'rsstype' => 1);
$exception_caught = false;
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(false);
} catch (Exception $e) {
$exception_caught = true;
$this->assertTrue($e instanceof moodle_exception);
}
$this->assertTrue($exception_caught);
// Unsupported Bound params
$sql = "SELECT * FROM {testtable} WHERE name = $1, rsstype = $2";
$params = array('first record', 1);
$exception_caught = false;
try {
$sqlarray = $DB->fix_sql_params($sql, $params);
$this->assertTrue(false);
} catch (Exception $e) {
$exception_caught = true;
$this->assertTrue($e instanceof moodle_exception);
}
$this->assertTrue($exception_caught);
// Correct named param placeholders
$sql = "SELECT * FROM {testtable} WHERE name = :name, rsstype = :rsstype";
@ -184,16 +179,16 @@ class dmllib_test extends UnitTestCase {
}
public function testGetTables() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
// Need to test with multiple DBs
$this->assertTrue($DB->get_tables() > 2);
}
public function testGetIndexes() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$this->assertTrue($indices = $DB->get_indexes('testtable'));
$this->assertTrue(count($indices) == 1);
@ -215,8 +210,8 @@ class dmllib_test extends UnitTestCase {
}
public function testGetColumns() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$this->assertTrue($columns = $DB->get_columns('testtable'));
$fields = $this->tables['testtable']->getFields();
@ -236,8 +231,8 @@ class dmllib_test extends UnitTestCase {
}
public function testExecute() {
$DB = $this->db; // do not use global $DB!
$dbmanager = $this->db->get_manager();
$DB = $this->tdb; // do not use global $DB!
$dbman = $this->tdb->get_manager();
$sql = "SELECT * FROM {testtable}";
$this->assertTrue($DB->execute($sql));

View File

@ -139,6 +139,9 @@ global $HTTPSPAGEREQUIRED;
//the problem is that we need specific version of quickforms and hacked excel files :-(
ini_set('include_path', $CFG->libdir.'/pear' . PATH_SEPARATOR . ini_get('include_path'));
/// set handler for uncought exceptions - equivalent to print_error() call
set_exception_handler('default_exception_handler');
/// Connect to the database
setup_DB();

View File

@ -1,6 +1,6 @@
<?php // $Id$
// These functions are required very early in the Moodle
// setup process, before any of the main libraries are
<?php // $Id$
// These functions are required very early in the Moodle
// setup process, before any of the main libraries are
// loaded.
@ -9,22 +9,68 @@
*/
class object {};
/**
* Base Moodle Exception class
*/
class moodle_exception extends Exception {
public $errorcode;
public $module;
public $a;
public $link;
/**
* Constructor
* @param string $errorcode The name of the string from error.php to print
* @param string $module name of module
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
* @param object $a Extra words and phrases that might be required in the error string
*/
function __construct($errorcode, $module='', $link='', $a=NULL) {
if (empty($module) || $module == 'moodle' || $module == 'core') {
$module = 'error';
}
$this->errorcode = $errorcode;
$this->module = $module;
$this->link = $link;
$this->a = $a;
$message = get_string($errorcode, $module, $a);
parent::__construct($message, 0);
}
}
/**
* Default exception handler, uncought exceptions are equivalent to using print_error()
*/
function default_exception_handler($ex) {
$backtrace = $ex->getTrace();
$place = array('file'=>$ex->getFile(), 'line'=>$ex->getLine(), 'exception'=>get_class($ex));
array_unshift($backtrace, $place);
if ($ex instanceof moodle_exception) {
_print_normal_error($ex->errorcode, $ex->module, $ex->a, $ex->link, $backtrace);
} else {
_print_normal_error('generalexceptionmessage', 'error', $ex->getMessage(), '', $backtrace);
}
}
/**
* Initializes our performance info early.
*
* Pairs up with get_performance_info() which is actually
* in moodlelib.php. This function is here so that we can
* call it before all the libs are pulled in.
* in moodlelib.php. This function is here so that we can
* call it before all the libs are pulled in.
*
* @uses $PERF
*/
function init_performance_info() {
global $PERF, $CFG, $USER;
$PERF = new Object;
$PERF->dbqueries = 0;
$PERF->dbqueries = 0;
$PERF->logwrites = 0;
if (function_exists('microtime')) {
$PERF->starttime = microtime();
@ -33,12 +79,12 @@ function init_performance_info() {
$PERF->startmemory = memory_get_usage();
}
if (function_exists('posix_times')) {
$PERF->startposixtimes = posix_times();
$PERF->startposixtimes = posix_times();
}
if (function_exists('apd_set_pprof_trace')) {
// APD profiling
if ($USER->id > 0 && $CFG->perfdebug >= 15) {
$tempdir = $CFG->dataroot . '/temp/profile/' . $USER->id;
$tempdir = $CFG->dataroot . '/temp/profile/' . $USER->id;
mkdir($tempdir);
apd_set_pprof_trace($tempdir);
$PERF->profiling = true;
@ -130,7 +176,7 @@ function make_upload_directory($directory, $shownotices=true) {
if (!file_exists($currdir)) {
if (! mkdir($currdir, $CFG->directorypermissions)) {
if ($shownotices) {
echo '<div class="notifyproblem" align="center">ERROR: You need to create the directory '.
echo '<div class="notifyproblem" align="center">ERROR: You need to create the directory '.
$currdir .' with web server write access</div>'."<br />\n";
}
return false;
@ -152,7 +198,7 @@ function make_upload_directory($directory, $shownotices=true) {
if (! file_exists($currdir)) {
if (! mkdir($currdir, $CFG->directorypermissions)) {
if ($shownotices) {
echo '<div class="notifyproblem" align="center">ERROR: Could not find or create a directory ('.
echo '<div class="notifyproblem" align="center">ERROR: Could not find or create a directory ('.
$currdir .')</div>'."<br />\n";
}
return false;
@ -171,9 +217,9 @@ function init_memcached() {
$MCACHE = new memcached;
if ($MCACHE->status()) {
return true;
}
}
unset($MCACHE);
return false;
return false;
}
function init_eaccelerator() {
@ -183,7 +229,7 @@ function init_eaccelerator() {
$MCACHE = new eaccelerator;
if ($MCACHE->status()) {
return true;
}
}
unset($MCACHE);
return false;
}

View File

@ -5593,18 +5593,41 @@ function print_scale_menu_helpbutton($courseid, $scale, $return=false) {
/**
* Print an error page displaying an error message. New method - use this for new code.
*
* @uses $SESSION
* @uses $CFG
* @param string $errorcode The name of the string from error.php to print
* @param string $module name of module
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
* @param object $a Extra words and phrases that might be required in the error string
* @return terminates script, does not return!
*/
function print_error ($errorcode, $module='', $link='', $a=NULL) {
global $CFG, $SESSION, $THEME, $UNITTEST;
function print_error($errorcode, $module='', $link='', $a=NULL) {
global $CFG, $UNITTEST;
// If unittest running, throw exception instead
if (!empty($UNITTEST->running)) {
// Errors in unit test become exceptions, so you can unit test
// code that might call error().
throw new moodle_exception($errorcode, $module, $link, $a);
}
if (empty($module) || $module == 'moodle' || $module == 'core') {
$module = 'error';
}
if (!isset($CFG->theme)) {
// error found before setup.php finished
_print_early_error($errorcode, $module, $a);
} else {
_print_normal_error($errorcode, $module, $a, $link, debug_backtrace());
}
}
/**
* Internal function - do not use directly!!
*/
function _print_normal_error($errorcode, $module, $a, $link, $backtrace, $showerrordebugwarning=false) {
global $CFG, $SESSION, $THEME;
if ($module == 'error') {
$modulelink = 'moodle';
} else {
$modulelink = $module;
@ -5612,19 +5635,10 @@ function print_error ($errorcode, $module='', $link='', $a=NULL) {
$message = get_string($errorcode, $module, $a);
/**
* TODO VERY DIRTY HACK USED FOR UNIT TESTING UNTIL PROPER EXCEPTION HANDLING IS IMPLEMENTED
*/
if (!empty($UNITTEST->running)) {
// Errors in unit test become exceptions, so you can unit test
// code that might call error().
throw new Exception('error() call: '. $message.($link!=='' ? ' ['.$link.']' : ''));
}
if (!isset($CFG->theme)) {
// error found before setup.php finished
print_early_error($message);
if (defined('FULLME') && FULLME == 'cron') {
// Errors in cron should be mtrace'd.
mtrace($message);
die;
}
if (empty($link) and !defined('ADMIN_EXT_HEADER_PRINTED')) {
@ -5644,17 +5658,6 @@ function print_error ($errorcode, $module='', $link='', $a=NULL) {
$errordocroot = 'http://docs.moodle.org';
}
if (defined('FULLME') && FULLME == 'cron') {
// Errors in cron should be mtrace'd.
mtrace($message);
die;
}
$message = clean_text('<p class="errormessage">'.$message.'</p>'.
'<p class="errorcode">'.
'<a href="'.$errordocroot.'/en/error/'.$modulelink.'/'.$errorcode.'">'.
get_string('moreinformation').'</a></p>');
if (! defined('HEADER_PRINTED')) {
//header not yet printed
@header('HTTP/1.0 404 Not Found');
@ -5665,9 +5668,21 @@ function print_error ($errorcode, $module='', $link='', $a=NULL) {
echo '<br />';
$message = clean_text('<p class="errormessage">'.$message.'</p>'.
'<p class="errorcode">'.
'<a href="'.$errordocroot.'/en/error/'.$modulelink.'/'.$errorcode.'">'.
get_string('moreinformation').'</a></p>');
print_simple_box($message, '', '', '', '', 'errorbox');
debugging('Stack trace:', DEBUG_DEVELOPER);
if ($showerrordebugwarning) {
debugging('error() is a deprecated function, please call print_error() instead of error()', DEBUG_DEVELOPER);
} else {
if (debugging('', DEBUG_DEVELOPER)) {
notify('Stack trace:'.print_backtrace($backtrace, true), 'notifytiny');
}
}
// in case we are logging upgrade in admin/index.php stop it
if (function_exists('upgrade_log_finish')) {
@ -5687,14 +5702,12 @@ function print_error ($errorcode, $module='', $link='', $a=NULL) {
}
/**
* Internal function - do not use directly
* Internal function - do not use directly!!
* This function is used if fatal error occures before the themes are fully initialised (eg. in lib/setup.php)
* @param string $errorcode The name of the string from error.php to print
* @param string $link The url where the user will be prompted to continue. If no url is provided the user will be directed to the site index page.
* @param object $a Extra words and phrases that might be required in the error string
* @return terminates script, does not return!
*/
function print_early_error($message) {
function _print_early_error($errorcode, $module, $a) {
$message = clean_text(get_string($errorcode, $module, $a));
// In the name of protocol correctness, monitoring and performance
// profiling, set the appropriate error headers for machine comsumption
if (isset($_SERVER['SERVER_PROTOCOL'])) {
@ -5719,7 +5732,7 @@ function print_early_error($message) {
<div style="margin-top: 6em; margin-left:auto; margin-right:auto; color:#990000; text-align:center; font-size:large; border-width:1px;
border-color:black; background-color:#ffffee; border-style:solid; border-radius: 20px; border-collapse: collapse;
width: 80%; -moz-border-radius: 20px; padding: 15px">
'.clean_text($message, FORMAT_HTML).'
'.$message.'
</div>
</body></html>';
die;
@ -6853,25 +6866,7 @@ function debugging($message='', $level=DEBUG_NORMAL) {
if ($CFG->debug >= $level) {
if ($message) {
$callers = debug_backtrace();
$from = '<ul style="text-align: left">';
foreach ($callers as $caller) {
if (!isset($caller['line'])) {
$caller['line'] = '?'; // probably call_user_func()
}
if (!isset($caller['file'])) {
$caller['file'] = $CFG->dirroot.'/unknownfile'; // probably call_user_func()
}
$from .= '<li>line ' . $caller['line'] . ' of ' . substr($caller['file'], strlen($CFG->dirroot) + 1);
if (isset($caller['function'])) {
$from .= ': call to ';
if (isset($caller['class'])) {
$from .= $caller['class'] . $caller['type'];
}
$from .= $caller['function'] . '()';
}
$from .= '</li>';
}
$from .= '</ul>';
$from = print_backtrace($callers, true);
if (!isset($CFG->debugdisplay)) {
$CFG->debugdisplay = ini_get('display_errors');
}
@ -6889,6 +6884,44 @@ function debugging($message='', $level=DEBUG_NORMAL) {
return false;
}
/**
* Prints formatted backtrace
* @param backtrace array
* @param return return as string or print
* @return mixed
*/
function print_backtrace($callers, $return=false) {
global $CFG;
$from = '<ul style="text-align: left">';
foreach ($callers as $caller) {
if (!isset($caller['line'])) {
$caller['line'] = '?'; // probably call_user_func()
}
if (!isset($caller['file'])) {
$caller['file'] = $CFG->dirroot.'/unknownfile'; // probably call_user_func()
}
$from .= '<li>line ' . $caller['line'] . ' of ' . substr($caller['file'], strlen($CFG->dirroot) + 1);
if (isset($caller['function'])) {
$from .= ': call to ';
if (isset($caller['class'])) {
$from .= $caller['class'] . $caller['type'];
}
$from .= $caller['function'] . '()';
} else if (isset($caller['exception'])) {
$from .= ': '.$caller['exception'].' thrown';
}
$from .= '</li>';
}
$from .= '</ul>';
if ($return) {
return $from;
} else {
echo $from;
}
}
/**
* Disable debug messages from debugging(), while keeping PHP error reporting level as is.
*/