2004-09-12 13:21:01 +00:00
< ? php //$Id$
2004-04-18 23:20:53 +00:00
//This library includes all the necessary stuff to use blocks in course pages
define ( 'BLOCK_MOVE_LEFT' , 0x01 );
define ( 'BLOCK_MOVE_RIGHT' , 0x02 );
define ( 'BLOCK_MOVE_UP' , 0x04 );
define ( 'BLOCK_MOVE_DOWN' , 0x08 );
2004-10-19 21:04:28 +00:00
define ( 'BLOCK_CONFIGURE' , 0x10 );
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
define ( 'BLOCK_POS_LEFT' , 'l' );
define ( 'BLOCK_POS_RIGHT' , 'r' );
2004-08-22 16:48:28 +00:00
2005-08-23 04:03:56 +00:00
define ( 'BLOCKS_PINNED_TRUE' , 0 );
define ( 'BLOCKS_PINNED_FALSE' , 1 );
define ( 'BLOCKS_PINNED_BOTH' , 2 );
2004-11-08 19:36:07 +00:00
require_once ( $CFG -> libdir . '/pagelib.php' );
2004-04-18 23:20:53 +00:00
2005-04-30 03:08:04 +00:00
// Returns false if this block is incompatible with the current version of Moodle.
function block_is_compatible ( $blockname ) {
global $CFG ;
$file = file ( $CFG -> dirroot . '/blocks/' . $blockname . '/block_' . $blockname . '.php' );
if ( empty ( $file )) {
return NULL ;
}
foreach ( $file as $line ) {
// If you find MoodleBlock (appearing in the class declaration) it's not compatible
if ( strpos ( $line , 'MoodleBlock' )) {
return false ;
}
// But if we find a { it means the class declaration is over, so it's compatible
else if ( strpos ( $line , '{' )) {
return true ;
}
}
return NULL ;
}
2004-06-18 12:25:27 +00:00
// Returns the case-sensitive name of the class' constructor function. This includes both
// PHP5- and PHP4-style constructors. If no appropriate constructor can be found, returns NULL.
// If there is no such class, returns boolean false.
function get_class_constructor ( $classname ) {
// Caching
static $constructors = array ();
if ( ! class_exists ( $classname )) {
return false ;
}
// Tests indicate this doesn't hurt even in PHP5.
$classname = strtolower ( $classname );
// Return cached value, if exists
if ( isset ( $constructors [ $classname ])) {
return $constructors [ $classname ];
}
// Get a list of methods. After examining several different ways of
// doing the check, (is_callable, method_exists, function_exists etc)
// it seems that this is the most reliable one.
$methods = get_class_methods ( $classname );
// PHP5 constructor?
if ( phpversion () >= '5' ) {
if ( in_array ( '__construct' , $methods )) {
return $constructors [ $classname ] = '__construct' ;
}
}
// If we have PHP5 but no magic constructor, we have to lowercase the methods
$methods = array_map ( 'strtolower' , $methods );
if ( in_array ( $classname , $methods )) {
return $constructors [ $classname ] = $classname ;
}
return $constructors [ $classname ] = NULL ;
}
2004-04-18 23:20:53 +00:00
//This function retrieves a method-defined property of a class WITHOUT instantiating an object
2005-12-17 04:37:55 +00:00
function block_method_result ( $blockname , $method , $param = NULL ) {
2004-04-18 23:20:53 +00:00
if ( ! block_load_class ( $blockname )) {
return NULL ;
}
2005-12-17 04:37:55 +00:00
return call_user_func ( array ( 'block_' . $blockname , $method ), $param );
2004-04-18 23:20:53 +00:00
}
//This function creates a new object of the specified block class
2004-10-19 21:04:28 +00:00
function block_instance ( $blockname , $instance = NULL ) {
2004-04-18 23:20:53 +00:00
if ( ! block_load_class ( $blockname )) {
return false ;
}
2004-11-23 18:53:34 +00:00
$classname = 'block_' . $blockname ;
2004-11-08 19:36:07 +00:00
$retval = new $classname ;
2004-10-19 21:04:28 +00:00
if ( $instance !== NULL ) {
2005-01-25 02:57:30 +00:00
$retval -> _load_instance ( $instance );
2004-10-19 21:04:28 +00:00
}
return $retval ;
2004-04-18 23:20:53 +00:00
}
//This function loads the necessary class files for a block
//Whenever you want to load a block, use this first
function block_load_class ( $blockname ) {
global $CFG ;
2005-12-17 03:09:13 +00:00
if ( empty ( $blockname )) {
2005-02-08 17:07:31 +00:00
return false ;
}
2004-11-23 18:53:34 +00:00
$classname = 'block_' . $blockname ;
2005-12-17 03:09:13 +00:00
if ( class_exists ( $classname )) {
return true ;
}
require_once ( $CFG -> dirroot . '/blocks/moodleblock.class.php' );
2005-01-27 23:57:37 +00:00
include_once ( $CFG -> dirroot . '/blocks/' . $blockname . '/block_' . $blockname . '.php' );
2004-04-18 23:20:53 +00:00
return class_exists ( $classname );
}
2004-11-12 18:39:25 +00:00
// 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 ) {
2004-11-08 19:36:07 +00:00
$missingblocks = array ();
$allblocks = blocks_get_record ();
$pageformat = $page -> get_format_name ();
if ( ! empty ( $allblocks )) {
foreach ( $allblocks as $block ) {
if ( $block -> visible && ( ! blocks_find_block ( $block -> id , $pageblocks ) || $block -> multiple )) {
// And if it's applicable for display in this format...
2005-02-10 18:43:18 +00:00
if ( blocks_name_allowed_in_format ( $block -> name , $pageformat )) {
2005-02-08 02:59:44 +00:00
// ...add it to the missing blocks
2004-11-08 19:36:07 +00:00
$missingblocks [] = $block -> id ;
}
}
}
}
return $missingblocks ;
}
function blocks_remove_inappropriate ( $page ) {
$pageblocks = blocks_get_by_page ( $page );
if ( empty ( $pageblocks )) {
return ;
}
if (( $pageformat = $page -> get_format_name ()) == NULL ) {
return ;
}
foreach ( $pageblocks as $position ) {
foreach ( $position as $instance ) {
$block = blocks_get_record ( $instance -> blockid );
2005-02-10 18:43:18 +00:00
if ( ! blocks_name_allowed_in_format ( $block -> name , $pageformat )) {
2005-02-08 02:59:44 +00:00
blocks_delete_instance ( $instance );
2004-11-08 19:36:07 +00:00
}
}
}
}
2005-02-10 18:43:18 +00:00
function blocks_name_allowed_in_format ( $name , $pageformat ) {
$formats = block_method_result ( $name , 'applicable_formats' );
$accept = NULL ;
$depth = - 1 ;
foreach ( $formats as $format => $allowed ) {
$thisformat = '^' . str_replace ( '*' , '[^-]*' , $format ) . '.*$' ;
if ( ereg ( $thisformat , $pageformat )) {
if (( $scount = substr_count ( $format , '-' )) > $depth ) {
$depth = $scount ;
$accept = $allowed ;
}
}
}
if ( $accept === NULL ) {
$accept = ! empty ( $formats [ 'all' ]);
}
return $accept ;
}
2005-08-16 00:25:39 +00:00
function blocks_delete_instance ( $instance , $pinned = false ) {
2004-11-08 19:36:07 +00:00
global $CFG ;
2005-06-13 03:32:31 +00:00
// Get the block object and call instance_delete() first
if ( ! $record = blocks_get_record ( $instance -> blockid )) {
2005-06-14 20:33:39 +00:00
return false ;
2005-06-13 03:32:31 +00:00
}
if ( ! $obj = block_instance ( $record -> name , $instance )) {
2005-06-14 20:33:39 +00:00
return false ;
2005-06-13 03:32:31 +00:00
}
// Return value ignored
$obj -> instance_delete ();
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
delete_records ( 'block_pinned' , 'id' , $instance -> id );
// And now, decrement the weight of all blocks after this one
execute_sql ( 'UPDATE ' . $CFG -> prefix . 'block_pinned SET weight = weight - 1 WHERE pagetype = \'' . $instance -> pagetype .
'\' AND position = \'' . $instance -> position .
'\' AND weight > ' . $instance -> weight , false );
} else {
// Now kill the db record;
delete_records ( 'block_instance' , 'id' , $instance -> id );
// And now, decrement the weight of all blocks after this one
execute_sql ( 'UPDATE ' . $CFG -> prefix . 'block_instance SET weight = weight - 1 WHERE pagetype = \'' . $instance -> pagetype .
'\' AND pageid = ' . $instance -> pageid . ' AND position = \'' . $instance -> position .
'\' AND weight > ' . $instance -> weight , false );
}
2005-06-14 20:33:39 +00:00
return true ;
2004-11-08 19:36:07 +00:00
}
2004-11-12 18:39:25 +00:00
// 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.
2005-03-02 05:56:24 +00:00
function blocks_have_content ( & $pageblocks , $position ) {
2005-08-16 00:25:39 +00:00
if ( empty ( $pageblocks ) || ! is_array ( $pageblocks ) || ! array_key_exists ( $position , $pageblocks )) {
return false ;
}
2006-05-17 04:39:43 +00:00
// use a for() loop to get references to the array elements
// foreach() cannot fetch references in PHP v4.x
for ( $n = 0 ; $n < count ( $pageblocks [ $position ]); $n ++ ) {
$instance = & $pageblocks [ $position ][ $n ];
2005-03-02 19:22:26 +00:00
if ( ! $instance -> visible ) {
2005-01-18 06:03:26 +00:00
continue ;
}
2005-03-02 19:22:26 +00:00
if ( ! $record = blocks_get_record ( $instance -> blockid )) {
2005-01-18 06:03:26 +00:00
continue ;
}
2005-03-02 19:22:26 +00:00
if ( ! $obj = block_instance ( $record -> name , $instance )) {
2004-10-19 21:04:28 +00:00
continue ;
}
2005-03-02 19:22:26 +00:00
if ( ! $obj -> is_empty ()) {
2006-05-17 04:39:43 +00:00
// cache rec and obj
// for blocks_print_group()
2006-05-17 11:38:34 +00:00
$instance -> rec = $record ;
2006-05-17 04:39:43 +00:00
$instance -> obj = $obj ;
2005-03-02 19:22:26 +00:00
return true ;
2004-04-18 23:20:53 +00:00
}
}
2004-10-19 21:04:28 +00:00
2004-04-18 23:20:53 +00:00
return false ;
}
2004-11-12 18:39:25 +00:00
// This function prints one group of blocks in a page
// Parameters passed by reference for speed; they are not modified.
2005-03-02 05:47:39 +00:00
function blocks_print_group ( & $page , & $pageblocks , $position ) {
2006-08-24 03:20:37 +00:00
global $COURSE ;
2005-03-02 05:47:39 +00:00
if ( empty ( $pageblocks [ $position ])) {
2005-03-08 23:24:10 +00:00
$pageblocks [ $position ] = array ();
2005-03-12 15:56:19 +00:00
$maxweight = 0 ;
}
else {
$maxweight = max ( array_keys ( $pageblocks [ $position ]));
2004-10-19 21:04:28 +00:00
}
2005-08-23 18:16:06 +00:00
foreach ( $pageblocks [ $position ] as $instance ) {
2005-08-23 04:48:34 +00:00
if ( ! empty ( $instance -> pinned )) {
$maxweight -- ;
}
}
2004-04-18 23:20:53 +00:00
2004-11-08 19:36:07 +00:00
$isediting = $page -> user_is_editing ();
2004-04-18 23:20:53 +00:00
2005-03-02 05:47:39 +00:00
foreach ( $pageblocks [ $position ] as $instance ) {
2006-05-17 04:39:43 +00:00
// $instance may have ->rec and ->obj
// cached from when we walked $pageblocks
// in blocks_have_content()
if ( empty ( $instance -> rec )) {
$block = blocks_get_record ( $instance -> blockid );
} else {
$block = $instance -> rec ;
}
2006-04-24 15:01:35 +00:00
if ( empty ( $block )) {
// Block doesn't exist! We should delete this instance!
continue ;
}
2004-10-19 21:04:28 +00:00
if ( ! $block -> visible ) {
// Disabled by the admin
continue ;
}
2006-05-17 04:39:43 +00:00
if ( empty ( $instance -> obj )) {
if ( ! $obj = block_instance ( $block -> name , $instance )) {
// Invalid block
continue ;
}
} else {
$obj = $instance -> obj ;
2004-11-24 09:16:39 +00:00
}
2004-04-18 23:20:53 +00:00
2005-08-23 04:48:34 +00:00
$editalways = $page -> edit_always ();
2005-08-16 00:25:39 +00:00
if (( $isediting && empty ( $instance -> pinned )) || ! empty ( $editalways )) {
2004-10-19 21:04:28 +00:00
$options = 0 ;
2004-11-08 19:36:07 +00:00
// The block can be moved up if it's NOT the first one in its position. If it is, we look at the OR clause:
// the first block might still be able to move up if the page says so (i.e., it will change position)
$options |= BLOCK_MOVE_UP * ( $instance -> weight != 0 || ( $page -> blocks_move_position ( $instance , BLOCK_MOVE_UP ) != $instance -> position ));
// Same thing for downward movement
$options |= BLOCK_MOVE_DOWN * ( $instance -> weight != $maxweight || ( $page -> blocks_move_position ( $instance , BLOCK_MOVE_DOWN ) != $instance -> position ));
// For left and right movements, it's up to the page to tell us whether they are allowed
$options |= BLOCK_MOVE_RIGHT * ( $page -> blocks_move_position ( $instance , BLOCK_MOVE_RIGHT ) != $instance -> position );
$options |= BLOCK_MOVE_LEFT * ( $page -> blocks_move_position ( $instance , BLOCK_MOVE_LEFT ) != $instance -> position );
// Finally, the block can be configured if the block class either allows multiple instances, or if it specifically
// allows instance configuration (multiple instances override that one). It doesn't have anything to do with what the
// administrator has allowed for this block in the site admin options.
$options |= BLOCK_CONFIGURE * ( $obj -> instance_allow_multiple () || $obj -> instance_allow_config () );
2005-01-25 02:57:30 +00:00
$obj -> _add_edit_controls ( $options );
2004-10-19 21:04:28 +00:00
}
2004-04-18 23:20:53 +00:00
2006-08-24 03:20:37 +00:00
if ( ! $instance -> visible && empty ( $COURSE -> javascriptportal )) {
if ( $isediting ) {
2005-01-25 02:57:30 +00:00
$obj -> _print_shadow ();
2004-04-18 23:20:53 +00:00
}
2006-08-24 03:20:37 +00:00
} else {
2006-08-28 02:06:04 +00:00
global $COURSE ;
if ( ! empty ( $COURSE -> javascriptportal ))
$COURSE -> javascriptportal -> currentblocksection = $position ;
2005-01-25 02:57:30 +00:00
$obj -> _print_block ();
2006-08-28 02:06:04 +00:00
2004-10-19 21:04:28 +00:00
}
2004-04-18 23:20:53 +00:00
}
2005-03-02 05:47:39 +00:00
2006-08-24 03:20:37 +00:00
if ( $page -> blocks_default_position () == $position && $page -> user_is_editing ()) {
2005-03-02 05:47:39 +00:00
blocks_print_adminblock ( $page , $pageblocks );
}
2004-04-18 23:20:53 +00:00
}
2004-11-12 18:39:25 +00:00
// 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 ) {
2004-04-18 23:20:53 +00:00
$width = 0 ;
2004-10-19 21:04:28 +00:00
if ( empty ( $instances ) || ! is_array ( $instances )) {
2004-04-18 23:20:53 +00:00
return 0 ;
}
2005-04-30 03:18:02 +00:00
$blocks = blocks_get_record ();
2004-10-19 21:04:28 +00:00
foreach ( $instances as $instance ) {
if ( ! $instance -> visible ) {
2004-08-12 07:17:46 +00:00
continue ;
2004-08-12 07:09:18 +00:00
}
2005-04-30 03:18:02 +00:00
2006-04-24 15:01:35 +00:00
if ( ! array_key_exists ( $instance -> blockid , $blocks )) {
// Block doesn't exist! We should delete this instance!
continue ;
}
2005-04-30 03:18:02 +00:00
if ( ! $blocks [ $instance -> blockid ] -> visible ) {
2005-04-30 03:14:42 +00:00
continue ;
}
2005-04-30 03:18:02 +00:00
$pref = block_method_result ( $blocks [ $instance -> blockid ] -> name , 'preferred_width' );
2004-10-19 21:04:28 +00:00
if ( $pref === NULL ) {
continue ;
}
if ( $pref > $width ) {
$width = $pref ;
2004-04-18 23:20:53 +00:00
}
}
return $width ;
}
2004-10-19 21:04:28 +00:00
function blocks_get_record ( $blockid = NULL , $invalidate = false ) {
static $cache = NULL ;
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
if ( $invalidate || empty ( $cache )) {
2005-02-16 21:39:35 +00:00
$cache = get_records ( 'block' );
2004-10-19 21:04:28 +00:00
}
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
if ( $blockid === NULL ) {
return $cache ;
}
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
return ( isset ( $cache [ $blockid ]) ? $cache [ $blockid ] : false );
}
function blocks_find_block ( $blockid , $blocksarray ) {
2005-08-16 00:25:39 +00:00
if ( empty ( $blocksarray )) {
return false ;
}
2004-10-19 21:04:28 +00:00
foreach ( $blocksarray as $blockgroup ) {
2005-08-16 00:25:39 +00:00
if ( empty ( $blockgroup )) {
continue ;
}
2004-10-19 21:04:28 +00:00
foreach ( $blockgroup as $instance ) {
if ( $instance -> blockid == $blockid ) {
return $instance ;
}
}
}
return false ;
}
function blocks_find_instance ( $instanceid , $blocksarray ) {
foreach ( $blocksarray as $subarray ) {
foreach ( $subarray as $instance ) {
if ( $instance -> id == $instanceid ) {
return $instance ;
}
}
}
return false ;
}
2005-03-02 05:15:39 +00:00
// Simple entry point for anyone that wants to use blocks
2005-08-23 04:03:56 +00:00
function blocks_setup ( & $PAGE , $pinned = BLOCKS_PINNED_FALSE ) {
switch ( $pinned ) {
case BLOCKS_PINNED_TRUE :
$pageblocks = blocks_get_pinned ( $PAGE );
break ;
case BLOCKS_PINNED_BOTH :
$pageblocks = blocks_get_by_page_pinned ( $PAGE );
break ;
case BLOCKS_PINNED_FALSE :
default :
$pageblocks = blocks_get_by_page ( $PAGE );
break ;
}
blocks_execute_url_action ( $PAGE , $pageblocks ,( $pinned == BLOCKS_PINNED_TRUE ));
2005-03-02 05:15:39 +00:00
return $pageblocks ;
}
2005-08-16 00:25:39 +00:00
function blocks_execute_action ( $page , & $pageblocks , $blockaction , $instanceorid , $pinned = false ) {
2004-10-19 21:04:28 +00:00
global $CFG ;
2004-10-25 03:20:02 +00:00
if ( is_int ( $instanceorid )) {
2004-10-19 21:04:28 +00:00
$blockid = $instanceorid ;
2004-10-25 03:20:02 +00:00
} else if ( is_object ( $instanceorid )) {
2004-10-19 21:04:28 +00:00
$instance = $instanceorid ;
}
2004-04-18 23:20:53 +00:00
switch ( $blockaction ) {
2004-10-19 21:04:28 +00:00
case 'config' :
2004-11-08 19:36:07 +00:00
global $USER ;
2004-10-19 21:04:28 +00:00
$block = blocks_get_record ( $instance -> blockid );
2005-02-18 17:05:49 +00:00
// Hacky hacky tricky stuff to get the original human readable block title,
// even if the block has configured its title to be something else.
// Create the object WITHOUT instance data.
$blockobject = block_instance ( $block -> name );
2004-10-19 21:04:28 +00:00
if ( $blockobject === false ) {
2005-12-17 04:37:55 +00:00
break ;
}
// First of all check to see if the block wants to be edited
if ( ! $blockobject -> user_can_edit ()) {
break ;
2004-10-19 21:04:28 +00:00
}
2005-12-17 04:37:55 +00:00
2005-02-18 17:05:49 +00:00
// Now get the title and AFTER that load up the instance
$blocktitle = $blockobject -> get_title ();
$blockobject -> _load_instance ( $instance );
2004-10-19 21:04:28 +00:00
optional_param ( 'submitted' , 0 , PARAM_INT );
2004-10-24 15:51:25 +00:00
// Define the data we're going to silently include in the instance config form here,
2004-10-19 21:04:28 +00:00
// so we can strip them from the submitted data BEFORE serializing it.
$hiddendata = array (
'sesskey' => $USER -> sesskey ,
'instanceid' => $instance -> id ,
'blockaction' => 'config'
);
2004-11-08 19:36:07 +00:00
// To this data, add anything the page itself needs to display
$hiddendata = array_merge ( $hiddendata , $page -> url_get_parameters ());
2004-10-19 21:04:28 +00:00
if ( $data = data_submitted ()) {
$remove = array_keys ( $hiddendata );
foreach ( $remove as $item ) {
unset ( $data -> $item );
2004-04-18 23:20:53 +00:00
}
2005-08-16 00:25:39 +00:00
if ( ! $blockobject -> instance_config_save ( $data , $pinned )) {
2004-10-19 21:04:28 +00:00
error ( 'Error saving block configuration' );
2004-04-18 23:20:53 +00:00
}
2004-10-19 21:04:28 +00:00
// And nothing more, continue with displaying the page
2004-04-18 23:20:53 +00:00
}
2004-10-19 21:04:28 +00:00
else {
2004-11-08 19:36:07 +00:00
// We need to show the config screen, so we highjack the display logic and then die
2005-02-18 17:05:49 +00:00
$strheading = get_string ( 'blockconfiga' , 'moodle' , $blocktitle );
2005-01-02 15:20:15 +00:00
$page -> print_header ( get_string ( 'pageheaderconfigablock' , 'moodle' ), array ( $strheading => '' ));
2005-09-09 16:52:47 +00:00
echo '<div class="block-config" id="' . $block -> name . '">' ; /// Make CSS easier
2005-01-02 15:20:15 +00:00
print_heading ( $strheading );
2004-11-08 19:36:07 +00:00
echo '<form method="post" action="' . $page -> url_get_path () . '">' ;
2004-10-19 21:04:28 +00:00
echo '<p>' ;
foreach ( $hiddendata as $name => $val ) {
2004-10-24 15:51:25 +00:00
echo '<input type="hidden" name="' . $name . '" value="' . $val . '" />' ;
2004-04-18 23:20:53 +00:00
}
2004-10-19 21:04:28 +00:00
echo '</p>' ;
$blockobject -> instance_config_print ();
echo '</form>' ;
2005-09-09 16:52:47 +00:00
echo '</div>' ;
2006-03-16 04:55:43 +00:00
$CFG -> pagepath = 'blocks/' . $block -> name ;
2004-10-19 21:04:28 +00:00
print_footer ();
2004-11-08 19:36:07 +00:00
die (); // Do not go on with the other page-related stuff
2004-04-18 23:20:53 +00:00
}
break ;
2004-10-19 21:04:28 +00:00
case 'toggle' :
if ( empty ( $instance )) {
error ( 'Invalid block instance for ' . $blockaction );
2004-04-18 23:20:53 +00:00
}
2004-10-19 21:04:28 +00:00
$instance -> visible = ( $instance -> visible ) ? 0 : 1 ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
update_record ( 'block_pinned' , $instance );
} else {
update_record ( 'block_instance' , $instance );
}
2004-10-19 21:04:28 +00:00
break ;
case 'delete' :
if ( empty ( $instance )) {
2004-10-25 03:20:02 +00:00
error ( 'Invalid block instance for ' . $blockaction );
2004-04-18 23:20:53 +00:00
}
2005-08-16 00:25:39 +00:00
blocks_delete_instance ( $instance , $pinned );
2004-04-18 23:20:53 +00:00
break ;
case 'moveup' :
2004-10-19 21:04:28 +00:00
if ( empty ( $instance )) {
2004-10-25 03:20:02 +00:00
error ( 'Invalid block instance for ' . $blockaction );
2004-10-19 21:04:28 +00:00
}
2004-11-08 19:36:07 +00:00
if ( $instance -> weight == 0 ) {
// The block is the first one, so a move "up" probably means it changes position
// Where is the instance going to be moved?
$newpos = $page -> blocks_move_position ( $instance , BLOCK_MOVE_UP );
2004-11-12 18:47:39 +00:00
$newweight = ( empty ( $pageblocks [ $newpos ]) ? 0 : max ( array_keys ( $pageblocks [ $newpos ])) + 1 );
2004-11-08 19:36:07 +00:00
2005-08-16 00:25:39 +00:00
blocks_execute_repositioning ( $instance , $newpos , $newweight , $pinned );
2004-10-29 16:56:59 +00:00
}
2004-11-08 19:36:07 +00:00
else {
// The block is just moving upwards in the same position.
// This configuration will make sure that even if somehow the weights
// become not continuous, block move operations will eventually bring
// the situation back to normal without printing any warnings.
if ( ! empty ( $pageblocks [ $instance -> position ][ $instance -> weight - 1 ])) {
$other = $pageblocks [ $instance -> position ][ $instance -> weight - 1 ];
}
if ( ! empty ( $other )) {
++ $other -> weight ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
update_record ( 'block_pinned' , $other );
} else {
update_record ( 'block_instance' , $other );
}
2004-11-08 19:36:07 +00:00
}
-- $instance -> weight ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
update_record ( 'block_pinned' , $instance );
} else {
update_record ( 'block_instance' , $instance );
}
2004-04-18 23:20:53 +00:00
}
break ;
case 'movedown' :
2004-10-19 21:04:28 +00:00
if ( empty ( $instance )) {
2004-10-25 03:20:02 +00:00
error ( 'Invalid block instance for ' . $blockaction );
2004-10-19 21:04:28 +00:00
}
2004-11-08 19:36:07 +00:00
if ( $instance -> weight == max ( array_keys ( $pageblocks [ $instance -> position ]))) {
// The block is the last one, so a move "down" probably means it changes position
// Where is the instance going to be moved?
$newpos = $page -> blocks_move_position ( $instance , BLOCK_MOVE_DOWN );
2004-11-12 18:47:39 +00:00
$newweight = ( empty ( $pageblocks [ $newpos ]) ? 0 : max ( array_keys ( $pageblocks [ $newpos ])) + 1 );
2004-11-08 19:36:07 +00:00
2005-08-16 00:25:39 +00:00
blocks_execute_repositioning ( $instance , $newpos , $newweight , $pinned );
2004-10-29 16:56:59 +00:00
}
2004-11-08 19:36:07 +00:00
else {
// The block is just moving downwards in the same position.
// This configuration will make sure that even if somehow the weights
// become not continuous, block move operations will eventually bring
// the situation back to normal without printing any warnings.
if ( ! empty ( $pageblocks [ $instance -> position ][ $instance -> weight + 1 ])) {
$other = $pageblocks [ $instance -> position ][ $instance -> weight + 1 ];
}
if ( ! empty ( $other )) {
-- $other -> weight ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
update_record ( 'block_pinned' , $other );
} else {
update_record ( 'block_instance' , $other );
}
2004-11-08 19:36:07 +00:00
}
++ $instance -> weight ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
update_record ( 'block_pinned' , $instance );
} else {
update_record ( 'block_instance' , $instance );
}
2004-04-18 23:20:53 +00:00
}
break ;
2004-10-19 21:04:28 +00:00
case 'moveleft' :
if ( empty ( $instance )) {
2004-10-25 03:20:02 +00:00
error ( 'Invalid block instance for ' . $blockaction );
2004-10-19 21:04:28 +00:00
}
2004-11-08 19:36:07 +00:00
// Where is the instance going to be moved?
$newpos = $page -> blocks_move_position ( $instance , BLOCK_MOVE_LEFT );
2004-11-12 18:47:39 +00:00
$newweight = ( empty ( $pageblocks [ $newpos ]) ? 0 : max ( array_keys ( $pageblocks [ $newpos ])) + 1 );
2004-11-08 19:36:07 +00:00
2005-08-16 00:25:39 +00:00
blocks_execute_repositioning ( $instance , $newpos , $newweight , $pinned );
2004-04-18 23:20:53 +00:00
break ;
2004-10-19 21:04:28 +00:00
case 'moveright' :
if ( empty ( $instance )) {
2004-10-25 03:20:02 +00:00
error ( 'Invalid block instance for ' . $blockaction );
2004-10-19 21:04:28 +00:00
}
2004-11-08 19:36:07 +00:00
// Where is the instance going to be moved?
$newpos = $page -> blocks_move_position ( $instance , BLOCK_MOVE_RIGHT );
2004-11-12 18:47:39 +00:00
$newweight = ( empty ( $pageblocks [ $newpos ]) ? 0 : max ( array_keys ( $pageblocks [ $newpos ])) + 1 );
2004-11-08 19:36:07 +00:00
2005-08-16 00:25:39 +00:00
blocks_execute_repositioning ( $instance , $newpos , $newweight , $pinned );
2004-10-19 21:04:28 +00:00
break ;
case 'add' :
// Add a new instance of this block, if allowed
$block = blocks_get_record ( $blockid );
2004-04-18 23:20:53 +00:00
2005-01-17 14:26:17 +00:00
if ( empty ( $block ) || ! $block -> visible ) {
// Only allow adding if the block exists and is enabled
2005-12-17 04:37:55 +00:00
break ;
2004-10-19 21:04:28 +00:00
}
2004-04-18 23:20:53 +00:00
2004-10-29 16:56:59 +00:00
if ( ! $block -> multiple && blocks_find_block ( $blockid , $pageblocks ) !== false ) {
// If no multiples are allowed and we already have one, return now
2005-12-17 04:37:55 +00:00
break ;
}
if ( ! block_method_result ( $block -> name , 'user_can_addto' , $page )) {
// If the block doesn't want to be added...
break ;
2004-10-29 16:56:59 +00:00
}
2004-11-08 19:36:07 +00:00
$newpos = $page -> blocks_default_position ();
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
$sql = 'SELECT 1, max(weight) + 1 AS nextfree FROM ' . $CFG -> prefix . 'block_pinned WHERE '
. ' pagetype = \'' . $page -> get_type () . '\' AND position = \'' . $newpos . '\'' ;
} else {
$sql = 'SELECT 1, max(weight) + 1 AS nextfree FROM ' . $CFG -> prefix . 'block_instance WHERE pageid = ' . $page -> get_id ()
. ' AND pagetype = \'' . $page -> get_type () . '\' AND position = \'' . $newpos . '\'' ;
}
$weight = get_record_sql ( $sql );
2004-10-19 21:04:28 +00:00
$newinstance = new stdClass ;
$newinstance -> blockid = $blockid ;
2005-08-16 00:25:39 +00:00
if ( empty ( $pinned )) {
$newinstance -> pageid = $page -> get_id ();
}
2004-11-08 19:36:07 +00:00
$newinstance -> pagetype = $page -> get_type ();
$newinstance -> position = $newpos ;
2005-02-23 18:51:00 +00:00
$newinstance -> weight = empty ( $weight -> nextfree ) ? 0 : $weight -> nextfree ;
2004-10-19 21:04:28 +00:00
$newinstance -> visible = 1 ;
$newinstance -> configdata = '' ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
$newinstance -> id = insert_record ( 'block_pinned' , $newinstance );
} else {
$newinstance -> id = insert_record ( 'block_instance' , $newinstance );
}
2005-06-13 03:32:31 +00:00
// If the new instance was created, allow it to do additional setup
if ( $newinstance && ( $obj = block_instance ( $block -> name , $newinstance ))) {
// Return value ignored
$obj -> instance_create ();
}
2004-10-19 21:04:28 +00:00
break ;
}
2004-11-08 19:36:07 +00:00
// In order to prevent accidental duplicate actions, redirect to a page with a clean url
redirect ( $page -> url_get_full ());
}
2005-02-01 06:24:28 +00:00
// You can use this to get the blocks to respond to URL actions without much hassle
2005-08-16 00:25:39 +00:00
function blocks_execute_url_action ( & $PAGE , & $pageblocks , $pinned = false ) {
2005-02-01 06:24:28 +00:00
$blockaction = optional_param ( 'blockaction' );
2005-02-01 06:55:02 +00:00
if ( empty ( $blockaction ) || ! $PAGE -> user_allowed_editing () || ! confirm_sesskey ()) {
2005-02-01 06:24:28 +00:00
return ;
}
$instanceid = optional_param ( 'instanceid' , 0 , PARAM_INT );
$blockid = optional_param ( 'blockid' , 0 , PARAM_INT );
if ( ! empty ( $blockid )) {
2005-08-16 00:25:39 +00:00
blocks_execute_action ( $PAGE , $pageblocks , strtolower ( $blockaction ), $blockid , $pinned );
2005-02-01 06:24:28 +00:00
}
else if ( ! empty ( $instanceid )) {
$instance = blocks_find_instance ( $instanceid , $pageblocks );
2005-08-16 00:25:39 +00:00
blocks_execute_action ( $PAGE , $pageblocks , strtolower ( $blockaction ), $instance , $pinned );
2005-02-01 06:24:28 +00:00
}
}
2004-11-08 19:36:07 +00:00
// This shouldn't be used externally at all, it's here for use by blocks_execute_action()
// in order to reduce code repetition.
2005-08-16 00:25:39 +00:00
function blocks_execute_repositioning ( & $instance , $newpos , $newweight , $pinned = false ) {
2004-11-08 19:36:07 +00:00
global $CFG ;
// If it's staying where it is, don't do anything
if ( $newpos == $instance -> position ) {
return ;
}
// Close the weight gap we 'll leave behind
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
$sql = 'UPDATE ' . $CFG -> prefix . 'block_instance SET weight = weight - 1 WHERE pagetype = \'' . $instance -> pagetype .
'\' AND position = \'' . $instance -> position .
'\' AND weight > ' . $instance -> weight ;
} else {
$sql = 'UPDATE ' . $CFG -> prefix . 'block_instance SET weight = weight - 1 WHERE pagetype = \'' . $instance -> pagetype .
2004-11-08 19:36:07 +00:00
'\' AND pageid = ' . $instance -> pageid . ' AND position = \'' . $instance -> position .
2005-08-16 00:25:39 +00:00
'\' AND weight > ' . $instance -> weight ;
}
execute_sql ( $sql , false );
2004-11-08 19:36:07 +00:00
$instance -> position = $newpos ;
$instance -> weight = $newweight ;
2005-08-16 00:25:39 +00:00
if ( ! empty ( $pinned )) {
update_record ( 'block_pinned' , $instance );
} else {
update_record ( 'block_instance' , $instance );
}
}
function blocks_get_pinned ( $page ) {
$visible = true ;
if ( method_exists ( $page , 'edit_always' )) {
if ( $page -> edit_always ()) {
$visible = false ;
}
}
$blocks = get_records_select ( 'block_pinned' , 'pagetype = \'' . $page -> get_type () . '\'' . (( $visible ) ? 'AND visible = 1' : '' ), 'position, weight' );
$positions = $page -> blocks_get_positions ();
$arr = array ();
foreach ( $positions as $key => $position ) {
$arr [ $position ] = array ();
}
if ( empty ( $blocks )) {
return $arr ;
}
foreach ( $blocks as $block ) {
$block -> pinned = true ; // so we know we can't move it.
2005-12-20 20:55:37 +00:00
// make up an instanceid if we can..
$block -> pageid = $page -> get_id ();
2005-08-16 00:25:39 +00:00
$arr [ $block -> position ][ $block -> weight ] = $block ;
}
return $arr ;
}
function blocks_get_by_page_pinned ( $page ) {
$pinned = blocks_get_pinned ( $page );
$user = blocks_get_by_page ( $page );
$weights = array ();
foreach ( $pinned as $pos => $arr ) {
$weights [ $pos ] = count ( $arr );
}
foreach ( $user as $pos => $blocks ) {
if ( ! array_key_exists ( $pos , $pinned )) {
$pinned [ $pos ] = array ();
}
if ( ! array_key_exists ( $pos , $weights )) {
$weights [ $pos ] = 0 ;
}
foreach ( $blocks as $block ) {
$pinned [ $pos ][ $weights [ $pos ]] = $block ;
$weights [ $pos ] ++ ;
}
}
return $pinned ;
2004-04-18 23:20:53 +00:00
}
2004-10-19 21:04:28 +00:00
function blocks_get_by_page ( $page ) {
2005-09-07 22:00:55 +00:00
$blocks = get_records_select ( 'block_instance' , " pageid = ' " . $page -> get_id () . " ' AND pagetype = ' " . $page -> get_type () . " ' " , 'position, weight' );
2004-11-08 19:36:07 +00:00
$positions = $page -> blocks_get_positions ();
$arr = array ();
foreach ( $positions as $key => $position ) {
$arr [ $position ] = array ();
}
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
if ( empty ( $blocks )) {
return $arr ;
}
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
foreach ( $blocks as $block ) {
$arr [ $block -> position ][ $block -> weight ] = $block ;
2004-04-18 23:20:53 +00:00
}
2004-10-19 21:04:28 +00:00
return $arr ;
}
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
//This function prints the block to admin blocks as necessary
2005-02-02 02:41:56 +00:00
function blocks_print_adminblock ( & $page , & $pageblocks ) {
2004-10-19 21:04:28 +00:00
global $USER ;
2004-04-18 23:20:53 +00:00
2005-02-02 02:41:56 +00:00
$missingblocks = blocks_get_missing ( $page , $pageblocks );
2004-10-19 21:04:28 +00:00
if ( ! empty ( $missingblocks )) {
2005-02-02 02:41:56 +00:00
$strblocks = get_string ( 'blocks' );
$stradd = get_string ( 'add' );
2004-10-19 21:04:28 +00:00
foreach ( $missingblocks as $blockid ) {
$block = blocks_get_record ( $blockid );
$blockobject = block_instance ( $block -> name );
if ( $blockobject === false ) {
continue ;
}
2005-12-17 04:37:55 +00:00
if ( ! $blockobject -> user_can_addto ( $page )) {
continue ;
}
2004-10-19 21:04:28 +00:00
$menu [ $block -> id ] = $blockobject -> get_title ();
}
2005-02-17 02:19:55 +00:00
asort ( $menu );
2004-04-18 23:20:53 +00:00
2004-11-08 19:36:07 +00:00
$target = $page -> url_get_full ( array ( 'sesskey' => $USER -> sesskey , 'blockaction' => 'add' ));
$content = popup_form ( $target . '&blockid=' , $menu , 'add_block' , '' , $stradd . '...' , '' , '' , true );
2005-02-18 03:37:07 +00:00
print_side_block ( $strblocks , $content , NULL , NULL , NULL , array ( 'class' => 'block_adminblock' ));
2004-04-18 23:20:53 +00:00
}
}
2004-10-19 21:04:28 +00:00
function blocks_repopulate_page ( $page ) {
global $CFG ;
2004-10-09 20:16:05 +00:00
2004-10-19 21:04:28 +00:00
$allblocks = blocks_get_record ();
if ( empty ( $allblocks )) {
error ( 'Could not retrieve blocks from the database' );
}
2004-11-08 19:36:07 +00:00
// Assemble the information to correlate block names to ids
2004-10-19 21:04:28 +00:00
$idforname = array ();
foreach ( $allblocks as $block ) {
$idforname [ $block -> name ] = $block -> id ;
}
2004-11-08 19:36:07 +00:00
/// If the site override has been defined, it is the only valid one.
if ( ! empty ( $CFG -> defaultblocks_override )) {
$blocknames = $CFG -> defaultblocks_override ;
}
else {
$blocknames = $page -> blocks_get_default ();
}
$positions = $page -> blocks_get_positions ();
$posblocks = explode ( ':' , $blocknames );
// Now one array holds the names of the positions, and the other one holds the blocks
// that are going to go in each position. Luckily for us, both arrays are numerically
// indexed and the indexes match, so we can work straight away... but CAREFULLY!
2004-10-19 21:04:28 +00:00
2004-11-08 19:36:07 +00:00
// Ready to start creating block instances, but first drop any existing ones
delete_records ( 'block_instance' , 'pageid' , $page -> get_id (), 'pagetype' , $page -> get_type ());
// Here we slyly count $posblocks and NOT $positions. This can actually make a difference
// if the textual representation has undefined slots in the end. So we only work with as many
// positions were retrieved, not with all the page says it has available.
$numpositions = count ( $posblocks );
for ( $i = 0 ; $i < $numpositions ; ++ $i ) {
$position = $positions [ $i ];
$blocknames = explode ( ',' , $posblocks [ $i ]);
2004-10-19 21:04:28 +00:00
$weight = 0 ;
foreach ( $blocknames as $blockname ) {
$newinstance = new stdClass ;
$newinstance -> blockid = $idforname [ $blockname ];
2004-11-08 19:36:07 +00:00
$newinstance -> pageid = $page -> get_id ();
$newinstance -> pagetype = $page -> get_type ();
2004-10-19 21:04:28 +00:00
$newinstance -> position = $position ;
$newinstance -> weight = $weight ;
$newinstance -> visible = 1 ;
$newinstance -> configdata = '' ;
2005-01-17 14:26:17 +00:00
if ( ! empty ( $newinstance -> blockid )) {
// Only add block if it was recognized
insert_record ( 'block_instance' , $newinstance );
++ $weight ;
}
2004-04-18 23:20:53 +00:00
}
}
2004-10-19 21:04:28 +00:00
return true ;
2004-04-18 23:20:53 +00:00
}
function upgrade_blocks_db ( $continueto ) {
/// This function upgrades the blocks tables, if necessary
/// It's called from admin/index.php
global $CFG , $db ;
2004-10-25 03:20:02 +00:00
require_once ( $CFG -> dirroot . '/blocks/version.php' ); // Get code versions
2004-04-18 23:20:53 +00:00
if ( empty ( $CFG -> blocks_version )) { // Blocks have never been installed.
2004-10-25 03:20:02 +00:00
$strdatabaseupgrades = get_string ( 'databaseupgrades' );
2006-07-13 09:48:56 +00:00
print_header ( $strdatabaseupgrades , $strdatabaseupgrades , $strdatabaseupgrades , '' ,
'<script type="text/javascript" src="' . $CFG -> wwwroot . '/lib/scroll_to_errors.js"></script>' ,
false , ' ' , ' ' );
2004-04-18 23:20:53 +00:00
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2006-08-30 23:18:29 +00:00
print_heading ( 'blocks' );
2004-04-18 23:20:53 +00:00
$db -> debug = true ;
2006-08-30 23:18:29 +00:00
/// Both old .sql files and new install.xml are supported
/// but we priorize install.xml (XMLDB) if present
$status = false ;
if ( file_exists ( $CFG -> dirroot . '/blocks/db/install.xml' ) && $CFG -> xmldb_enabled ) {
$status = install_from_xmldb_file ( $CFG -> dirroot . '/blocks/db/install.xml' ); //New method
} else if ( file_exists ( $CFG -> dirroot . '/blocks/db/' . $CFG -> dbtype . '.sql' )) {
$status = modify_database ( $CFG -> dirroot . '/blocks/db/' . $CFG -> dbtype . '.sql' ); //Old method
}
$db -> debug = false ;
if ( $status ) {
2004-10-25 03:20:02 +00:00
if ( set_config ( 'blocks_version' , $blocks_version )) {
2005-02-08 17:07:31 +00:00
notify ( get_string ( 'databasesuccess' ), 'notifysuccess' );
2006-08-14 08:37:19 +00:00
notify ( get_string ( 'databaseupgradeblocks' , '' , $blocks_version ), 'notifysuccess' );
2004-04-18 23:20:53 +00:00
print_continue ( $continueto );
exit ;
} else {
2004-10-25 03:20:02 +00:00
error ( 'Upgrade of blocks system failed! (Could not update version in config table)' );
2004-04-18 23:20:53 +00:00
}
} else {
2004-10-25 03:20:02 +00:00
error ( 'Blocks tables could NOT be set up successfully!' );
2004-04-18 23:20:53 +00:00
}
}
2006-08-30 23:18:29 +00:00
/// Upgrading code starts here
$oldupgrade = false ;
$newupgrade = false ;
if ( is_readable ( $CFG -> dirroot . '/blocks/db/' . $CFG -> dbtype . '.php' )) {
include_once ( $CFG -> dirroot . '/blocks/db/' . $CFG -> dbtype . '.php' ); // defines old upgrading function
$oldupgrade = true ;
}
if ( is_readable ( $CFG -> dirroot . '/blocks/db/upgrade.php' ) && $CFG -> xmldb_enabled ) {
include_once ( $CFG -> dirroot . '/blocks/db/upgrade.php' ); // defines new upgrading function
$newupgrade = true ;
}
2004-04-18 23:20:53 +00:00
if ( $blocks_version > $CFG -> blocks_version ) { // Upgrade tables
2004-10-25 03:20:02 +00:00
$strdatabaseupgrades = get_string ( 'databaseupgrades' );
2006-07-13 09:48:56 +00:00
print_header ( $strdatabaseupgrades , $strdatabaseupgrades , $strdatabaseupgrades , '' ,
'<script type="text/javascript" src="' . $CFG -> wwwroot . '/lib/scroll_to_errors.js"></script>' );
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2006-08-30 23:18:29 +00:00
print_heading ( 'blocks' );
/// Run de old and new upgrade functions for the module
$oldupgrade_function = 'blocks_upgrade' ;
$newupgrade_function = 'xmldb_blocks_upgrade' ;
/// First, the old function if exists
$oldupgrade_status = true ;
if ( $oldupgrade && function_exists ( $oldupgrade_function )) {
$db -> debug = true ;
$oldupgrade_status = $oldupgrade_function ( $CFG -> blocks_version );
} else if ( $oldupgrade ) {
notify ( 'Upgrade function ' . $oldupgrade_function . ' was not available in ' .
'/blocks/db/' . $CFG -> dbtype . '.php' );
}
2004-04-18 23:20:53 +00:00
2006-08-30 23:18:29 +00:00
/// Then, the new function if exists and the old one was ok
$newupgrade_status = true ;
if ( $newupgrade && function_exists ( $newupgrade_function ) && $oldupgrade_status ) {
$db -> debug = true ;
$newupgrade_status = $newupgrade_function ( $CFG -> blocks_version );
} else if ( $newupgrade ) {
notify ( 'Upgrade function ' . $newupgrade_function . ' was not available in ' .
'/blocks/db/upgrade.php' );
}
$db -> debug = false ;
/// Now analyze upgrade results
if ( $oldupgrade_status && $newupgrade_status ) { // No upgrading failed
2004-10-25 03:20:02 +00:00
if ( set_config ( 'blocks_version' , $blocks_version )) {
2005-02-08 17:07:31 +00:00
notify ( get_string ( 'databasesuccess' ), 'notifysuccess' );
2006-08-14 08:37:19 +00:00
notify ( get_string ( 'databaseupgradeblocks' , '' , $blocks_version ), 'notifysuccess' );
2004-04-18 23:20:53 +00:00
print_continue ( $continueto );
exit ;
} else {
2004-10-25 03:20:02 +00:00
error ( 'Upgrade of blocks system failed! (Could not update version in config table)' );
2004-04-18 23:20:53 +00:00
}
} else {
2004-10-25 03:20:02 +00:00
error ( 'Upgrade failed! See blocks/version.php' );
2004-04-18 23:20:53 +00:00
}
} else if ( $blocks_version < $CFG -> blocks_version ) {
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2005-05-17 15:28:06 +00:00
notify ( 'WARNING!!! The Blocks version you are using is OLDER than the version that made these databases!' );
2004-04-18 23:20:53 +00:00
}
2006-08-30 23:18:29 +00:00
upgrade_log_finish ();
2004-04-18 23:20:53 +00:00
}
//This function finds all available blocks and install them
//into blocks table or do all the upgrade process if newer
function upgrade_blocks_plugins ( $continueto ) {
global $CFG ;
$blocktitles = array ();
$invalidblocks = array ();
$validblocks = array ();
$notices = array ();
//Count the number of blocks in db
2004-10-19 21:04:28 +00:00
$blockcount = count_records ( 'block' );
2004-04-18 23:20:53 +00:00
//If there isn't records. This is the first install, so I remember it
if ( $blockcount == 0 ) {
$first_install = true ;
} else {
$first_install = false ;
}
$site = get_site ();
2004-10-19 21:04:28 +00:00
if ( ! $blocks = get_list_of_plugins ( 'blocks' , 'db' ) ) {
2004-10-25 03:20:02 +00:00
error ( 'No blocks installed!' );
2004-04-18 23:20:53 +00:00
}
2004-10-25 03:20:02 +00:00
include_once ( $CFG -> dirroot . '/blocks/moodleblock.class.php' );
2004-11-23 18:53:34 +00:00
if ( ! class_exists ( 'block_base' )) {
error ( 'Class block_base is not defined or file not found for /blocks/moodleblock.class.php' );
2004-04-18 23:20:53 +00:00
}
foreach ( $blocks as $blockname ) {
2004-10-25 03:20:02 +00:00
if ( $blockname == 'NEWBLOCK' ) { // Someone has unzipped the template, ignore it
2004-04-18 23:20:53 +00:00
continue ;
}
2005-04-30 03:08:04 +00:00
if ( ! block_is_compatible ( $blockname )) {
// This is an old-style block
//$notices[] = 'Block '. $blockname .' is not compatible with the current version of Mooodle and needs to be updated by a programmer.';
$invalidblocks [] = $blockname ;
continue ;
}
2006-08-09 14:00:51 +00:00
2004-10-25 03:20:02 +00:00
$fullblock = $CFG -> dirroot . '/blocks/' . $blockname ;
2004-04-18 23:20:53 +00:00
2004-10-19 21:04:28 +00:00
if ( is_readable ( $fullblock . '/block_' . $blockname . '.php' )) {
include_once ( $fullblock . '/block_' . $blockname . '.php' );
2004-04-18 23:20:53 +00:00
} else {
2004-10-25 03:20:02 +00:00
$notices [] = 'Block ' . $blockname . ': ' . $fullblock . '/block_' . $blockname . '.php was not readable' ;
2004-04-18 23:20:53 +00:00
continue ;
}
2004-10-25 03:20:02 +00:00
if ( @ is_dir ( $fullblock . '/db/' )) {
if ( @ is_readable ( $fullblock . '/db/' . $CFG -> dbtype . '.php' )) {
2004-10-29 16:56:59 +00:00
include_once ( $fullblock . '/db/' . $CFG -> dbtype . '.php' ); // defines upgrading function
2004-05-11 16:08:03 +00:00
} else {
2005-04-10 13:51:19 +00:00
//$notices[] ='Block '. $blockname .': '. $fullblock .'/db/'. $CFG->dbtype .'.php was not readable';
2004-05-11 16:08:03 +00:00
continue ;
}
2004-04-18 23:20:53 +00:00
}
2004-11-23 18:53:34 +00:00
$classname = 'block_' . $blockname ;
2004-04-18 23:20:53 +00:00
if ( ! class_exists ( $classname )) {
2004-10-25 03:20:02 +00:00
$notices [] = 'Block ' . $blockname . ': ' . $classname . ' not implemented' ;
2004-04-18 23:20:53 +00:00
continue ;
}
2004-10-19 21:04:28 +00:00
// Here is the place to see if the block implements a constructor (old style),
// an init() function (new style) or nothing at all (error time).
2004-06-18 12:25:27 +00:00
$constructor = get_class_constructor ( $classname );
if ( empty ( $constructor )) {
2004-04-18 23:20:53 +00:00
// No constructor
2004-10-25 03:20:02 +00:00
$notices [] = 'Block ' . $blockname . ': class does not have a constructor' ;
2004-04-18 23:20:53 +00:00
$invalidblocks [] = $blockname ;
continue ;
}
2004-10-19 21:04:28 +00:00
$block = new stdClass ; // This may be used to update the db below
$blockobj = new $classname ; // This is what we 'll be testing
2004-04-18 23:20:53 +00:00
2004-11-23 18:53:34 +00:00
// Inherits from block_base?
if ( ! is_subclass_of ( $blockobj , 'block_base' )) {
$notices [] = 'Block ' . $blockname . ': class does not inherit from block_base' ;
2004-04-18 23:20:53 +00:00
continue ;
}
// OK, it's as we all hoped. For further tests, the object will do them itself.
if ( ! $blockobj -> _self_test ()) {
2004-10-25 03:20:02 +00:00
$notices [] = 'Block ' . $blockname . ': self test failed' ;
2004-04-18 23:20:53 +00:00
continue ;
}
$block -> version = $blockobj -> get_version ();
if ( ! isset ( $block -> version )) {
2004-10-25 03:20:02 +00:00
$notices [] = 'Block ' . $blockname . ': has no version support. It must be updated by a programmer.' ;
2004-04-18 23:20:53 +00:00
continue ;
}
$block -> name = $blockname ; // The name MUST match the directory
$blocktitle = $blockobj -> get_title ();
2004-10-19 21:04:28 +00:00
if ( $currblock = get_record ( 'block' , 'name' , $block -> name )) {
2004-04-18 23:20:53 +00:00
if ( $currblock -> version == $block -> version ) {
// do nothing
} else if ( $currblock -> version < $block -> version ) {
if ( empty ( $updated_blocks )) {
2004-10-25 03:20:02 +00:00
$strblocksetup = get_string ( 'blocksetup' );
2006-07-13 09:48:56 +00:00
print_header ( $strblocksetup , $strblocksetup , $strblocksetup , '' ,
'<script type="text/javascript" src="' . $CFG -> wwwroot . '/lib/scroll_to_errors.js"></script>' ,
false , ' ' , ' ' );
2004-04-18 23:20:53 +00:00
}
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2004-05-27 14:16:27 +00:00
print_heading ( 'New version of ' . $blocktitle . ' (' . $block -> name . ') exists' );
$upgrade_function = $block -> name . '_upgrade' ;
2004-04-18 23:20:53 +00:00
if ( function_exists ( $upgrade_function )) {
$db -> debug = true ;
if ( $upgrade_function ( $currblock -> version , $block )) {
2004-05-27 14:16:27 +00:00
$upgradesuccess = true ;
2004-04-18 23:20:53 +00:00
} else {
2004-05-27 14:16:27 +00:00
$upgradesuccess = false ;
}
$db -> debug = false ;
}
else {
$upgradesuccess = true ;
}
if ( ! $upgradesuccess ) {
2004-10-25 03:20:02 +00:00
notify ( 'Upgrading block ' . $block -> name . ' from ' . $currblock -> version . ' to ' . $block -> version . ' FAILED!' );
2004-05-27 14:16:27 +00:00
}
2006-08-08 05:13:06 +00:00
if ( ! update_capabilities ( 'block/' . $block -> name )) {
notify ( 'Could not update ' . $block -> name . ' capabilities!' );
}
2004-05-27 14:16:27 +00:00
else {
2004-10-19 21:04:28 +00:00
// OK so far, now update the block record
2004-05-27 14:16:27 +00:00
$block -> id = $currblock -> id ;
2004-10-19 21:04:28 +00:00
if ( ! update_record ( 'block' , $block )) {
2004-10-25 03:20:02 +00:00
error ( 'Could not update block ' . $block -> name . ' record in block table!' );
2004-04-18 23:20:53 +00:00
}
2005-02-08 17:07:31 +00:00
notify ( get_string ( 'blocksuccess' , '' , $blocktitle ), 'notifysuccess' );
2004-05-27 14:16:27 +00:00
echo '<hr />' ;
2004-04-18 23:20:53 +00:00
}
$updated_blocks = true ;
} else {
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2004-10-25 03:20:02 +00:00
error ( 'Version mismatch: block ' . $block -> name . ' can\'t downgrade ' . $currblock -> version . ' -> ' . $block -> version . '!' );
2004-04-18 23:20:53 +00:00
}
} else { // block not installed yet, so install it
2004-10-19 21:04:28 +00:00
// If it allows multiples, start with it enabled
$block -> multiple = $blockobj -> instance_allow_multiple ();
2006-02-14 03:24:08 +00:00
if ( ! empty ( $blockobj -> cron )) {
$block -> cron = $blockobj -> cron ;
}
2004-10-19 21:04:28 +00:00
2004-04-18 23:20:53 +00:00
// [pj] Normally this would be inline in the if, but we need to
// check for NULL (necessary for 4.0.5 <= PHP < 4.2.0)
$conflictblock = array_search ( $blocktitle , $blocktitles );
if ( $conflictblock !== false && $conflictblock !== NULL ) {
// Duplicate block titles are not allowed, they confuse people
// AND PHP's associative arrays ;)
error ( '<strong>Naming conflict</strong>: block <strong>' . $block -> name . '</strong> has the same title with an existing block, <strong>' . $conflictblock . '</strong>!' );
}
if ( empty ( $updated_blocks )) {
2004-10-25 03:20:02 +00:00
$strblocksetup = get_string ( 'blocksetup' );
2006-07-13 09:48:56 +00:00
print_header ( $strblocksetup , $strblocksetup , $strblocksetup , '' ,
'<script type="text/javascript" src="' . $CFG -> wwwroot . '/lib/scroll_to_errors.js"></script>' ,
false , ' ' , ' ' );
2004-04-18 23:20:53 +00:00
}
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2004-04-18 23:20:53 +00:00
print_heading ( $block -> name );
$updated_blocks = true ;
$db -> debug = true ;
2004-05-18 14:12:21 +00:00
@ set_time_limit ( 0 ); // To allow slow databases to complete the long SQL
2004-10-25 03:20:02 +00:00
if ( ! is_dir ( $fullblock . '/db/' ) || modify_database ( $fullblock . '/db/' . $CFG -> dbtype . '.sql' )) {
2004-04-18 23:20:53 +00:00
$db -> debug = false ;
2004-10-19 21:04:28 +00:00
if ( $block -> id = insert_record ( 'block' , $block )) {
2006-07-14 11:17:46 +00:00
$blockobj -> after_install ();
2005-02-08 17:07:31 +00:00
notify ( get_string ( 'blocksuccess' , '' , $blocktitle ), 'notifysuccess' );
2004-10-25 03:20:02 +00:00
echo '<hr />' ;
2004-04-18 23:20:53 +00:00
} else {
2004-10-25 03:20:02 +00:00
error ( $block -> name . ' block could not be added to the block list!' );
2004-04-18 23:20:53 +00:00
}
2006-08-08 05:13:06 +00:00
if ( ! update_capabilities ( 'block' , $block -> name )) {
notify ( 'Could not set up ' . $block -> name . ' capabilities!' );
}
2004-04-18 23:20:53 +00:00
} else {
2004-10-25 03:20:02 +00:00
error ( 'Block ' . $block -> name . ' tables could NOT be set up successfully!' );
2004-04-18 23:20:53 +00:00
}
}
$blocktitles [ $block -> name ] = $blocktitle ;
}
if ( ! empty ( $notices )) {
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2004-04-18 23:20:53 +00:00
foreach ( $notices as $notice ) {
notify ( $notice );
}
}
2004-10-19 21:04:28 +00:00
// Finally, if we are in the first_install of BLOCKS (this means that we are
// upgrading from Moodle < 1.3), put blocks in all existing courses.
2004-04-18 23:20:53 +00:00
if ( $first_install ) {
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2004-04-18 23:20:53 +00:00
//Iterate over each course
2004-10-19 21:04:28 +00:00
if ( $courses = get_records ( 'course' )) {
2004-04-18 23:20:53 +00:00
foreach ( $courses as $course ) {
2005-01-31 02:18:15 +00:00
$page = page_create_object ( PAGE_COURSE_VIEW , $course -> id );
2004-10-19 21:04:28 +00:00
blocks_repopulate_page ( $page );
2004-04-18 23:20:53 +00:00
}
}
}
2004-08-30 16:26:00 +00:00
if ( ! empty ( $CFG -> siteblocksadded )) { /// This is a once-off hack to make a proper upgrade
2006-08-01 07:46:19 +00:00
upgrade_log_start ();
2005-01-31 02:18:15 +00:00
$page = page_create_object ( PAGE_COURSE_VIEW , SITEID );
2004-10-19 21:04:28 +00:00
blocks_repopulate_page ( $page );
2004-08-30 16:26:00 +00:00
delete_records ( 'config' , 'name' , 'siteblocksadded' );
}
2006-08-01 07:46:19 +00:00
upgrade_log_finish ();
2004-04-18 23:20:53 +00:00
if ( ! empty ( $updated_blocks )) {
print_continue ( $continueto );
die ;
}
}
2006-08-09 14:00:51 +00:00
?>