2009-05-22 02:18:49 +00:00
< ? php
2009-07-28 09:59:21 +00:00
// This file is part of Moodle - http://moodle.org/
//
2009-05-22 02:18:49 +00:00
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
2009-07-28 09:59:21 +00:00
//
2009-05-22 02:18:49 +00:00
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
2009-04-30 03:50:00 +00:00
/**
2009-05-22 02:18:49 +00:00
* Block Class and Functions
2009-04-30 03:50:00 +00:00
*
2009-07-28 09:59:21 +00:00
* This file defines the { @ link block_manager } class ,
2009-07-09 07:35:03 +00:00
*
2009-05-22 02:18:49 +00:00
* @ package moodlecore
* @ copyright 1999 onwards Martin Dougiamas http :// dougiamas . com
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
2009-04-30 03:50:00 +00:00
*/
2004-04-18 23:20:53 +00:00
2009-07-10 05:58:59 +00:00
/** #@+
* @ deprecated since Moodle 2.0 . No longer used .
2009-07-09 07:35:03 +00:00
*/
2004-04-18 23:20:53 +00:00
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 );
2009-07-10 05:58:59 +00:00
/**#@-*/
2004-04-18 23:20:53 +00:00
2009-07-10 05:58:59 +00:00
/** #@+
* Default names for the block regions in the standard theme .
*/
2009-05-06 09:15:05 +00:00
define ( 'BLOCK_POS_LEFT' , 'side-pre' );
define ( 'BLOCK_POS_RIGHT' , 'side-post' );
2009-07-10 05:58:59 +00:00
/**#@-*/
2004-08-22 16:48:28 +00:00
2009-07-10 05:58:59 +00:00
/** #@+
* @ deprecated since Moodle 2.0 . No longer used .
*/
2005-08-23 04:03:56 +00:00
define ( 'BLOCKS_PINNED_TRUE' , 0 );
define ( 'BLOCKS_PINNED_FALSE' , 1 );
define ( 'BLOCKS_PINNED_BOTH' , 2 );
2009-07-10 05:58:59 +00:00
/**#@-*/
2005-08-23 04:03:56 +00:00
2009-05-22 02:18:49 +00:00
/**
2009-07-09 07:35:03 +00:00
* Exception thrown when someone tried to do something with a block that does
* not exist on a page .
2009-05-22 02:18:49 +00:00
*
2009-07-09 07:35:03 +00:00
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
2009-05-22 02:18:49 +00:00
*/
2009-05-08 06:34:40 +00:00
class block_not_on_page_exception extends moodle_exception {
2009-05-22 02:18:49 +00:00
/**
* Contructor
2009-07-09 07:35:03 +00:00
* @ param int $instanceid the block instance id of the block that was looked for .
* @ param object $page the current page .
2009-05-22 02:18:49 +00:00
*/
2009-05-08 06:34:40 +00:00
public function __construct ( $instanceid , $page ) {
$a = new stdClass ;
$a -> instanceid = $instanceid ;
2009-07-14 09:28:10 +00:00
$a -> url = $page -> url -> out ();
parent :: __construct ( 'blockdoesnotexistonpage' , '' , $page -> url -> out (), $a );
2009-05-08 06:34:40 +00:00
}
}
2009-05-06 09:14:01 +00:00
/**
* This class keeps track of the block that should appear on a moodle_page .
2009-05-06 09:15:05 +00:00
*
2009-07-09 07:35:03 +00:00
* The page to work with as passed to the constructor .
2009-05-08 03:11:24 +00:00
*
2009-07-09 07:35:03 +00:00
* @ copyright 2009 Tim Hunt
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.0
2009-05-06 09:14:01 +00:00
*/
2009-07-09 07:35:03 +00:00
class block_manager {
2009-07-30 10:29:14 +00:00
/**
* The UI normally only shows block weights between - MAX_WEIGHT and MAX_WEIGHT ,
* although other weights are valid .
*/
const MAX_WEIGHT = 10 ;
2009-05-06 09:14:01 +00:00
/// Field declarations =========================================================
2009-07-09 07:35:03 +00:00
/** @var moodle_page the moodle_page we aremanaging blocks for. */
2009-05-06 09:14:01 +00:00
protected $page ;
2009-07-09 07:35:03 +00:00
/** @var array region name => 1.*/
2009-05-06 09:14:01 +00:00
protected $regions = array ();
2009-07-09 07:35:03 +00:00
/** @var string the region where new blocks are added.*/
protected $defaultregion = null ;
/** @var array will be $DB->get_records('blocks') */
protected $allblocks = null ;
/**
* @ var array blocks that this user can add to this page . Will be a subset
2009-07-14 08:37:28 +00:00
* of $allblocks , but with array keys block -> name . Access this via the
* { @ link get_addable_blocks ()} method to ensure it is lazy - loaded .
2009-07-09 07:35:03 +00:00
*/
protected $addableblocks = null ;
2009-05-06 09:14:42 +00:00
2009-05-06 09:15:05 +00:00
/**
* Will be an array region - name => array ( db rows loaded in load_blocks );
2009-05-22 02:18:49 +00:00
* @ var array
2009-05-06 09:15:05 +00:00
*/
protected $birecordsbyregion = null ;
/**
* array region - name => array ( block objects ); populated as necessary by
* the ensure_instances_exist method .
2009-05-22 02:18:49 +00:00
* @ var array
2009-05-06 09:15:05 +00:00
*/
protected $blockinstances = array ();
/**
2009-07-09 07:35:03 +00:00
* array region - name => array ( block_contents objects ) what acutally needs to
2009-05-06 09:15:05 +00:00
* be displayed in each region .
2009-05-22 02:18:49 +00:00
* @ var array
2009-05-06 09:15:05 +00:00
*/
protected $visibleblockcontent = array ();
2009-05-06 09:14:42 +00:00
2009-07-09 07:35:03 +00:00
/**
* array region - name => array ( block_contents objects ) extra block - like things
* to be displayed in each region , before the real blocks .
* @ var array
*/
protected $extracontent = array ();
2009-07-30 08:22:12 +00:00
/**
* Used by the block move id , to track whether a block is cuurently being moved .
*
* Whe you click on the move icon of a block , first the page needs to reload with
* extra UI for chooseing a new position for a particular block . In that situation
* this field holds the id of the block being moved .
*
* @ var integer | null
*/
protected $movingblock = null ;
2009-05-06 09:14:01 +00:00
/// Constructor ================================================================
/**
* Constructor .
* @ param object $page the moodle_page object object we are managing the blocks for ,
* or a reasonable faxilimily . ( See the comment at the top of this classe
2009-05-22 02:18:49 +00:00
* and { @ link http :// en . wikipedia . org / wiki / Duck_typing })
2009-05-06 09:14:01 +00:00
*/
public function __construct ( $page ) {
$this -> page = $page ;
}
/// Getter methods =============================================================
/**
2009-05-22 02:18:49 +00:00
* Get an array of all region names on this page where a block may appear
*
2009-05-06 09:14:01 +00:00
* @ return array the internal names of the regions on this page where block may appear .
*/
public function get_regions () {
2009-12-16 18:00:58 +00:00
if ( is_null ( $this -> defaultregion )) {
2009-09-30 16:24:05 +00:00
$this -> page -> initialise_theme_and_output ();
2009-12-16 18:00:58 +00:00
}
2009-05-06 09:14:01 +00:00
return array_keys ( $this -> regions );
}
/**
2009-05-22 02:18:49 +00:00
* Get the region name of the region blocks are added to by default
*
2009-05-06 09:14:01 +00:00
* @ return string the internal names of the region where new blocks are added
* by default , and where any blocks from an unrecognised region are shown .
* ( Imagine that blocks were added with one theme selected , then you switched
* to a theme with different block positions . )
*/
public function get_default_region () {
2009-07-09 07:35:03 +00:00
$this -> page -> initialise_theme_and_output ();
2009-05-06 09:14:01 +00:00
return $this -> defaultregion ;
}
2009-05-06 09:14:42 +00:00
/**
* The list of block types that may be added to this page .
2009-05-22 02:18:49 +00:00
*
2009-07-14 10:41:59 +00:00
* @ return array block name => record from block table .
2009-05-06 09:14:42 +00:00
*/
public function get_addable_blocks () {
$this -> check_is_loaded ();
if ( ! is_null ( $this -> addableblocks )) {
return $this -> addableblocks ;
}
// Lazy load.
$this -> addableblocks = array ();
$allblocks = blocks_get_record ();
if ( empty ( $allblocks )) {
return $this -> addableblocks ;
}
2009-05-06 09:15:05 +00:00
$pageformat = $this -> page -> pagetype ;
2009-05-06 09:14:42 +00:00
foreach ( $allblocks as $block ) {
if ( $block -> visible &&
2009-05-06 09:15:05 +00:00
( block_method_result ( $block -> name , 'instance_allow_multiple' ) || ! $this -> is_block_present ( $block -> id )) &&
2009-07-14 08:37:28 +00:00
blocks_name_allowed_in_format ( $block -> name , $pageformat ) &&
block_method_result ( $block -> name , 'user_can_addto' , $this -> page )) {
$this -> addableblocks [ $block -> name ] = $block ;
2009-05-06 09:14:42 +00:00
}
}
return $this -> addableblocks ;
}
2009-05-22 02:18:49 +00:00
/**
* Find out if a block is present ? just a guess
* @ todo Write this function and document
*/
2009-05-06 09:14:42 +00:00
public function is_block_present ( $blocktypeid ) {
// TODO
}
/**
2009-05-22 02:18:49 +00:00
* Find out if a block type is known by the system
*
2009-05-06 09:14:42 +00:00
* @ param string $blockname the name of ta type of block .
* @ param boolean $includeinvisible if false ( default ) only check 'visible' blocks , that is , blocks enabled by the admin .
* @ return boolean true if this block in installed .
*/
public function is_known_block_type ( $blockname , $includeinvisible = false ) {
$blocks = $this -> get_installed_blocks ();
foreach ( $blocks as $block ) {
if ( $block -> name == $blockname && ( $includeinvisible || $block -> visible )) {
return true ;
}
}
return false ;
}
/**
2009-05-22 02:18:49 +00:00
* Find out if a region exists on a page
*
2009-05-06 09:14:42 +00:00
* @ param string $region a region name
* @ return boolean true if this retion exists on this page .
*/
public function is_known_region ( $region ) {
return array_key_exists ( $region , $this -> regions );
}
/**
2009-05-22 02:18:49 +00:00
* Get an array of all blocks within a given region
*
* @ param string $region a block region that exists on this page .
2009-05-06 09:14:42 +00:00
* @ return array of block instances .
*/
public function get_blocks_for_region ( $region ) {
$this -> check_is_loaded ();
2009-05-06 09:15:05 +00:00
$this -> ensure_instances_exist ( $region );
return $this -> blockinstances [ $region ];
}
/**
2009-05-22 02:18:49 +00:00
* Returns an array of block content objects that exist in a region
*
2009-07-09 07:35:03 +00:00
* @ param string $region a block region that exists on this page .
* @ return array of block block_contents objects for all the blocks in a region .
2009-05-06 09:15:05 +00:00
*/
2009-07-09 07:35:03 +00:00
public function get_content_for_region ( $region , $output ) {
2009-05-06 09:15:05 +00:00
$this -> check_is_loaded ();
2009-07-09 07:35:03 +00:00
$this -> ensure_content_created ( $region , $output );
2009-05-06 09:15:05 +00:00
return $this -> visibleblockcontent [ $region ];
2009-05-06 09:14:42 +00:00
}
2009-07-30 08:22:12 +00:00
/**
* Helper method used by get_content_for_region .
* @ param string $region region name
* @ param float $weight weight . May be fractional , since you may want to move a block
* between ones with weight 2 and 3 , say ( $weight would be 2.5 ) .
* @ return string URL for moving block $this -> movingblock to this position .
*/
protected function get_move_target_url ( $region , $weight ) {
2010-02-17 18:36:26 +00:00
return new moodle_url ( $this -> page -> url , array ( 'bui_moveid' => $this -> movingblock ,
2010-01-17 09:50:55 +00:00
'bui_newregion' => $region , 'bui_newweight' => $weight , 'sesskey' => sesskey ()));
2009-07-30 08:22:12 +00:00
}
2009-07-09 07:35:03 +00:00
/**
* Determine whether a region contains anything . ( Either any real blocks , or
* the add new block UI . )
2009-07-22 05:38:28 +00:00
*
* ( You may wonder why the $output parameter is required . Unfortunately ,
* becuase of the way that blocks work , the only reliable way to find out
* if a block will be visible is to get the content for output , and to
* get the content , you need a renderer . Fortunately , this is not a
* performance problem , becuase we cache the output that is generated , and
* in almost every case where we call region_has_content , we are about to
* output the blocks anyway , so we are not doing wasted effort . )
*
2009-07-09 07:35:03 +00:00
* @ param string $region a block region that exists on this page .
2009-12-16 18:00:58 +00:00
* @ param object $output a core_renderer . normally the global $OUTPUT .
2009-07-09 07:35:03 +00:00
* @ return boolean Whether there is anything in this region .
*/
2009-07-22 05:38:28 +00:00
public function region_has_content ( $region , $output ) {
2010-03-31 07:41:31 +00:00
2009-07-09 07:35:03 +00:00
if ( ! $this -> is_known_region ( $region )) {
return false ;
}
$this -> check_is_loaded ();
2009-07-22 05:38:28 +00:00
$this -> ensure_content_created ( $region , $output );
2009-07-09 07:35:03 +00:00
if ( $this -> page -> user_is_editing () && $this -> page -> user_can_edit_blocks ()) {
// If editing is on, we need all the block regions visible, for the
// move blocks UI.
return true ;
}
2009-07-22 05:38:28 +00:00
return ! empty ( $this -> visibleblockcontent [ $region ]) || ! empty ( $this -> extracontent [ $region ]);
2009-07-09 07:35:03 +00:00
}
2009-05-06 09:14:42 +00:00
/**
2009-05-22 02:18:49 +00:00
* Get an array of all of the installed blocks .
*
2009-05-06 09:14:42 +00:00
* @ return array contents of the block table .
*/
public function get_installed_blocks () {
global $DB ;
if ( is_null ( $this -> allblocks )) {
$this -> allblocks = $DB -> get_records ( 'block' );
}
return $this -> allblocks ;
}
2009-05-06 09:14:01 +00:00
/// Setter methods =============================================================
/**
2009-05-22 02:18:49 +00:00
* Add a region to a page
*
2009-05-06 09:14:01 +00:00
* @ param string $region add a named region where blocks may appear on the
* current page . This is an internal name , like 'side-pre' , not a string to
* display in the UI .
*/
public function add_region ( $region ) {
$this -> check_not_yet_loaded ();
$this -> regions [ $region ] = 1 ;
}
/**
2009-05-22 02:18:49 +00:00
* Add an array of regions
* @ see add_region ()
*
2009-05-06 09:14:01 +00:00
* @ param array $regions this utility method calls add_region for each array element .
*/
public function add_regions ( $regions ) {
foreach ( $regions as $region ) {
$this -> add_region ( $region );
}
}
/**
2009-05-22 02:18:49 +00:00
* Set the default region for new blocks on the page
*
2009-05-06 09:14:01 +00:00
* @ param string $defaultregion the internal names of the region where new
* blocks should be added by default , and where any blocks from an
* unrecognised region are shown .
*/
public function set_default_region ( $defaultregion ) {
$this -> check_not_yet_loaded ();
2009-09-30 22:35:48 +00:00
if ( $defaultregion ) {
$this -> check_region_is_known ( $defaultregion );
}
2009-05-06 09:14:01 +00:00
$this -> defaultregion = $defaultregion ;
}
2009-07-09 07:35:03 +00:00
/**
* Add something that looks like a block , but which isn ' t an actual block_instance ,
* to this page .
*
* @ param block_contents $bc the content of the block like thing .
* @ param string $region a block region that exists on this page .
*/
public function add_pretend_block ( $bc , $region ) {
$this -> page -> initialise_theme_and_output ();
$this -> check_region_is_known ( $region );
if ( array_key_exists ( $region , $this -> visibleblockcontent )) {
throw new coding_exception ( 'block_manager has already prepared the blocks in region ' .
$region . 'for output. It is too late to add a pretend block.' );
}
$this -> extracontent [ $region ][] = $bc ;
}
2009-05-06 09:14:42 +00:00
/// Actions ====================================================================
/**
* This method actually loads the blocks for our page from the database .
2009-05-22 02:18:49 +00:00
*
2009-07-15 07:41:25 +00:00
* @ param boolean | null $includeinvisible
* null ( default ) - load hidden blocks if $this -> page -> user_is_editing ();
* true - load hidden blocks .
* false - don ' t load hidden blocks .
2009-05-06 09:14:42 +00:00
*/
2009-07-15 07:41:25 +00:00
public function load_blocks ( $includeinvisible = null ) {
2009-05-07 02:56:48 +00:00
global $DB , $CFG ;
2009-09-30 16:24:05 +00:00
2009-05-06 09:15:05 +00:00
if ( ! is_null ( $this -> birecordsbyregion )) {
// Already done.
return ;
}
2009-05-06 09:14:42 +00:00
2009-05-07 02:56:48 +00:00
if ( $CFG -> version < 2009050619 ) {
// Upgrade/install not complete. Don't try too show any blocks.
$this -> birecordsbyregion = array ();
return ;
}
2009-07-09 07:35:03 +00:00
// Ensure we have been initialised.
2009-09-30 16:24:05 +00:00
if ( is_null ( $this -> defaultregion )) {
2009-07-01 05:54:26 +00:00
$this -> page -> initialise_theme_and_output ();
2009-07-09 07:35:03 +00:00
// If there are still no block regions, then there are no blocks on this page.
if ( empty ( $this -> regions )) {
$this -> birecordsbyregion = array ();
return ;
}
2009-07-01 05:54:26 +00:00
}
2009-05-06 09:14:42 +00:00
if ( is_null ( $includeinvisible )) {
$includeinvisible = $this -> page -> user_is_editing ();
}
if ( $includeinvisible ) {
$visiblecheck = '' ;
2009-07-15 07:41:25 +00:00
} else {
$visiblecheck = 'AND (bp.visible = 1 OR bp.visible IS NULL)' ;
2009-05-06 09:14:42 +00:00
}
$context = $this -> page -> context ;
2009-07-10 05:58:59 +00:00
$contexttest = 'bi.parentcontextid = :contextid2' ;
2009-05-06 09:14:42 +00:00
$parentcontextparams = array ();
$parentcontextids = get_parent_contexts ( $context );
if ( $parentcontextids ) {
list ( $parentcontexttest , $parentcontextparams ) =
$DB -> get_in_or_equal ( $parentcontextids , SQL_PARAMS_NAMED , 'parentcontext0000' );
2009-07-10 05:58:59 +00:00
$contexttest = " ( $contexttest OR (bi.showinsubcontexts = 1 AND bi.parentcontextid $parentcontexttest )) " ;
2009-05-06 09:14:42 +00:00
}
2009-07-16 10:50:19 +00:00
$pagetypepatterns = matching_page_type_patterns ( $this -> page -> pagetype );
2009-05-06 09:14:42 +00:00
list ( $pagetypepatterntest , $pagetypepatternparams ) =
$DB -> get_in_or_equal ( $pagetypepatterns , SQL_PARAMS_NAMED , 'pagetypepatterntest0000' );
2010-03-31 07:41:31 +00:00
list ( $ccselect , $ccjoin ) = context_instance_preload_sql ( 'b.id' , CONTEXT_BLOCK , 'ctx' );
2009-05-06 09:14:42 +00:00
$params = array (
'subpage1' => $this -> page -> subpage ,
'subpage2' => $this -> page -> subpage ,
'contextid1' => $context -> id ,
'contextid2' => $context -> id ,
'pagetype' => $this -> page -> pagetype ,
);
$sql = " SELECT
bi . id ,
2009-07-09 07:35:03 +00:00
bp . id AS blockpositionid ,
2009-05-06 09:14:42 +00:00
bi . blockname ,
2009-07-10 05:58:59 +00:00
bi . parentcontextid ,
2009-05-06 09:14:42 +00:00
bi . showinsubcontexts ,
bi . pagetypepattern ,
bi . subpagepattern ,
2009-07-15 07:41:25 +00:00
bi . defaultregion ,
bi . defaultweight ,
2009-05-06 09:15:05 +00:00
COALESCE ( bp . visible , 1 ) AS visible ,
2009-05-06 09:14:42 +00:00
COALESCE ( bp . region , bi . defaultregion ) AS region ,
COALESCE ( bp . weight , bi . defaultweight ) AS weight ,
2010-03-31 07:41:31 +00:00
bi . configdata
$ccselect
2009-05-06 09:14:42 +00:00
FROM { block_instances } bi
JOIN { block } b ON bi . blockname = b . name
LEFT JOIN { block_positions } bp ON bp . blockinstanceid = bi . id
AND bp . contextid = : contextid1
AND bp . pagetype = : pagetype
AND bp . subpage = : subpage1
2010-03-31 07:41:31 +00:00
$ccjoin
2009-05-06 09:14:42 +00:00
WHERE
$contexttest
AND bi . pagetypepattern $pagetypepatterntest
AND ( bi . subpagepattern IS NULL OR bi . subpagepattern = : subpage2 )
$visiblecheck
AND b . visible = 1
ORDER BY
COALESCE ( bp . region , bi . defaultregion ),
COALESCE ( bp . weight , bi . defaultweight ),
bi . id " ;
$blockinstances = $DB -> get_recordset_sql ( $sql , $params + $parentcontextparams + $pagetypepatternparams );
2009-05-06 09:15:05 +00:00
$this -> birecordsbyregion = $this -> prepare_per_region_arrays ();
2009-05-06 09:14:42 +00:00
$unknown = array ();
foreach ( $blockinstances as $bi ) {
2010-03-31 07:41:31 +00:00
context_instance_preload ( $bi );
2009-05-06 09:14:42 +00:00
if ( $this -> is_known_region ( $bi -> region )) {
2009-05-06 09:15:05 +00:00
$this -> birecordsbyregion [ $bi -> region ][] = $bi ;
2009-05-06 09:14:42 +00:00
} else {
$unknown [] = $bi ;
}
}
2009-07-09 07:35:03 +00:00
// Pages don't necessarily have a defaultregion. The one time this can
// happen is when there are no theme block regions, but the script itself
// has a block region in the main content area.
if ( ! empty ( $this -> defaultregion )) {
$this -> birecordsbyregion [ $this -> defaultregion ] =
array_merge ( $this -> birecordsbyregion [ $this -> defaultregion ], $unknown );
}
2009-05-06 09:14:42 +00:00
}
/**
* Add a block to the current page , or related pages . The block is added to
* context $this -> page -> contextid . If $pagetypepattern $subpagepattern
2009-05-22 02:18:49 +00:00
*
2009-05-06 09:14:42 +00:00
* @ param string $blockname The type of block to add .
* @ param string $region the block region on this page to add the block to .
* @ param integer $weight determines the order where this block appears in the region .
* @ param boolean $showinsubcontexts whether this block appears in subcontexts , or just the current context .
* @ param string | null $pagetypepattern which page types this block should appear on . Defaults to just the current page type .
* @ param string | null $subpagepattern which subpage this block should appear on . NULL = any ( the default ), otherwise only the specified subpage .
*/
public function add_block ( $blockname , $region , $weight , $showinsubcontexts , $pagetypepattern = NULL , $subpagepattern = NULL ) {
global $DB ;
$this -> check_known_block_type ( $blockname );
$this -> check_region_is_known ( $region );
if ( empty ( $pagetypepattern )) {
$pagetypepattern = $this -> page -> pagetype ;
}
$blockinstance = new stdClass ;
$blockinstance -> blockname = $blockname ;
2009-07-10 05:58:59 +00:00
$blockinstance -> parentcontextid = $this -> page -> context -> id ;
2009-05-06 09:14:42 +00:00
$blockinstance -> showinsubcontexts = ! empty ( $showinsubcontexts );
$blockinstance -> pagetypepattern = $pagetypepattern ;
$blockinstance -> subpagepattern = $subpagepattern ;
$blockinstance -> defaultregion = $region ;
$blockinstance -> defaultweight = $weight ;
$blockinstance -> configdata = '' ;
2009-05-07 09:16:22 +00:00
$blockinstance -> id = $DB -> insert_record ( 'block_instances' , $blockinstance );
2009-07-13 08:37:34 +00:00
// Ensure the block context is created.
get_context_instance ( CONTEXT_BLOCK , $blockinstance -> id );
2009-05-08 07:47:50 +00:00
2009-05-07 09:16:22 +00:00
// If the new instance was created, allow it to do additional setup
2009-07-13 08:37:34 +00:00
if ( $block = block_instance ( $blockname , $blockinstance )) {
2009-05-07 09:16:22 +00:00
$block -> instance_create ();
}
2009-05-06 09:14:42 +00:00
}
2009-07-14 07:18:57 +00:00
public function add_block_at_end_of_default_region ( $blockname ) {
$defaulregion = $this -> get_default_region ();
2009-07-14 09:28:10 +00:00
2009-07-14 07:18:57 +00:00
$lastcurrentblock = end ( $this -> birecordsbyregion [ $defaulregion ]);
2009-07-14 09:28:10 +00:00
if ( $lastcurrentblock ) {
$weight = $lastcurrentblock -> weight + 1 ;
} else {
$weight = 0 ;
}
2009-07-14 07:18:57 +00:00
if ( $this -> page -> subpage ) {
$subpage = $this -> page -> subpage ;
} else {
$subpage = null ;
}
2009-07-14 08:37:28 +00:00
// Special case. Course view page type include the course format, but we
// want to add the block non-format-specifically.
$pagetypepattern = $this -> page -> pagetype ;
if ( strpos ( $pagetypepattern , 'course-view' ) === 0 ) {
$pagetypepattern = 'course-view-*' ;
}
2009-07-14 09:28:10 +00:00
$this -> add_block ( $blockname , $defaulregion , $weight , false , $pagetypepattern , $subpage );
2009-07-14 07:18:57 +00:00
}
2009-05-07 07:05:22 +00:00
/**
* Convenience method , calls add_block repeatedly for all the blocks in $blocks .
2009-05-22 02:18:49 +00:00
*
2009-07-14 09:28:10 +00:00
* @ param array $blocks array with array keys the region names , and values an array of block names .
2009-05-07 07:05:22 +00:00
* @ param string $pagetypepattern optional . Passed to @ see add_block ()
* @ param string $subpagepattern optional . Passed to @ see add_block ()
*/
2009-08-28 08:47:31 +00:00
public function add_blocks ( $blocks , $pagetypepattern = NULL , $subpagepattern = NULL , $showinsubcontexts = false , $weight = 0 ) {
2009-05-07 07:05:22 +00:00
$this -> add_regions ( array_keys ( $blocks ));
foreach ( $blocks as $region => $regionblocks ) {
$weight = 0 ;
foreach ( $regionblocks as $blockname ) {
2009-08-28 08:47:31 +00:00
$this -> add_block ( $blockname , $region , $weight , $showinsubcontexts , $pagetypepattern , $subpagepattern );
2009-05-07 07:05:22 +00:00
$weight += 1 ;
}
}
}
2009-07-30 10:29:14 +00:00
/**
* Move a block to a new position on this page .
*
* If this block cannot appear on any other pages , then we change defaultposition / weight
* in the block_instances table . Otherwise we just set the postition on this page .
*
* @ param $blockinstanceid the block instance id .
* @ param $newregion the new region name .
* @ param $newweight the new weight .
*/
public function reposition_block ( $blockinstanceid , $newregion , $newweight ) {
global $DB ;
$this -> check_region_is_known ( $newregion );
$inst = $this -> find_instance ( $blockinstanceid );
$bi = $inst -> instance ;
if ( $bi -> weight == $bi -> defaultweight && $bi -> region == $bi -> defaultregion &&
! $bi -> showinsubcontexts && strpos ( $bi -> pagetypepattern , '*' ) === false &&
( ! $this -> page -> subpage || $bi -> subpagepattern )) {
// Set default position
$newbi = new stdClass ;
$newbi -> id = $bi -> id ;
$newbi -> defaultregion = $newregion ;
$newbi -> defaultweight = $newweight ;
$DB -> update_record ( 'block_instances' , $newbi );
if ( $bi -> blockpositionid ) {
$bp = new stdClass ;
$bp -> id = $bi -> blockpositionid ;
$bp -> region = $newregion ;
$bp -> weight = $newweight ;
$DB -> update_record ( 'block_positions' , $bp );
}
} else {
// Just set position on this page.
$bp = new stdClass ;
$bp -> region = $newregion ;
$bp -> weight = $newweight ;
if ( $bi -> blockpositionid ) {
$bp -> id = $bi -> blockpositionid ;
$DB -> update_record ( 'block_positions' , $bp );
} else {
$bp -> blockinstanceid = $bi -> id ;
$bp -> contextid = $this -> page -> context -> id ;
$bp -> pagetype = $this -> page -> pagetype ;
if ( $this -> page -> subpage ) {
$bp -> subpage = $this -> page -> subpage ;
} else {
$bp -> subpage = '' ;
}
$bp -> visible = $bi -> visible ;
$DB -> insert_record ( 'block_positions' , $bp );
}
}
}
2009-05-08 06:34:40 +00:00
/**
2009-07-28 09:59:21 +00:00
* Find a given block by its instance id
2009-05-22 02:18:49 +00:00
*
2009-05-08 06:34:40 +00:00
* @ param integer $instanceid
2009-05-22 02:18:49 +00:00
* @ return object
2009-05-08 06:34:40 +00:00
*/
public function find_instance ( $instanceid ) {
foreach ( $this -> regions as $region => $notused ) {
$this -> ensure_instances_exist ( $region );
foreach ( $this -> blockinstances [ $region ] as $instance ) {
if ( $instance -> instance -> id == $instanceid ) {
return $instance ;
}
}
}
throw new block_not_on_page_exception ( $instanceid , $this -> page );
}
2009-05-06 09:14:01 +00:00
/// Inner workings =============================================================
2009-05-22 02:18:49 +00:00
/**
* Check whether the page blocks have been loaded yet
*
* @ return void Throws coding exception if already loaded
*/
2009-05-06 09:14:01 +00:00
protected function check_not_yet_loaded () {
2009-05-06 09:15:05 +00:00
if ( ! is_null ( $this -> birecordsbyregion )) {
2009-05-06 09:14:01 +00:00
throw new coding_exception ( 'block_manager has already loaded the blocks, to it is too late to change things that might affect which blocks are visible.' );
}
}
2009-05-22 02:18:49 +00:00
/**
* Check whether the page blocks have been loaded yet
*
* Nearly identical to the above function { @ link check_not_yet_loaded ()} except different message
*
* @ return void Throws coding exception if already loaded
*/
2009-05-06 09:14:42 +00:00
protected function check_is_loaded () {
2009-05-06 09:15:05 +00:00
if ( is_null ( $this -> birecordsbyregion )) {
2009-05-06 09:14:42 +00:00
throw new coding_exception ( 'block_manager has not yet loaded the blocks, to it is too soon to request the information you asked for.' );
}
}
2009-05-22 02:18:49 +00:00
/**
* Check if a block type is known and usable
*
* @ param string $blockname The block type name to search for
* @ param bool $includeinvisible Include disabled block types in the intial pass
* @ return void Coding Exception thrown if unknown or not enabled
*/
2009-05-06 09:14:42 +00:00
protected function check_known_block_type ( $blockname , $includeinvisible = false ) {
if ( ! $this -> is_known_block_type ( $blockname , $includeinvisible )) {
if ( $this -> is_known_block_type ( $blockname , true )) {
throw new coding_exception ( 'Unknown block type ' . $blockname );
} else {
throw new coding_exception ( 'Block type ' . $blockname . ' has been disabled by the administrator.' );
}
}
}
2009-05-22 02:18:49 +00:00
/**
* Check if a region is known by its name
*
* @ param string $region
* @ return void Coding Exception thrown if the region is not known
*/
2009-05-06 09:14:42 +00:00
protected function check_region_is_known ( $region ) {
if ( ! $this -> is_known_region ( $region )) {
throw new coding_exception ( 'Trying to reference an unknown block region ' . $region );
}
2009-05-06 09:14:01 +00:00
}
2009-05-06 09:15:05 +00:00
/**
2009-05-22 02:18:49 +00:00
* Returns an array of region names as keys and nested arrays for values
*
2009-05-06 09:15:05 +00:00
* @ return array an array where the array keys are the region names , and the array
* values are empty arrays .
*/
protected function prepare_per_region_arrays () {
$result = array ();
foreach ( $this -> regions as $region => $notused ) {
$result [ $region ] = array ();
}
return $result ;
}
2009-05-22 02:18:49 +00:00
/**
* Create a set of new block instance from a record array
*
* @ param array $birecords An array of block instance records
* @ return array An array of instantiated block_instance objects
*/
2009-05-06 09:15:05 +00:00
protected function create_block_instances ( $birecords ) {
$results = array ();
foreach ( $birecords as $record ) {
2009-08-22 11:24:39 +00:00
if ( $blockobject = block_instance ( $record -> blockname , $record , $this -> page )) {
$results [] = $blockobject ;
}
2009-05-06 09:15:05 +00:00
}
return $results ;
}
2009-07-20 03:04:08 +00:00
/**
* Create all the bock instances for all the blocks that were loaded by
* load_blocks . This is used , for example , to ensure that all blocks get a
* chance to initialise themselves via the { @ link block_base :: specialize ()}
* method , before any output is done .
*/
public function create_all_block_instances () {
foreach ( $this -> get_regions () as $region ) {
$this -> ensure_instances_exist ( $region );
}
}
2009-05-22 02:18:49 +00:00
/**
2009-07-30 08:22:12 +00:00
* Return an array of content objects from a set of block instances
2009-05-22 02:18:49 +00:00
*
* @ param array $instances An array of block instances
2009-12-16 18:00:58 +00:00
* @ param renderer_base The renderer to use .
2009-07-30 08:22:12 +00:00
* @ param string $region the region name .
* @ return array An array of block_content ( and possibly block_move_target ) objects .
2009-05-22 02:18:49 +00:00
*/
2009-07-30 08:22:12 +00:00
protected function create_block_contents ( $instances , $output , $region ) {
2009-05-06 09:15:05 +00:00
$results = array ();
2009-07-30 08:22:12 +00:00
$lastweight = 0 ;
$lastblock = 0 ;
if ( $this -> movingblock ) {
$first = reset ( $instances );
if ( $first ) {
$lastweight = $first -> instance -> weight - 2 ;
}
$strmoveblockhere = get_string ( 'moveblockhere' , 'block' );
}
2009-05-06 09:15:05 +00:00
foreach ( $instances as $instance ) {
2009-07-09 07:35:03 +00:00
$content = $instance -> get_content_for_output ( $output );
2009-07-30 08:22:12 +00:00
if ( empty ( $content )) {
continue ;
}
if ( $this -> movingblock && $lastweight != $instance -> instance -> weight &&
$content -> blockinstanceid != $this -> movingblock && $lastblock != $this -> movingblock ) {
2010-02-17 18:36:26 +00:00
$results [] = new block_move_target ( $strmoveblockhere , $this -> get_move_target_url ( $region , ( $lastweight + $instance -> instance -> weight ) / 2 ));
2009-07-30 08:22:12 +00:00
}
if ( $content -> blockinstanceid == $this -> movingblock ) {
$content -> add_class ( 'beingmoved' );
$content -> annotation .= get_string ( 'movingthisblockcancel' , 'block' ,
2010-02-11 16:27:53 +00:00
html_writer :: link ( $this -> page -> url , get_string ( 'cancel' )));
2009-05-06 09:15:05 +00:00
}
2009-07-30 08:22:12 +00:00
$results [] = $content ;
$lastweight = $instance -> instance -> weight ;
$lastblock = $instance -> instance -> id ;
}
if ( $this -> movingblock && $lastblock != $this -> movingblock ) {
2010-02-17 18:36:26 +00:00
$results [] = new block_move_target ( $strmoveblockhere , $this -> get_move_target_url ( $region , $lastweight + 1 ));
2009-05-06 09:15:05 +00:00
}
return $results ;
}
2009-05-22 02:18:49 +00:00
/**
* Ensure block instances exist for a given region
2009-07-28 09:59:21 +00:00
*
2009-05-22 02:18:49 +00:00
* @ param string $region Check for bi ' s with the instance with this name
*/
2009-05-06 09:15:05 +00:00
protected function ensure_instances_exist ( $region ) {
$this -> check_region_is_known ( $region );
if ( ! array_key_exists ( $region , $this -> blockinstances )) {
$this -> blockinstances [ $region ] =
$this -> create_block_instances ( $this -> birecordsbyregion [ $region ]);
}
}
2009-05-22 02:18:49 +00:00
/**
* Ensure that there is some content within the given region
*
* @ param string $region The name of the region to check
*/
2009-07-09 07:35:03 +00:00
protected function ensure_content_created ( $region , $output ) {
2009-05-06 09:15:05 +00:00
$this -> ensure_instances_exist ( $region );
if ( ! array_key_exists ( $region , $this -> visibleblockcontent )) {
2009-07-09 07:35:03 +00:00
$contents = array ();
if ( array_key_exists ( $region , $this -> extracontent )) {
$contents = $this -> extracontent [ $region ];
}
2009-07-30 08:22:12 +00:00
$contents = array_merge ( $contents , $this -> create_block_contents ( $this -> blockinstances [ $region ], $output , $region ));
2009-07-09 07:35:03 +00:00
if ( $region == $this -> defaultregion ) {
2009-07-14 07:18:57 +00:00
$addblockui = block_add_block_ui ( $this -> page , $output );
2009-07-09 07:35:03 +00:00
if ( $addblockui ) {
$contents [] = $addblockui ;
}
}
$this -> visibleblockcontent [ $region ] = $contents ;
2009-05-06 09:15:05 +00:00
}
}
2009-07-28 09:59:21 +00:00
/// Process actions from the URL ===============================================
2009-07-30 08:22:12 +00:00
/**
* Get the appropriate list of editing icons for a block . This is used
* to set { @ link block_contents :: $controls } in { @ link block_base :: get_contents_for_output ()} .
*
* @ param $output The core_renderer to use when generating the output . ( Need to get icon paths . )
* @ return an array in the format for { @ link block_contents :: $controls }
*/
public function edit_controls ( $block ) {
global $CFG ;
2009-09-11 06:00:32 +00:00
if ( ! isset ( $CFG -> undeletableblocktypes ) || ( ! is_array ( $CFG -> undeletableblocktypes ) && ! is_string ( $CFG -> undeletableblocktypes ))) {
$CFG -> undeletableblocktypes = array ( 'global_navigation_tree' , 'settings_navigation_tree' );
} else if ( is_string ( $CFG -> undeletableblocktypes )) {
$CFG -> undeletableblocktypes = explode ( ',' , $CFG -> undeletableblocktypes );
}
2009-07-30 08:22:12 +00:00
$controls = array ();
2010-01-17 09:50:55 +00:00
$actionurl = $this -> page -> url -> out ( false , array ( 'sesskey' => sesskey ()));
2009-07-30 08:22:12 +00:00
// Assign roles icon.
if ( has_capability ( 'moodle/role:assign' , $block -> context )) {
2010-01-17 09:13:36 +00:00
//TODO: please note it is sloppy to pass urls through page parameters!!
// it is shortened because some web servers (e.g. IIS by default) give
// a 'security' error if you try to pass a full URL as a GET parameter in another URL.
2010-03-31 07:41:31 +00:00
2010-01-17 11:01:31 +00:00
$return = $this -> page -> url -> out ( false );
2010-01-17 09:13:36 +00:00
$return = str_replace ( $CFG -> wwwroot . '/' , '' , $return );
2010-03-31 07:41:31 +00:00
2009-07-30 08:22:12 +00:00
$controls [] = array ( 'url' => $CFG -> wwwroot . '/' . $CFG -> admin .
2010-01-17 09:13:36 +00:00
'/roles/assign.php?contextid=' . $block -> context -> id . '&returnurl=' . urlencode ( $return ),
2009-07-30 08:22:12 +00:00
'icon' => 'i/roles' , 'caption' => get_string ( 'assignroles' , 'role' ));
}
if ( $this -> page -> user_can_edit_blocks ()) {
// Show/hide icon.
if ( $block -> instance -> visible ) {
$controls [] = array ( 'url' => $actionurl . '&bui_hideid=' . $block -> instance -> id ,
'icon' => 't/hide' , 'caption' => get_string ( 'hide' ));
} else {
$controls [] = array ( 'url' => $actionurl . '&bui_showid=' . $block -> instance -> id ,
'icon' => 't/show' , 'caption' => get_string ( 'show' ));
}
}
if ( $this -> page -> user_can_edit_blocks () || $block -> user_can_edit ()) {
// Edit config icon - always show - needed for positioning UI.
$controls [] = array ( 'url' => $actionurl . '&bui_editid=' . $block -> instance -> id ,
'icon' => 't/edit' , 'caption' => get_string ( 'configuration' ));
}
if ( $this -> page -> user_can_edit_blocks () && $block -> user_can_edit () && $block -> user_can_addto ( $this -> page )) {
2009-09-11 06:00:32 +00:00
if ( ! in_array ( $block -> instance -> blockname , $CFG -> undeletableblocktypes )) {
// Delete icon.
$controls [] = array ( 'url' => $actionurl . '&bui_deleteid=' . $block -> instance -> id ,
'icon' => 't/delete' , 'caption' => get_string ( 'delete' ));
}
2009-07-30 08:22:12 +00:00
}
if ( $this -> page -> user_can_edit_blocks ()) {
// Move icon.
$controls [] = array ( 'url' => $actionurl . '&bui_moveid=' . $block -> instance -> id ,
'icon' => 't/move' , 'caption' => get_string ( 'move' ));
}
return $controls ;
}
2009-07-28 09:59:21 +00:00
/**
* Process any block actions that were specified in the URL .
*
* This can only be done given a valid $page object .
*
* @ param moodle_page $page the page to add blocks to .
* @ return boolean true if anything was done . False if not .
*/
public function process_url_actions () {
2009-07-30 08:22:12 +00:00
if ( ! $this -> page -> user_is_editing ()) {
return false ;
}
2009-07-28 09:59:21 +00:00
return $this -> process_url_add () || $this -> process_url_delete () ||
2009-07-30 08:22:12 +00:00
$this -> process_url_show_hide () || $this -> process_url_edit () ||
$this -> process_url_move ();
2009-07-28 09:59:21 +00:00
}
/**
* Handle adding a block .
* @ return boolean true if anything was done . False if not .
*/
public function process_url_add () {
$blocktype = optional_param ( 'bui_addblock' , null , PARAM_SAFEDIR );
if ( ! $blocktype ) {
return false ;
}
2009-11-02 17:16:28 +00:00
require_sesskey ();
2009-07-28 09:59:21 +00:00
2009-07-30 09:40:11 +00:00
if ( ! $this -> page -> user_can_edit_blocks ()) {
2009-07-28 09:59:21 +00:00
throw new moodle_exception ( 'nopermissions' , '' , $this -> page -> url -> out (), get_string ( 'addblock' ));
}
if ( ! array_key_exists ( $blocktype , $this -> get_addable_blocks ())) {
throw new moodle_exception ( 'cannotaddthisblocktype' , '' , $this -> page -> url -> out (), $blocktype );
}
$this -> add_block_at_end_of_default_region ( $blocktype );
// If the page URL was a guses, it will contain the bui_... param, so we must make sure it is not there.
$this -> page -> ensure_param_not_in_url ( 'bui_addblock' );
return true ;
}
/**
* Handle deleting a block .
* @ return boolean true if anything was done . False if not .
*/
public function process_url_delete () {
$blockid = optional_param ( 'bui_deleteid' , null , PARAM_INTEGER );
if ( ! $blockid ) {
return false ;
}
2009-11-02 17:16:28 +00:00
require_sesskey ();
2009-07-28 09:59:21 +00:00
$block = $this -> page -> blocks -> find_instance ( $blockid );
2009-07-29 03:19:43 +00:00
if ( ! $block -> user_can_edit () || ! $this -> page -> user_can_edit_blocks () || ! $block -> user_can_addto ( $this -> page )) {
2009-07-28 09:59:21 +00:00
throw new moodle_exception ( 'nopermissions' , '' , $this -> page -> url -> out (), get_string ( 'deleteablock' ));
}
blocks_delete_instance ( $block -> instance );
// If the page URL was a guses, it will contain the bui_... param, so we must make sure it is not there.
$this -> page -> ensure_param_not_in_url ( 'bui_deleteid' );
return true ;
}
/**
* Handle showing or hiding a block .
* @ return boolean true if anything was done . False if not .
*/
public function process_url_show_hide () {
if ( $blockid = optional_param ( 'bui_hideid' , null , PARAM_INTEGER )) {
$newvisibility = 0 ;
} else if ( $blockid = optional_param ( 'bui_showid' , null , PARAM_INTEGER )) {
$newvisibility = 1 ;
} else {
return false ;
}
2009-11-02 17:16:28 +00:00
require_sesskey ();
2009-07-28 09:59:21 +00:00
$block = $this -> page -> blocks -> find_instance ( $blockid );
2009-07-30 03:44:10 +00:00
if ( ! $this -> page -> user_can_edit_blocks ()) {
2009-07-28 09:59:21 +00:00
throw new moodle_exception ( 'nopermissions' , '' , $this -> page -> url -> out (), get_string ( 'hideshowblocks' ));
}
blocks_set_visibility ( $block -> instance , $this -> page , $newvisibility );
// If the page URL was a guses, it will contain the bui_... param, so we must make sure it is not there.
$this -> page -> ensure_param_not_in_url ( 'bui_hideid' );
$this -> page -> ensure_param_not_in_url ( 'bui_showid' );
return true ;
}
/**
* Handle showing / processing the submission from the block editing form .
* @ return boolean true if the form was submitted and the new config saved . Does not
* return if the editing form was displayed . False otherwise .
*/
public function process_url_edit () {
global $CFG , $DB , $PAGE ;
$blockid = optional_param ( 'bui_editid' , null , PARAM_INTEGER );
if ( ! $blockid ) {
return false ;
}
2009-11-02 17:16:28 +00:00
require_sesskey ();
2009-07-28 09:59:21 +00:00
require_once ( $CFG -> dirroot . '/blocks/edit_form.php' );
$block = $this -> find_instance ( $blockid );
2009-07-30 03:44:10 +00:00
if ( ! $block -> user_can_edit () && ! $this -> page -> user_can_edit_blocks ()) {
2009-07-28 09:59:21 +00:00
throw new moodle_exception ( 'nopermissions' , '' , $this -> page -> url -> out (), get_string ( 'editblock' ));
}
$editpage = new moodle_page ();
2010-02-18 09:23:14 +00:00
$editpage -> set_pagelayout ( 'admin' );
2009-07-28 09:59:21 +00:00
$editpage -> set_course ( $this -> page -> course );
2009-07-29 03:19:43 +00:00
$editpage -> set_context ( $block -> context );
2010-01-18 12:12:38 +00:00
$editurlbase = str_replace ( $CFG -> wwwroot . '/' , '/' , $this -> page -> url -> out_omit_querystring ());
2009-07-28 09:59:21 +00:00
$editurlparams = $this -> page -> url -> params ();
$editurlparams [ 'bui_editid' ] = $blockid ;
$editpage -> set_url ( $editurlbase , $editurlparams );
$editpage -> _block_actions_done = true ;
// At this point we are either going to redirect, or display the form, so
// overwrite global $PAGE ready for this. (Formslib refers to it.)
$PAGE = $editpage ;
$formfile = $CFG -> dirroot . '/blocks/' . $block -> name () . '/edit_form.php' ;
if ( is_readable ( $formfile )) {
require_once ( $formfile );
$classname = 'block_' . $block -> name () . '_edit_form' ;
} else {
$classname = 'block_edit_form' ;
}
$mform = new $classname ( $editpage -> url , $block , $this -> page );
$mform -> set_data ( $block -> instance );
if ( $mform -> is_cancelled ()) {
redirect ( $this -> page -> url );
} else if ( $data = $mform -> get_data ()) {
$bi = new stdClass ;
$bi -> id = $block -> instance -> id ;
$bi -> pagetypepattern = $data -> bui_pagetypepattern ;
if ( empty ( $data -> bui_subpagepattern ) || $data -> bui_subpagepattern == '%@NULL@%' ) {
$bi -> subpagepattern = null ;
} else {
$bi -> subpagepattern = $data -> bui_subpagepattern ;
}
2010-01-20 09:08:04 +00:00
$parentcontext = get_context_instance_by_id ( $data -> bui_parentcontextid );
$systemcontext = get_context_instance ( CONTEXT_SYSTEM );
// Updating stickiness and contexts. See MDL-21375 for details.
if ( has_capability ( 'moodle/site:manageblocks' , $parentcontext )) { // Check permissions in destination
// Explicitly set the context
$bi -> parentcontextid = $parentcontext -> id ;
// If the context type is > 0 then we'll explicitly set the block as sticky, otherwise not
$bi -> showinsubcontexts = ( int )( ! empty ( $data -> bui_contexts ));
// If the block wants to be system-wide, then explicitly set that
if ( $data -> bui_contexts == 2 ) { // Only possible on a frontpage or system page
$bi -> parentcontextid = $systemcontext -> id ;
} else { // The block doesn't want to be system-wide, so let's ensure that
if ( $parentcontext -> id == $systemcontext -> id ) { // We need to move it to the front page
$frontpagecontext = get_context_instance ( CONTEXT_COURSE , SITEID );
$bi -> parentcontextid = $frontpagecontext -> id ;
$bi -> pagetypepattern = '*' ; // Just in case
}
2010-01-19 10:07:52 +00:00
}
}
2010-01-20 09:08:04 +00:00
2009-07-28 09:59:21 +00:00
$bi -> defaultregion = $data -> bui_defaultregion ;
$bi -> defaultweight = $data -> bui_defaultweight ;
$DB -> update_record ( 'block_instances' , $bi );
2009-07-29 03:51:16 +00:00
if ( ! empty ( $block -> config )) {
$config = clone ( $block -> config );
} else {
$config = new stdClass ;
}
2009-07-28 09:59:21 +00:00
foreach ( $data as $configfield => $value ) {
if ( strpos ( $configfield , 'config_' ) !== 0 ) {
continue ;
}
$field = substr ( $configfield , 7 );
$config -> $field = $value ;
}
$block -> instance_config_save ( $config );
$bp = new stdClass ;
$bp -> visible = $data -> bui_visible ;
$bp -> region = $data -> bui_region ;
$bp -> weight = $data -> bui_weight ;
$needbprecord = ! $data -> bui_visible || $data -> bui_region != $data -> bui_defaultregion ||
$data -> bui_weight != $data -> bui_defaultweight ;
if ( $block -> instance -> blockpositionid && ! $needbprecord ) {
$DB -> delete_records ( 'block_positions' , array ( 'id' => $block -> instance -> blockpositionid ));
} else if ( $block -> instance -> blockpositionid && $needbprecord ) {
$bp -> id = $block -> instance -> blockpositionid ;
$DB -> update_record ( 'block_positions' , $bp );
} else if ( $needbprecord ) {
$bp -> blockinstanceid = $block -> instance -> id ;
2009-07-29 03:51:16 +00:00
$bp -> contextid = $this -> page -> context -> id ;
2009-07-28 09:59:21 +00:00
$bp -> pagetype = $this -> page -> pagetype ;
if ( $this -> page -> subpage ) {
$bp -> subpage = $this -> page -> subpage ;
} else {
2009-07-29 03:51:16 +00:00
$bp -> subpage = '' ;
2009-07-28 09:59:21 +00:00
}
$DB -> insert_record ( 'block_positions' , $bp );
}
redirect ( $this -> page -> url );
} else {
$strheading = get_string ( 'editinga' , $block -> name ());
if ( strpos ( $strheading , '[[' ) === 0 ) {
$strheading = get_string ( 'blockconfiga' , 'moodle' , $block -> get_title ());
}
$editpage -> set_title ( $strheading );
$editpage -> set_heading ( $strheading );
2010-02-18 09:23:14 +00:00
$editpage -> navbar -> add ( $strheading );
2009-12-17 14:06:22 +00:00
$output = $editpage -> get_renderer ( 'core' );
2009-07-28 09:59:21 +00:00
echo $output -> header ();
echo $output -> heading ( $strheading , 2 );
$mform -> display ();
echo $output -> footer ();
exit ;
}
}
2009-07-30 08:22:12 +00:00
/**
* Handle showing / processing the submission from the block editing form .
* @ return boolean true if the form was submitted and the new config saved . Does not
* return if the editing form was displayed . False otherwise .
*/
public function process_url_move () {
global $CFG , $DB , $PAGE ;
$blockid = optional_param ( 'bui_moveid' , null , PARAM_INTEGER );
if ( ! $blockid ) {
return false ;
}
2009-11-02 17:16:28 +00:00
require_sesskey ();
2009-07-30 08:22:12 +00:00
$block = $this -> find_instance ( $blockid );
if ( ! $this -> page -> user_can_edit_blocks ()) {
throw new moodle_exception ( 'nopermissions' , '' , $this -> page -> url -> out (), get_string ( 'editblock' ));
}
$newregion = optional_param ( 'bui_newregion' , '' , PARAM_ALPHANUMEXT );
$newweight = optional_param ( 'bui_newweight' , null , PARAM_FLOAT );
if ( ! $newregion || is_null ( $newweight )) {
// Don't have a valid target position yet, must be just starting the move.
$this -> movingblock = $blockid ;
$this -> page -> ensure_param_not_in_url ( 'bui_moveid' );
return false ;
}
2009-07-30 10:29:14 +00:00
if ( ! $this -> is_known_region ( $newregion )) {
throw new moodle_exception ( 'unknownblockregion' , '' , $this -> page -> url , $newregion );
}
// Move this block. This may involve moving other nearby blocks.
$blocks = $this -> birecordsbyregion [ $newregion ];
2009-09-09 02:44:57 +00:00
$maxweight = self :: MAX_WEIGHT ;
$minweight = - self :: MAX_WEIGHT ;
// Initialise the used weights and spareweights array with the default values
2009-07-30 10:29:14 +00:00
$spareweights = array ();
$usedweights = array ();
2009-09-09 02:44:57 +00:00
for ( $i = $minweight ; $i <= $maxweight ; $i ++ ) {
2009-07-30 10:29:14 +00:00
$spareweights [ $i ] = $i ;
$usedweights [ $i ] = array ();
}
2009-09-09 02:44:57 +00:00
// Check each block and sort out where we have used weights
2009-07-30 10:29:14 +00:00
foreach ( $blocks as $bi ) {
2009-09-09 02:44:57 +00:00
if ( $bi -> weight > $maxweight ) {
// If this statement is true then the blocks weight is more than the
// current maximum. To ensure that we can get the best block position
// we will initialise elements within the usedweights and spareweights
// arrays between the blocks weight (which will then be the new max) and
// the current max
$parseweight = $bi -> weight ;
while ( ! array_key_exists ( $parseweight , $usedweights )) {
$usedweights [ $parseweight ] = array ();
$spareweights [ $parseweight ] = $parseweight ;
$parseweight -- ;
}
$maxweight = $bi -> weight ;
} else if ( $bi -> weight < $minweight ) {
// As above except this time the blocks weight is LESS than the
// the current minimum, so we will initialise the array from the
// blocks weight (new minimum) to the current minimum
$parseweight = $bi -> weight ;
while ( ! array_key_exists ( $parseweight , $usedweights )) {
$usedweights [ $parseweight ] = array ();
$spareweights [ $parseweight ] = $parseweight ;
$parseweight ++ ;
}
$minweight = $bi -> weight ;
}
if ( $bi -> id != $block -> instance -> id ) {
unset ( $spareweights [ $bi -> weight ]);
$usedweights [ $bi -> weight ][] = $bi -> id ;
2009-07-30 10:29:14 +00:00
}
}
2009-09-09 02:44:57 +00:00
// First we find the nearest gap in the list of weights.
2009-07-30 10:29:14 +00:00
$bestdistance = max ( abs ( $newweight - self :: MAX_WEIGHT ), abs ( $newweight + self :: MAX_WEIGHT )) + 1 ;
$bestgap = null ;
foreach ( $spareweights as $spareweight ) {
if ( abs ( $newweight - $spareweight ) < $bestdistance ) {
$bestdistance = abs ( $newweight - $spareweight );
$bestgap = $spareweight ;
}
}
// If there is no gap, we have to go outside -self::MAX_WEIGHT .. self::MAX_WEIGHT.
if ( is_null ( $bestgap )) {
$bestgap = self :: MAX_WEIGHT + 1 ;
while ( ! empty ( $usedweights [ $bestgap ])) {
$bestgap ++ ;
}
}
// Now we know the gap we are aiming for, so move all the blocks along.
if ( $bestgap < $newweight ) {
$newweight = floor ( $newweight );
for ( $weight = $bestgap + 1 ; $weight <= $newweight ; $weight ++ ) {
foreach ( $usedweights [ $weight ] as $biid ) {
$this -> reposition_block ( $biid , $newregion , $weight - 1 );
}
}
$this -> reposition_block ( $block -> instance -> id , $newregion , $newweight );
} else {
$newweight = ceil ( $newweight );
for ( $weight = $bestgap - 1 ; $weight >= $newweight ; $weight -- ) {
foreach ( $usedweights [ $weight ] as $biid ) {
$this -> reposition_block ( $biid , $newregion , $weight + 1 );
}
}
$this -> reposition_block ( $block -> instance -> id , $newregion , $newweight );
}
2009-11-01 16:48:45 +00:00
2009-07-30 08:22:12 +00:00
$this -> page -> ensure_param_not_in_url ( 'bui_moveid' );
$this -> page -> ensure_param_not_in_url ( 'bui_newregion' );
$this -> page -> ensure_param_not_in_url ( 'bui_newweight' );
return true ;
}
2009-05-06 09:14:01 +00:00
}
2009-05-06 09:14:42 +00:00
/// Helper functions for working with block classes ============================
/**
* Call a class method ( one that does not requrie a block instance ) on a block class .
2009-05-22 02:18:49 +00:00
*
2009-05-06 09:14:42 +00:00
* @ param string $blockname the name of the block .
* @ param string $method the method name .
* @ param array $param parameters to pass to the method .
* @ return mixed whatever the method returns .
*/
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
}
2009-05-06 09:14:42 +00:00
/**
* Creates a new object of the specified block class .
2009-05-22 02:18:49 +00:00
*
2009-05-06 09:14:42 +00:00
* @ param string $blockname the name of the block .
* @ param $instance block_instances DB table row ( optional ) .
2009-05-06 09:15:05 +00:00
* @ param moodle_page $page the page this block is appearing on .
2009-05-06 09:14:42 +00:00
* @ return block_base the requested block instance .
*/
2009-05-06 09:15:05 +00:00
function block_instance ( $blockname , $instance = NULL , $page = 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 ) {
2009-05-06 09:15:05 +00:00
if ( is_null ( $page )) {
global $PAGE ;
$page = $PAGE ;
}
$retval -> _load_instance ( $instance , $page );
2004-10-19 21:04:28 +00:00
}
return $retval ;
2004-04-18 23:20:53 +00:00
}
2009-05-06 09:14:42 +00:00
/**
* Load the block class for a particular type of block .
2009-05-22 02:18:49 +00:00
*
2009-05-06 09:14:42 +00:00
* @ param string $blockname the name of the block .
* @ return boolean success or failure .
*/
2004-04-18 23:20:53 +00:00
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 ;
}
2009-08-22 11:24:39 +00:00
$blockpath = $CFG -> dirroot . '/blocks/' . $blockname . '/block_' . $blockname . '.php' ;
if ( file_exists ( $blockpath )) {
require_once ( $CFG -> dirroot . '/blocks/moodleblock.class.php' );
include_once ( $blockpath );
} else {
2010-04-11 12:08:40 +00:00
//debugging("$blockname code does not exist in $blockpath", DEBUG_DEVELOPER);
2009-08-22 11:24:39 +00:00
return false ;
}
2004-04-18 23:20:53 +00:00
return class_exists ( $classname );
}
2009-07-16 10:50:19 +00:00
/**
* Given a specific page type , return all the page type patterns that might
* match it .
*
* @ param string $pagetype for example 'course-view-weeks' or 'mod-quiz-view' .
* @ return array an array of all the page type patterns that might match this page type .
*/
function matching_page_type_patterns ( $pagetype ) {
$patterns = array ( $pagetype );
$bits = explode ( '-' , $pagetype );
if ( count ( $bits ) == 3 && $bits [ 0 ] == 'mod' ) {
if ( $bits [ 2 ] == 'view' ) {
$patterns [] = 'mod-*-view' ;
} else if ( $bits [ 2 ] == 'index' ) {
$patterns [] = 'mod-*-index' ;
}
}
while ( count ( $bits ) > 0 ) {
$patterns [] = implode ( '-' , $bits ) . '-*' ;
array_pop ( $bits );
}
$patterns [] = '*' ;
return $patterns ;
}
2009-07-14 07:18:57 +00:00
/// Functions update the blocks if required by the request parameters ==========
/**
* Return a { @ link block_contents } representing the add a new block UI , if
* this user is allowed to see it .
*
* @ return block_contents an appropriate block_contents , or null if the user
* cannot add any blocks here .
*/
function block_add_block_ui ( $page , $output ) {
2009-08-10 03:39:21 +00:00
global $CFG , $OUTPUT ;
2009-07-14 07:18:57 +00:00
if ( ! $page -> user_is_editing () || ! $page -> user_can_edit_blocks ()) {
return null ;
}
$bc = new block_contents ();
$bc -> title = get_string ( 'addblock' );
$bc -> add_class ( 'block_adminblock' );
2009-07-14 08:37:28 +00:00
$missingblocks = $page -> blocks -> get_addable_blocks ();
2009-07-14 07:18:57 +00:00
if ( empty ( $missingblocks )) {
2009-07-14 08:37:28 +00:00
$bc -> content = get_string ( 'noblockstoaddhere' );
2009-07-14 07:18:57 +00:00
return $bc ;
}
$menu = array ();
2009-07-14 08:37:28 +00:00
foreach ( $missingblocks as $block ) {
2009-07-14 07:18:57 +00:00
$blockobject = block_instance ( $block -> name );
if ( $blockobject !== false && $blockobject -> user_can_addto ( $page )) {
$menu [ $block -> name ] = $blockobject -> get_title ();
}
}
asort ( $menu , SORT_LOCALE_STRING );
2010-01-17 10:54:13 +00:00
$actionurl = new moodle_url ( $page -> url , array ( 'sesskey' => sesskey ()));
2010-02-10 09:37:50 +00:00
$select = new single_select ( $actionurl , 'bui_addblock' , $menu , null , array ( '' => get_string ( 'adddots' )), 'add_block' );
$bc -> content = $OUTPUT -> render ( $select );
2009-07-14 07:18:57 +00:00
return $bc ;
}
// Functions that have been deprecated by block_manager =======================
2004-11-08 19:36:07 +00:00
2009-05-06 09:14:42 +00:00
/**
2009-07-14 08:37:28 +00:00
* @ deprecated since Moodle 2.0 - use $page -> blocks -> get_addable_blocks ();
2009-05-22 02:18:49 +00:00
*
2009-05-06 09:14:42 +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 .
2009-05-22 02:18:49 +00:00
*
2009-05-06 09:14:42 +00:00
* @ param $page the page object .
2009-05-06 09:15:05 +00:00
* @ param $blockmanager Not used .
2009-05-06 09:14:42 +00:00
* @ return array of block type ids .
*/
2009-05-06 09:15:05 +00:00
function blocks_get_missing ( & $page , & $blockmanager ) {
2009-07-14 08:37:28 +00:00
debugging ( 'blocks_get_missing is deprecated. Please use $page->blocks->get_addable_blocks() instead.' , DEBUG_DEVELOPER );
$blocks = $page -> blocks -> get_addable_blocks ();
$ids = array ();
foreach ( $blocks as $block ) {
$ids [] = $block -> id ;
}
return $ids ;
2004-11-08 19:36:07 +00:00
}
2009-05-06 09:15:05 +00:00
/**
* Actually delete from the database any blocks that are currently on this page ,
* but which should not be there according to blocks_name_allowed_in_format .
2009-05-22 02:18:49 +00:00
*
* @ todo Write / Fix this function . Currently returns immediatly
2009-06-12 11:56:30 +00:00
* @ param $course
2009-05-06 09:15:05 +00:00
*/
2009-06-12 11:56:30 +00:00
function blocks_remove_inappropriate ( $course ) {
2009-05-06 09:15:05 +00:00
// TODO
return ;
$blockmanager = blocks_get_by_page ( $page );
2004-11-08 19:36:07 +00:00
2009-12-16 18:00:58 +00:00
if ( empty ( $blockmanager )) {
2004-11-08 19:36:07 +00:00
return ;
}
2009-12-16 18:00:58 +00:00
if (( $pageformat = $page -> pagetype ) == NULL ) {
2004-11-08 19:36:07 +00:00
return ;
}
2009-05-06 09:27:02 +00:00
foreach ( $blockmanager as $region ) {
foreach ( $region as $instance ) {
2004-11-08 19:36:07 +00:00
$block = blocks_get_record ( $instance -> blockid );
2005-02-10 18:43:18 +00:00
if ( ! blocks_name_allowed_in_format ( $block -> name , $pageformat )) {
2009-07-14 08:37:28 +00:00
blocks_delete_instance ( $instance -> instance );
2004-11-08 19:36:07 +00:00
}
}
}
}
2009-05-22 02:18:49 +00:00
/**
* Check that a given name is in a permittable format
*
* @ param string $name
* @ param string $pageformat
* @ return bool
*/
2005-02-10 18:43:18 +00:00
function blocks_name_allowed_in_format ( $name , $pageformat ) {
2009-05-06 08:36:50 +00:00
$accept = NULL ;
$maxdepth = - 1 ;
$formats = block_method_result ( $name , 'applicable_formats' );
if ( ! $formats ) {
$formats = array ();
}
foreach ( $formats as $format => $allowed ) {
$formatregex = '/^' . str_replace ( '*' , '[^-]*' , $format ) . '.*$/' ;
$depth = substr_count ( $format , '-' );
if ( preg_match ( $formatregex , $pageformat ) && $depth > $maxdepth ) {
$maxdepth = $depth ;
$accept = $allowed ;
2005-02-10 18:43:18 +00:00
}
}
2009-05-06 08:36:50 +00:00
if ( $accept === NULL ) {
2005-02-10 18:43:18 +00:00
$accept = ! empty ( $formats [ 'all' ]);
}
return $accept ;
}
2009-05-07 09:16:22 +00:00
/**
* Delete a block , and associated data .
2009-05-22 02:18:49 +00:00
*
2009-05-07 09:16:22 +00:00
* @ param object $instance a row from the block_instances table
2009-05-22 02:18:49 +00:00
* @ param bool $nolongerused legacy parameter . Not used , but kept for bacwards compatibility .
* @ param bool $skipblockstables for internal use only . Makes @ see blocks_delete_all_for_context () more efficient .
2009-05-07 09:16:22 +00:00
*/
function blocks_delete_instance ( $instance , $nolongerused = false , $skipblockstables = false ) {
2009-05-08 06:34:40 +00:00
global $DB ;
if ( $block = block_instance ( $instance -> blockname , $instance )) {
2009-05-07 09:16:22 +00:00
$block -> instance_delete ();
}
delete_context ( CONTEXT_BLOCK , $instance -> id );
2004-11-08 19:36:07 +00:00
2009-05-07 09:16:22 +00:00
if ( ! $skipblockstables ) {
$DB -> delete_records ( 'block_positions' , array ( 'blockinstanceid' => $instance -> id ));
$DB -> delete_records ( 'block_instances' , array ( 'id' => $instance -> id ));
2005-06-13 03:32:31 +00:00
}
2009-05-07 09:16:22 +00:00
}
2005-06-13 03:32:31 +00:00
2009-05-07 09:16:22 +00:00
/**
* Delete all the blocks that belong to a particular context .
2009-05-22 02:18:49 +00:00
*
* @ param int $contextid the context id .
2009-05-07 09:16:22 +00:00
*/
function blocks_delete_all_for_context ( $contextid ) {
global $DB ;
2009-07-14 08:37:28 +00:00
$instances = $DB -> get_recordset ( 'block_instances' , array ( 'parentcontextid' => $contextid ));
2009-05-07 09:16:22 +00:00
foreach ( $instances as $instance ) {
blocks_delete_instance ( $instance , true );
2005-08-16 00:25:39 +00:00
}
2009-05-07 09:16:22 +00:00
$instances -> close ();
2009-07-10 05:58:59 +00:00
$DB -> delete_records ( 'block_instances' , array ( 'parentcontextid' => $contextid ));
2009-05-07 09:16:22 +00:00
$DB -> delete_records ( 'block_positions' , array ( 'contextid' => $contextid ));
2004-11-08 19:36:07 +00:00
}
2009-07-15 07:41:25 +00:00
/**
* Set a block to be visible or hidden on a particular page .
*
* @ param object $instance a row from the block_instances , preferably LEFT JOINed with the
* block_positions table as return by block_manager .
* @ param moodle_page $page the back to set the visibility with respect to .
* @ param integer $newvisibility 1 for visible , 0 for hidden .
*/
function blocks_set_visibility ( $instance , $page , $newvisibility ) {
global $DB ;
if ( ! empty ( $instance -> blockpositionid )) {
// Already have local information on this page.
$DB -> set_field ( 'block_positions' , 'visible' , $newvisibility , array ( 'id' => $instance -> blockpositionid ));
return ;
}
// Create a new block_positions record.
$bp = new stdClass ;
$bp -> blockinstanceid = $instance -> id ;
$bp -> contextid = $page -> context -> id ;
$bp -> pagetype = $page -> pagetype ;
if ( $page -> subpage ) {
$bp -> subpage = $page -> subpage ;
}
$bp -> visible = $newvisibility ;
$bp -> region = $instance -> defaultregion ;
$bp -> weight = $instance -> defaultweight ;
$DB -> insert_record ( 'block_positions' , $bp );
}
2009-05-22 02:18:49 +00:00
/**
2009-07-09 07:35:03 +00:00
* @ deprecated since 2.0
* Delete all the blocks from a particular page .
2009-05-22 02:18:49 +00:00
*
2009-07-09 07:35:03 +00:00
* @ param string $pagetype the page type .
* @ param integer $pageid the page id .
* @ return bool success or failure .
2009-05-22 02:18:49 +00:00
*/
2009-07-09 07:35:03 +00:00
function blocks_delete_all_on_page ( $pagetype , $pageid ) {
global $DB ;
debugging ( 'Call to deprecated function blocks_delete_all_on_page. ' .
'This function cannot work any more. Doing nothing. ' .
'Please update your code to use a block_manager method $PAGE->blocks->....' , DEBUG_DEVELOPER );
return false ;
2004-04-18 23:20:53 +00:00
}
2009-05-22 02:18:49 +00:00
/**
2009-07-09 07:35:03 +00:00
* Dispite what this function is called , it seems to be mostly used to populate
* the default blocks when a new course ( or whatever ) is created .
2009-05-22 02:18:49 +00:00
*
2009-07-09 07:35:03 +00:00
* @ deprecated since 2.0
2009-05-22 02:18:49 +00:00
*
2009-07-09 07:35:03 +00:00
* @ param object $page the page to add default blocks to .
* @ return boolean success or failure .
2009-05-22 02:18:49 +00:00
*/
2009-07-09 07:35:03 +00:00
function blocks_repopulate_page ( $page ) {
global $CFG ;
2004-04-18 23:20:53 +00:00
2009-07-09 07:35:03 +00:00
debugging ( 'Call to deprecated function blocks_repopulate_page. ' .
'Use a more specific method like blocks_add_default_course_blocks, ' .
'or just call $PAGE->blocks->add_blocks()' , DEBUG_DEVELOPER );
2006-11-15 03:31:28 +00:00
2009-07-09 07:35:03 +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 ();
2005-03-02 05:47:39 +00:00
}
2004-04-18 23:20:53 +00:00
2009-07-09 07:35:03 +00:00
$blocks = blocks_parse_default_blocks_list ( $blocknames );
$page -> blocks -> add_blocks ( $blocks );
return true ;
2004-04-18 23:20:53 +00:00
}
2009-05-06 09:14:42 +00:00
/**
2009-07-09 07:35:03 +00:00
* Get the block record for a particular blockid - that is , a particul type os block .
2009-05-22 02:18:49 +00:00
*
* @ param $int blockid block type id . If null , an array of all block types is returned .
* @ param bool $notusedanymore No longer used .
2009-05-06 09:14:42 +00:00
* @ return array | object row from block table , or all rows .
*/
function blocks_get_record ( $blockid = NULL , $notusedanymore = false ) {
global $PAGE ;
$blocks = $PAGE -> blocks -> get_installed_blocks ();
if ( $blockid === NULL ) {
return $blocks ;
} else if ( isset ( $blocks [ $blockid ])) {
return $blocks [ $blockid ];
} else {
return false ;
2004-10-19 21:04:28 +00:00
}
}
2009-05-22 02:18:49 +00:00
/**
* Find a given block by its blockid within a provide array
*
* @ param int $blockid
* @ param array $blocksarray
* @ return bool | object Instance if found else false
*/
2004-10-19 21:04:28 +00:00
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 ;
}
2009-07-09 07:35:03 +00:00
// Functions for programatically adding default blocks to pages ================
2004-04-18 23:20:53 +00:00
2009-05-07 07:05:22 +00:00
/**
* Parse a list of default blocks . See config - dist for a description of the format .
2009-05-22 02:18:49 +00:00
*
2009-05-07 07:05:22 +00:00
* @ param string $blocksstr
* @ return array
*/
function blocks_parse_default_blocks_list ( $blocksstr ) {
2009-05-07 08:55:10 +00:00
$blocks = array ();
$bits = explode ( ':' , $blocksstr );
if ( ! empty ( $bits )) {
2009-08-28 08:47:31 +00:00
$leftbits = trim ( array_shift ( $bits ));
if ( $leftbits != '' ) {
$blocks [ BLOCK_POS_LEFT ] = explode ( ',' , $leftbits );
}
2009-05-07 08:55:10 +00:00
}
if ( ! empty ( $bits )) {
2009-08-28 08:47:31 +00:00
$rightbits = trim ( array_shift ( $bits ));
if ( $rightbits != '' ) {
$blocks [ BLOCK_POS_RIGHT ] = explode ( ',' , $rightbits );
}
2009-05-07 08:55:10 +00:00
}
return $blocks ;
2009-05-07 07:05:22 +00:00
}
2004-10-09 20:16:05 +00:00
2009-05-07 07:05:22 +00:00
/**
* @ return array the blocks that should be added to the site course by default .
*/
function blocks_get_default_site_course_blocks () {
global $CFG ;
2004-10-19 21:04:28 +00:00
2009-05-07 07:05:22 +00:00
if ( ! empty ( $CFG -> defaultblocks_site )) {
2009-05-07 08:55:10 +00:00
return blocks_parse_default_blocks_list ( $CFG -> defaultblocks_site );
2009-05-07 07:05:22 +00:00
} else {
2009-05-07 08:55:10 +00:00
return array (
2009-08-28 08:47:31 +00:00
BLOCK_POS_LEFT => array ( 'site_main_menu' ),
2009-05-07 07:05:22 +00:00
BLOCK_POS_RIGHT => array ( 'course_summary' , 'calendar_month' )
);
2004-10-19 21:04:28 +00:00
}
2009-05-07 07:05:22 +00:00
}
/**
* Add the default blocks to a course .
2009-05-22 02:18:49 +00:00
*
2009-05-07 07:05:22 +00:00
* @ param object $course a course object .
*/
function blocks_add_default_course_blocks ( $course ) {
global $CFG ;
if ( ! empty ( $CFG -> defaultblocks_override )) {
$blocknames = blocks_parse_default_blocks_list ( $CFG -> defaultblocks_override );
} else if ( $course -> id == SITEID ) {
$blocknames = blocks_get_default_site_course_blocks ();
} else {
$defaultblocks = 'defaultblocks_' . $course -> format ;
if ( ! empty ( $CFG -> $defaultblocks )) {
$blocknames = blocks_parse_default_blocks_list ( $CFG -> $defaultblocks );
} else {
2009-05-08 03:11:24 +00:00
$formatconfig = $CFG -> dirroot . '/course/format/' . $course -> format . '/config.php' ;
if ( is_readable ( $formatconfig )) {
2009-05-07 07:05:22 +00:00
require ( $formatconfig );
}
if ( ! empty ( $format [ 'defaultblocks' ])) {
$blocknames = blocks_parse_default_blocks_list ( $format [ 'defaultblocks' ]);
2004-10-19 21:04:28 +00:00
2009-05-07 07:05:22 +00:00
} else if ( ! empty ( $CFG -> defaultblocks )){
$blocknames = blocks_parse_default_blocks_list ( $CFG -> defaultblocks );
} else {
$blocknames = array (
2009-08-28 08:47:31 +00:00
BLOCK_POS_LEFT => array (),
BLOCK_POS_RIGHT => array ( 'search_forums' , 'news_items' , 'calendar_upcoming' , 'recent_activity' )
2009-05-07 07:05:22 +00:00
);
}
}
2004-10-19 21:04:28 +00:00
}
2009-05-07 08:55:10 +00:00
if ( $course -> id == SITEID ) {
$pagetypepattern = 'site-index' ;
} else {
$pagetypepattern = 'course-view-*' ;
}
2009-05-07 07:05:22 +00:00
$page = new moodle_page ();
$page -> set_course ( $course );
2009-05-07 08:55:10 +00:00
$page -> blocks -> add_blocks ( $blocknames , $pagetypepattern );
2009-05-07 07:05:22 +00:00
}
/**
* Add the default system - context blocks . E . g . the admin tree .
*/
function blocks_add_default_system_blocks () {
$page = new moodle_page ();
$page -> set_context ( get_context_instance ( CONTEXT_SYSTEM ));
2009-08-28 08:47:31 +00:00
$page -> blocks -> add_blocks ( array ( BLOCK_POS_LEFT => array ( 'global_navigation_tree' , 'settings_navigation_tree' )), '*' , null , true );
$page -> blocks -> add_blocks ( array ( BLOCK_POS_LEFT => array ( 'admin_bookmarks' )), 'admin-*' , null , null , 2 );
2009-05-07 07:05:22 +00:00
}