From: defacer Date: Fri, 12 Nov 2004 18:39:25 +0000 (+0000) Subject: Pages/blocks code updates: X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=c8e0b57900eec70bec2b6dedf476286117a4a762;p=moodle.git Pages/blocks code updates: NEW: The code now supports dynamically plugging your own Pages and block position identifiers into Moodle without messing with the main libraries at all. UPDATE: Many functions in blocklib now use pass-by-reference for speed. UPDATE: Class MoodlePage has been made more presentable and robust. --- diff --git a/blocks/db/mysql.php b/blocks/db/mysql.php index 1b573ee733..2123123d98 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 fe9b44f1af..6dfae52cab 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 1c0cb7f5b3..ec0acfac97 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 2eb2c2a8d9..53598786ed 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 3e3151a6dd..776025f03c 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 a2d7d774af..424b155354 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 6346572e1c..96fa0ef421 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 ed63b5d224..aeeab460a5 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(); } + + // 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' - ); - - if(!isset($typeids[$type])) { - error('Unrecognized type passed to MoodlePage::create_object: '. $type); - } + $classname = MoodlePage::map_page_type($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 c06cdd3593..0360d2cbf2 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