diff --git a/blocks/db/mysql.php b/blocks/db/mysql.php
index 1b573ee733e..2123123d98f 100644
--- a/blocks/db/mysql.php
+++ b/blocks/db/mysql.php
@@ -121,6 +121,11 @@ global $CFG;
execute_sql("ALTER TABLE `{$CFG->prefix}course` DROP COLUMN blockinfo");
}
+ if ($oldversion < 2004112900 && $result) {
+ $result = $result && table_column('block_instance', 'pagetype', 'pagetype', 'varchar', '20', '');
+ $result = $result && table_column('block_instance', 'position', 'position', 'varchar', '10', '');
+ }
+
//Finally, return result
return $result;
}
diff --git a/blocks/db/mysql.sql b/blocks/db/mysql.sql
index fe9b44f1af5..6dfae52caba 100644
--- a/blocks/db/mysql.sql
+++ b/blocks/db/mysql.sql
@@ -18,8 +18,8 @@ CREATE TABLE `prefix_block_instance` (
`id` int(10) not null auto_increment,
`blockid` int(10) not null default '0',
`pageid` int(10) not null default '0',
- `pagetype` enum('course') not null,
- `position` enum('l', 'r') not null,
+ `pagetype` varchar(20) not null default '',
+ `position` varchar(10) not null default '',
`weight` tinyint(3) not null default '0',
`visible` tinyint(1) not null default '0',
`configdata` text not null default '',
diff --git a/blocks/db/postgres7.php b/blocks/db/postgres7.php
index 1c0cb7f5b39..ec0acfac97d 100644
--- a/blocks/db/postgres7.php
+++ b/blocks/db/postgres7.php
@@ -119,6 +119,11 @@ global $CFG;
execute_sql("ALTER TABLE {$CFG->prefix}course DROP COLUMN blockinfo");
}
+ if ($oldversion < 2004112900 && $result) {
+ $result = $result && table_column('block_instance', 'pagetype', 'pagetype', 'varchar', '20', '');
+ $result = $result && table_column('block_instance', 'position', 'position', 'varchar', '10', '');
+ }
+
//Finally, return result
return $result;
}
diff --git a/blocks/db/postgres7.sql b/blocks/db/postgres7.sql
index 2eb2c2a8d96..53598786edd 100644
--- a/blocks/db/postgres7.sql
+++ b/blocks/db/postgres7.sql
@@ -17,8 +17,8 @@ CREATE TABLE prefix_block_instance (
id SERIAL8 PRIMARY KEY,
blockid INT8 not null default '0',
pageid INT8 not null default '0',
- pagetype varchar(12) not null check (pagetype in ('course')),
- position char not null check (position in ('l', 'r')),
+ pagetype varchar(20) not null default '',
+ position varchar(10) not null default '',
weight int not null default '0',
visible int not null default '0',
configdata text not null default ''
diff --git a/blocks/version.php b/blocks/version.php
index 3e3151a6dde..776025f03c7 100644
--- a/blocks/version.php
+++ b/blocks/version.php
@@ -5,4 +5,4 @@
// database (blocks_version) to determine whether upgrades should
// be performed (see db/backup_*.php)
-$blocks_version = 2004101900; // The current version is a date (YYYYMMDDXX)
+$blocks_version = 2004111200; // The current version is a date (YYYYMMDDXX)
diff --git a/index.php b/index.php
index a2d7d774af7..424b1553540 100644
--- a/index.php
+++ b/index.php
@@ -61,7 +61,7 @@
'',
true, '', $loginstring . $langmenu);
- $editing = isediting($site->id);
+ $editing = $PAGE->user_is_editing();
$pageblocks = blocks_get_by_page($PAGE);
diff --git a/lib/blocklib.php b/lib/blocklib.php
index 6346572e1c2..96fa0ef421f 100644
--- a/lib/blocklib.php
+++ b/lib/blocklib.php
@@ -90,7 +90,9 @@ function block_load_class($blockname) {
return class_exists($classname);
}
-function blocks_get_missing($page, $pageblocks) {
+// This function returns an array with the IDs of any blocks that you can add to your page.
+// Parameters are passed by reference for speed; they are not modified at all.
+function blocks_get_missing(&$page, &$pageblocks) {
$missingblocks = array();
$allblocks = blocks_get_record();
@@ -147,7 +149,10 @@ function blocks_delete_instance($instance) {
'\' AND weight > '.$instance->weight, false);
}
-function blocks_have_content($instances) {
+// Accepts an array of block instances and checks to see if any of them have content to display
+// (causing them to calculate their content in the process). Returns true or false. Parameter passed
+// by reference for speed; the array is actually not modified.
+function blocks_have_content(&$instances) {
foreach($instances as $instance) {
if(!$instance->visible) {
continue;
@@ -174,8 +179,9 @@ function blocks_have_content($instances) {
return false;
}
-//This function prints one side of the blocks in the course main page
-function blocks_print_group($page, $instances) {
+// This function prints one group of blocks in a page
+// Parameters passed by reference for speed; they are not modified.
+function blocks_print_group(&$page, &$instances) {
if(empty($instances)) {
return;
@@ -222,8 +228,9 @@ function blocks_print_group($page, $instances) {
}
}
-//This iterates over an array of blocks and calculates the preferred width
-function blocks_preferred_width($instances) {
+// This iterates over an array of blocks and calculates the preferred width
+// Parameter passed by reference for speed; it's not modified.
+function blocks_preferred_width(&$instances) {
$width = 0;
if(empty($instances) || !is_array($instances)) {
diff --git a/lib/pagelib.php b/lib/pagelib.php
index ed63b5d224b..aeeab460a5e 100644
--- a/lib/pagelib.php
+++ b/lib/pagelib.php
@@ -48,15 +48,68 @@ class MoodlePage {
/// Class Functions
+ // USER-RELATED THINGS
+
+ // By default, no user is editing anything and none CAN edit anything. Developers
+ // will have to override these settings to let Moodle know when it should grant
+ // editing rights to the user viewing the page.
+ function user_allowed_editing() {
+ trigger_error('Page class does not implement method user_allowed_editing()', E_USER_WARNING);
+ return false;
+ }
+ function user_is_editing() {
+ trigger_error('Page class does not implement method user_is_editing()', E_USER_WARNING);
+ return false;
+ }
+
+ // HTML OUTPUT SECTION
+
+ // We have absolutely no idea what derived pages are all about
+ function print_header($title) {
+ trigger_error('Page class does not implement method print_header()', E_USER_WARNING);
+ return;
+ }
+
+ // BLOCKS RELATED SECTION
+
+ // By default, pages don't have any blocks. Override this in your derived class if you need blocks.
function blocks_get_positions() {
return array();
}
- function url_get_path() {
+
+ // Thus there is no default block position. If you override the above you should override this one too.
+ // Because this makes sense only if blocks_get_positions() is overridden and because these two should
+ // be overridden as a group or not at all, this one issues a warning. The sneaky part is that this warning
+ // will only be seen if you override blocks_get_positions() but NOT blocks_default_position().
+ function blocks_default_position() {
+ trigger_error('Page class does not implement method blocks_default_position()', E_USER_WARNING);
return NULL;
}
+
+ // If you don't override this, newly constructed pages of this kind won't have any blocks.
+ function blocks_get_default() {
+ return '';
+ }
+
+ // If you don't override this, your blocks will not be able to change positions
+ function blocks_move_position(&$instance, $move) {
+ return $instance->position;
+ }
+
+ // SELF-REPORTING SECTION
+
+ // Derived classes HAVE to define their "home url"
+ function url_get_path() {
+ trigger_error('Page class does not implement method url_get_path()', E_USER_WARNING);
+ return NULL;
+ }
+
+ // It's not always required to pass any arguments to the home url, so this doesn't trigger any errors (sensible default)
function url_get_parameters() {
return array();
}
+
+ // This should actually NEVER be overridden unless you have GOOD reason. Works fine as it is.
function url_get_full($extraparams = array()) {
$path = $this->url_get_path();
if(empty($path)) {
@@ -80,44 +133,49 @@ class MoodlePage {
return $path;
}
+
+ // This forces implementers to actually hardwire their page identification constant in the class.
+ // Good thing, if you ask me. That way we can later auto-detect "installed" page types by querying
+ // the classes themselves in the future.
function get_type() {
- error('get_type() called on a page object which is not correctly implemented');
+ trigger_error('Page class does not implement method get_type()', E_USER_ERROR);
+ return NULL;
}
+
+ // Simple stuff, do not override this.
function get_id() {
return $this->id;
}
+
+ // "Sensible default" case here. Don't trigger any error.
function get_format_name() {
return NULL;
}
- function user_allowed_editing() {
- return false;
- }
- function user_is_editing() {
- return false;
- }
+ // Initialize the data members of the parent class
function init_quick($data) {
$this->type = $data->pagetype;
$this->id = $data->pageid;
}
+ function init_full() {
+ $this->full_init_done = true;
+ }
+
+ // DO NOT TOUCH! NEVER! SECTION
+
+ // Factory method MoodlePage::create_object(). Called with a pagetype identifier and possibly with
+ // its numeric ID. Returns a fully constructed MoodlePage subclass you can work with.
function create_object($type, $id = NULL) {
$data = new stdClass;
$data->pagetype = $type;
$data->pageid = $id;
- // This might be moved somewhere more easily accessible from the outside,
- // as anyone that implements a new Page class will need to add a line here.
- $typeids = array(
- MOODLE_PAGE_COURSE => 'MoodlePage_Course'
- );
+ $classname = MoodlePage::map_page_type($type);
- if(!isset($typeids[$type])) {
- error('Unrecognized type passed to MoodlePage::create_object: '. $type);
- }
-
- $object = &new $typeids[$type];
+ $object = &new $classname;
+ // TODO: subclassing check here
if($object->get_type() !== $type) {
// Somehow somewhere someone made a mistake
@@ -127,6 +185,28 @@ class MoodlePage {
$object->init_quick($data);
return $object;
}
+
+ // Method map_page_type() is the way for your code to define its own Page subclasses and let Moodle recognize them.
+ // Use it to associate the textual identifier of your Page with the actual class name that has to be instantiated.
+ function map_page_type($type, $classname = NULL) {
+ static $mappings = array(
+ MOODLE_PAGE_COURSE => 'MoodlePage_Course'
+ );
+
+ if(!empty($type) && !empty($classname)) {
+ $mappings[$type] = $classname;
+ }
+ if(!isset($mappings[$type])) {
+ error('Page class mapping requested for unknown type: '.$type);
+ }
+
+ if(!class_exists($mappings[$type])) {
+ error('Page class mapping for id "'.$type.'" exists but class "'.$mappings[$type].'" is not defined');
+ }
+
+ return $mappings[$type];
+ }
+
}
@@ -168,6 +248,8 @@ class MoodlePage_Course extends MoodlePage {
$this->full_init_done = true;
}
+ // USER-RELATED THINGS
+
// When is a user said to have "editing rights" in this page? This would have something
// to do with roles, in the future.
function user_allowed_editing() {
@@ -180,7 +262,9 @@ class MoodlePage_Course extends MoodlePage {
return isediting($this->id);
}
- // HTML output section. This function prints out the common part of the page's header.
+ // HTML OUTPUT SECTION
+
+ // This function prints out the common part of the page's header.
// You should NEVER print the header "by hand" in other code.
function print_header($title) {
global $USER;
@@ -197,6 +281,8 @@ class MoodlePage_Course extends MoodlePage {
'', '', true, update_course_icon($this->courserecord->id), $loggedinas);
}
+ // SELF-REPORTING SECTION
+
// This is hardwired here so the factory method create_object() can be sure there was no mistake.
// Also, it doubles as a way to let others inquire about our type.
function get_type() {
@@ -233,7 +319,7 @@ class MoodlePage_Course extends MoodlePage {
}
}
- // Blocks-related section
+ // BLOCKS RELATED SECTION
// Which are the positions in this page which support blocks? Return an array containing their identifiers.
// BE CAREFUL, ORDER DOES MATTER! In textual representations, lists of blocks in a page use the ':' character
diff --git a/version.php b/version.php
index c06cdd3593f..0360d2cbf27 100644
--- a/version.php
+++ b/version.php
@@ -6,7 +6,7 @@
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)
- $version = 2004111000; // YYYYMMDD = date of first major branch release 1.4
+ $version = 2004111200; // YYYYMMDD = date of first major branch release 1.4
// XY = increments within a single day
$release = '1.5 UNSTABLE DEVELOPMENT'; // Human-friendly version name