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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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 '',
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ''
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
'<meta name="description" content="'. s(strip_tags($site->summary)) .'" />',
|
||||
true, '', $loginstring . $langmenu);
|
||||
|
||||
$editing = isediting($site->id);
|
||||
$editing = $PAGE->user_is_editing();
|
||||
|
||||
$pageblocks = blocks_get_by_page($PAGE);
|
||||
|
||||
|
||||
+13
-6
@@ -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)) {
|
||||
|
||||
+106
-20
@@ -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 <strong>user_allowed_editing()</strong>', E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
function user_is_editing() {
|
||||
trigger_error('Page class does not implement method <strong>user_is_editing()</strong>', 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 <strong>print_header()</strong>', 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 <strong>blocks_default_position()</strong>', 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 <strong>url_get_path()</strong>', 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 <strong>get_type()</strong>', 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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user