MDL-10107 Fixed the definition of message providers ... it now works through files...
[moodle.git] / lib / blocklib.php
1 <?php //$Id$
3 //This library includes all the necessary stuff to use blocks in course pages
5 define('BLOCK_MOVE_LEFT',   0x01);
6 define('BLOCK_MOVE_RIGHT',  0x02);
7 define('BLOCK_MOVE_UP',     0x04);
8 define('BLOCK_MOVE_DOWN',   0x08);
9 define('BLOCK_CONFIGURE',   0x10);
11 define('BLOCK_POS_LEFT',  'l');
12 define('BLOCK_POS_RIGHT', 'r');
14 define('BLOCKS_PINNED_TRUE',0);
15 define('BLOCKS_PINNED_FALSE',1);
16 define('BLOCKS_PINNED_BOTH',2);
18 require_once($CFG->libdir.'/pagelib.php');
19 require_once($CFG->dirroot.'/course/lib.php'); // needed to solve all those: Call to undefined function: print_recent_activity() when adding Recent Activity
21 // Returns false if this block is incompatible with the current version of Moodle.
22 function block_is_compatible($blockname) {
23     global $CFG;
25     $file = @file($CFG->dirroot.'/blocks/'.$blockname.'/block_'.$blockname.'.php'); // ignore errors when file does not exist
26     if(empty($file)) {
27         return NULL;
28     }
30     foreach($file as $line) {
31         // If you find MoodleBlock (appearing in the class declaration) it's not compatible
32         if(strpos($line, 'MoodleBlock')) {
33             return false;
34         }
35         // But if we find a { it means the class declaration is over, so it's compatible
36         else if(strpos($line, '{')) {
37             return true;
38         }
39     }
41     return NULL;
42 }
44 // Returns the case-sensitive name of the class' constructor function. This includes both
45 // PHP5- and PHP4-style constructors. If no appropriate constructor can be found, returns NULL.
46 // If there is no such class, returns boolean false.
47 function get_class_constructor($classname) {
48     // Caching
49     static $constructors = array();
51     if(!class_exists($classname)) {
52         return false;
53     }
55     // Tests indicate this doesn't hurt even in PHP5.
56     $classname = strtolower($classname);
58     // Return cached value, if exists
59     if(isset($constructors[$classname])) {
60         return $constructors[$classname];
61     }
63     // Get a list of methods. After examining several different ways of
64     // doing the check, (is_callable, method_exists, function_exists etc)
65     // it seems that this is the most reliable one.
66     $methods = get_class_methods($classname);
68     // PHP5 constructor?
69     if(phpversion() >= '5') {
70         if(in_array('__construct', $methods)) {
71             return $constructors[$classname] = '__construct';
72         }
73     }
75     // If we have PHP5 but no magic constructor, we have to lowercase the methods
76     $methods = array_map('strtolower', $methods);
78     if(in_array($classname, $methods)) {
79         return $constructors[$classname] = $classname;
80     }
82     return $constructors[$classname] = NULL;
83 }
85 //This function retrieves a method-defined property of a class WITHOUT instantiating an object
86 function block_method_result($blockname, $method, $param = NULL) {
87     if(!block_load_class($blockname)) {
88         return NULL;
89     }
90     return call_user_func(array('block_'.$blockname, $method), $param);
91 }
93 //This function creates a new object of the specified block class
94 function block_instance($blockname, $instance = NULL) {
95     if(!block_load_class($blockname)) {
96         return false;
97     }
98     $classname = 'block_'.$blockname;
99     $retval = new $classname;
100     if($instance !== NULL) {
101         $retval->_load_instance($instance);
102     }
103     return $retval;
106 //This function loads the necessary class files for a block
107 //Whenever you want to load a block, use this first
108 function block_load_class($blockname) {
109     global $CFG;
111     if(empty($blockname)) {
112         return false;
113     }
115     $classname = 'block_'.$blockname;
117     if(class_exists($classname)) {
118         return true;
119     }
121     require_once($CFG->dirroot.'/blocks/moodleblock.class.php');
122     @include_once($CFG->dirroot.'/blocks/'.$blockname.'/block_'.$blockname.'.php'); // do not throw errors if block code not present
124     return class_exists($classname);
127 // This function returns an array with the IDs of any blocks that you can add to your page.
128 // Parameters are passed by reference for speed; they are not modified at all.
129 function blocks_get_missing(&$page, &$pageblocks) {
131     $missingblocks = array();
132     $allblocks = blocks_get_record();
133     $pageformat = $page->get_format_name();
135     if(!empty($allblocks)) {
136         foreach($allblocks as $block) {
137             if($block->visible && (!blocks_find_block($block->id, $pageblocks) || $block->multiple)) {
138                 // And if it's applicable for display in this format...
139                 if(blocks_name_allowed_in_format($block->name, $pageformat)) {
140                     // ...add it to the missing blocks
141                     $missingblocks[] = $block->id;
142                 }
143             }
144         }
145     }
146     return $missingblocks;
149 function blocks_remove_inappropriate($page) {
150     $pageblocks = blocks_get_by_page($page);
152     if(empty($pageblocks)) {
153         return;
154     }
156     if(($pageformat = $page->get_format_name()) == NULL) {
157         return;
158     }
160     foreach($pageblocks as $position) {
161         foreach($position as $instance) {
162             $block = blocks_get_record($instance->blockid);
163             if(!blocks_name_allowed_in_format($block->name, $pageformat)) {
164                blocks_delete_instance($instance);
165             }
166         }
167     }
170 function blocks_name_allowed_in_format($name, $pageformat) {
172     $accept  = NULL;
173     $depth   = -1;
174     if ($formats = block_method_result($name, 'applicable_formats')) {
175         foreach($formats as $format => $allowed) {
176             $thisformat = '^'.str_replace('*', '[^-]*', $format).'.*$';
177             if(ereg($thisformat, $pageformat)) {
178                 if(($scount = substr_count($format, '-')) > $depth) {
179                     $depth  = $scount;
180                     $accept = $allowed;
181                 }
182             }
183         }
184     }
185     if($accept === NULL) {
186         $accept = !empty($formats['all']);
187     }
188     return $accept;
191 function blocks_delete_instance($instance,$pinned=false) {
192     global $DB;
194     // Get the block object and call instance_delete() if possible
195     if($record = blocks_get_record($instance->blockid)) {
196         if($obj = block_instance($record->name, $instance)) {
197             // Return value ignored
198             $obj->instance_delete();
199         }
200     }
202     if (!empty($pinned)) {
203          $DB->delete_records('block_pinned', array('id'=>$instance->id));
204         // And now, decrement the weight of all blocks after this one
205         $sql = "UPDATE {block_pinned}
206                    SET weight = weight - 1
207                  WHERE pagetype = ? AND position = ? AND weight > ?";
208         $params = array($instance->pagetype, $instance->position, $instance->weight);
209         $DB->execute($sql, $params);
210     } else {
211         // Now kill the db record;
212         $DB->delete_records('block_instance', array('id'=>$instance->id));
213         // And now, decrement the weight of all blocks after this one
214         $sql = "UPDATE {block_instance}
215                    SET weight = weight - 1
216                  WHERE pagetype = ? AND pageid = ?
217                        AND position = ? AND weight > ?";
218         $params = array($instance->pagetype, $instance->pageid, $instance->position, $instance->weight);
219         $DB->execute($sql, $params);
220     }
221     return true;
224 // Accepts an array of block instances and checks to see if any of them have content to display
225 // (causing them to calculate their content in the process). Returns true or false. Parameter passed
226 // by reference for speed; the array is actually not modified.
227 function blocks_have_content(&$pageblocks, $position) {
229     if (empty($pageblocks) || !is_array($pageblocks) || !array_key_exists($position,$pageblocks)) {
230         return false;
231     }
232     // use a for() loop to get references to the array elements
233     // foreach() cannot fetch references in PHP v4.x
234     for ($n=0; $n<count($pageblocks[$position]);$n++) {
235         $instance = &$pageblocks[$position][$n];
236         if (empty($instance->visible)) {
237             continue;
238         }
239         if(!$record = blocks_get_record($instance->blockid)) {
240             continue;
241         }
242         if(!$obj = block_instance($record->name, $instance)) {
243             continue;
244         }
245         if(!$obj->is_empty()) {
246             // cache rec and obj
247             // for blocks_print_group()
248             $instance->rec = $record;
249             $instance->obj = $obj;
250             return true;
251         }
252     }
254     return false;
257 // This function prints one group of blocks in a page
258 // Parameters passed by reference for speed; they are not modified.
259 function blocks_print_group(&$page, &$pageblocks, $position) {
260     global $COURSE, $CFG, $USER;
262     if (empty($pageblocks[$position])) {
263         $groupblocks = array();
264         $maxweight = 0;
265     } else {
266         $groupblocks = $pageblocks[$position];
267         $maxweight = max(array_keys($groupblocks));
268     }
271     foreach ($groupblocks as $instance) {
272         if (!empty($instance->pinned)) {
273             $maxweight--;
274         }
275     }
277     $isediting = $page->user_is_editing();
280     foreach($groupblocks as $instance) {
283         // $instance may have ->rec and ->obj
284         // cached from when we walked $pageblocks
285         // in blocks_have_content()
286         if (empty($instance->rec)) {
287             if (empty($instance->blockid)) {
288                 continue;   // Can't do anything
289             }
290             $block = blocks_get_record($instance->blockid);
291         } else {
292             $block = $instance->rec;
293         }
295         if (empty($block)) {
296             // Block doesn't exist! We should delete this instance!
297             continue;
298         }
300         if (empty($block->visible)) {
301             // Disabled by the admin
302             continue;
303         }
305         if (empty($instance->obj)) {
306             if (!$obj = block_instance($block->name, $instance)) {
307                 // Invalid block
308                 continue;
309             }
310         } else {
311             $obj = $instance->obj;
312         }
314         $editalways = $page->edit_always();
317         if (($isediting  && empty($instance->pinned)) || !empty($editalways)) {
318             $options = 0;
319             // 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:
320             // the first block might still be able to move up if the page says so (i.e., it will change position)
321             $options |= BLOCK_MOVE_UP    * ($instance->weight != 0          || ($page->blocks_move_position($instance, BLOCK_MOVE_UP)   != $instance->position));
322             // Same thing for downward movement
323             $options |= BLOCK_MOVE_DOWN  * ($instance->weight != $maxweight || ($page->blocks_move_position($instance, BLOCK_MOVE_DOWN) != $instance->position));
324             // For left and right movements, it's up to the page to tell us whether they are allowed
325             $options |= BLOCK_MOVE_RIGHT * ($page->blocks_move_position($instance, BLOCK_MOVE_RIGHT) != $instance->position);
326             $options |= BLOCK_MOVE_LEFT  * ($page->blocks_move_position($instance, BLOCK_MOVE_LEFT ) != $instance->position);
327             // Finally, the block can be configured if the block class either allows multiple instances, or if it specifically
328             // allows instance configuration (multiple instances override that one). It doesn't have anything to do with what the
329             // administrator has allowed for this block in the site admin options.
330             $options |= BLOCK_CONFIGURE * ( $obj->instance_allow_multiple() || $obj->instance_allow_config() );
331             $obj->_add_edit_controls($options);
332         }
334         if (!$instance->visible && empty($COURSE->javascriptportal)) {
335             if ($isediting) {
336                 $obj->_print_shadow();
337             }
338         } else {
339             global $COURSE;
340             if(!empty($COURSE->javascriptportal)) {
341                  $COURSE->javascriptportal->currentblocksection = $position;
342             }
343             $obj->_print_block();
344         }
345         if (!empty($COURSE->javascriptportal)
346                     && (empty($instance->pinned) || !$instance->pinned)) {
347             $COURSE->javascriptportal->block_add('inst'.$instance->id, !$instance->visible);
348         }
349     } // End foreach
351     //  Check if
352     //    we are on the default position/side AND
353     //    we're editing the page AND
354     //    (
355     //      we have the capability to manage blocks OR
356     //      we are in myMoodle page AND have the capibility to manage myMoodle blocks
357     //    )
359     // for constant PAGE_MY_MOODLE
360     include_once($CFG->dirroot.'/my/pagelib.php');
362     $coursecontext = get_context_instance(CONTEXT_COURSE, $COURSE->id);
363     $myownblogpage = (isset($page->filtertype) && isset($page->filterselect) && $page->type=='blog-view' && $page->filtertype=='user' && $page->filterselect == $USER->id);
365     $managecourseblocks = has_capability('moodle/site:manageblocks', $coursecontext);
366     $editmymoodle = $page->type == PAGE_MY_MOODLE && has_capability('moodle/my:manageblocks', $coursecontext);
368     if ($page->blocks_default_position() == $position &&
369         $page->user_is_editing() &&
370         ($managecourseblocks || $editmymoodle || $myownblogpage)) {
372         blocks_print_adminblock($page, $pageblocks);
373     }
376 // This iterates over an array of blocks and calculates the preferred width
377 // Parameter passed by reference for speed; it's not modified.
378 function blocks_preferred_width(&$instances) {
379     $width = 0;
381     if(empty($instances) || !is_array($instances)) {
382         return 0;
383     }
385     $blocks = blocks_get_record();
387     foreach($instances as $instance) {
388         if(!$instance->visible) {
389             continue;
390         }
392         if (!array_key_exists($instance->blockid, $blocks)) {
393             // Block doesn't exist! We should delete this instance!
394             continue;
395         }
397         if(!$blocks[$instance->blockid]->visible) {
398             continue;
399         }
400         $pref = block_method_result($blocks[$instance->blockid]->name, 'preferred_width');
401         if($pref === NULL) {
402             continue;
403         }
404         if($pref > $width) {
405             $width = $pref;
406         }
407     }
408     return $width;
411 function blocks_get_record($blockid = NULL, $invalidate = false) {
412     global $DB;
414     static $cache = NULL;
416     if($invalidate || empty($cache)) {
417         $cache = $DB->get_records('block');
418     }
420     if($blockid === NULL) {
421         return $cache;
422     }
424     return (isset($cache[$blockid])? $cache[$blockid] : false);
427 function blocks_find_block($blockid, $blocksarray) {
428     if (empty($blocksarray)) {
429         return false;
430     }
431     foreach($blocksarray as $blockgroup) {
432         if (empty($blockgroup)) {
433             continue;
434         }
435         foreach($blockgroup as $instance) {
436             if($instance->blockid == $blockid) {
437                 return $instance;
438             }
439         }
440     }
441     return false;
444 function blocks_find_instance($instanceid, $blocksarray) {
445     foreach($blocksarray as $subarray) {
446         foreach($subarray as $instance) {
447             if($instance->id == $instanceid) {
448                 return $instance;
449             }
450         }
451     }
452     return false;
455 // Simple entry point for anyone that wants to use blocks
456 function blocks_setup(&$PAGE,$pinned=BLOCKS_PINNED_FALSE) {
457     switch ($pinned) {
458     case BLOCKS_PINNED_TRUE:
459         $pageblocks = blocks_get_pinned($PAGE);
460         break;
461     case BLOCKS_PINNED_BOTH:
462         $pageblocks = blocks_get_by_page_pinned($PAGE);
463         break;
464     case BLOCKS_PINNED_FALSE:
465     default:
466         $pageblocks = blocks_get_by_page($PAGE);
467         break;
468     }
469     blocks_execute_url_action($PAGE, $pageblocks,($pinned==BLOCKS_PINNED_TRUE));
470     return $pageblocks;
473 function blocks_execute_action($page, &$pageblocks, $blockaction, $instanceorid, $pinned=false, $redirect=true) {
474     global $CFG, $USER, $DB;
476     if (is_int($instanceorid)) {
477         $blockid = $instanceorid;
478     } else if (is_object($instanceorid)) {
479         $instance = $instanceorid;
480     }
482     switch($blockaction) {
483         case 'config':
484             $block = blocks_get_record($instance->blockid);
485             // Hacky hacky tricky stuff to get the original human readable block title,
486             // even if the block has configured its title to be something else.
487             // Create the object WITHOUT instance data.
488             $blockobject = block_instance($block->name);
489             if ($blockobject === false) {
490                 break;
491             }
493             // First of all check to see if the block wants to be edited
494             if(!$blockobject->user_can_edit()) {
495                 break;
496             }
498             // Now get the title and AFTER that load up the instance
499             $blocktitle = $blockobject->get_title();
500             $blockobject->_load_instance($instance);
502             // Define the data we're going to silently include in the instance config form here,
503             // so we can strip them from the submitted data BEFORE serializing it.
504             $hiddendata = array(
505                 'sesskey' => $USER->sesskey,
506                 'instanceid' => $instance->id,
507                 'blockaction' => 'config'
508             );
510             // To this data, add anything the page itself needs to display
511             $hiddendata = array_merge($hiddendata, $page->url_get_parameters());
513             if ($data = data_submitted()) {
514                 $remove = array_keys($hiddendata);
515                 foreach($remove as $item) {
516                     unset($data->$item);
517                 }
518                 if(!$blockobject->instance_config_save($data, $pinned)) {
519                     print_error('cannotsaveblock');
520                 }
521                 // And nothing more, continue with displaying the page
522             }
523             else {
524                 // We need to show the config screen, so we highjack the display logic and then die
525                 $strheading = get_string('blockconfiga', 'moodle', $blocktitle);
526                 $page->print_header(get_string('pageheaderconfigablock', 'moodle'), array($strheading => ''));
528                 echo '<div class="block-config" id="'.$block->name.'">';   /// Make CSS easier
530                 print_heading($strheading);
531                 echo '<form method="post" name="block-config" action="'. $page->url_get_path() .'">';
532                 echo '<p>';
533                 foreach($hiddendata as $name => $val) {
534                     echo '<input type="hidden" name="'. $name .'" value="'. $val .'" />';
535                 }
536                 echo '</p>';
537                 $blockobject->instance_config_print();
538                 echo '</form>';
540                 echo '</div>';
541                 $CFG->pagepath = 'blocks/' . $block->name;
542                 print_footer();
543                 die(); // Do not go on with the other page-related stuff
544             }
545         break;
546         case 'toggle':
547             if(empty($instance))  {
548                 print_error('invalidblockinstance', '', '', $blockaction);
549             }
550             $instance->visible = ($instance->visible) ? 0 : 1;
551             if (!empty($pinned)) {
552                 $DB->update_record('block_pinned', $instance);
553             } else {
554                 $DB->update_record('block_instance', $instance);
555             }
556         break;
557         case 'delete':
558             if(empty($instance))  {
559                 print_error('invalidblockinstance', '', '', $blockaction);
560             }
561             blocks_delete_instance($instance, $pinned);
562         break;
563         case 'moveup':
564             if(empty($instance))  {
565                 print_error('invalidblockinstance', '', '', $blockaction);
566             }
568             if($instance->weight == 0) {
569                 // The block is the first one, so a move "up" probably means it changes position
570                 // Where is the instance going to be moved?
571                 $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_UP);
572                 $newweight = (empty($pageblocks[$newpos]) ? 0 : max(array_keys($pageblocks[$newpos])) + 1);
574                 blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
575             }
576             else {
577                 // The block is just moving upwards in the same position.
578                 // This configuration will make sure that even if somehow the weights
579                 // become not continuous, block move operations will eventually bring
580                 // the situation back to normal without printing any warnings.
581                 if(!empty($pageblocks[$instance->position][$instance->weight - 1])) {
582                     $other = $pageblocks[$instance->position][$instance->weight - 1];
583                 }
584                 if(!empty($other)) {
585                     ++$other->weight;
586                     if (!empty($pinned)) {
587                         $DB->update_record('block_pinned', $other);
588                     } else {
589                         $DB->update_record('block_instance', $other);
590                     }
591                 }
592                 --$instance->weight;
593                 if (!empty($pinned)) {
594                     $DB->update_record('block_pinned', $instance);
595                 } else {
596                     $DB->update_record('block_instance', $instance);
597                 }
598             }
599         break;
600         case 'movedown':
601             if(empty($instance))  {
602                 print_error('invalidblockinstance', '', '', $blockaction);
603             }
605             if($instance->weight == max(array_keys($pageblocks[$instance->position]))) {
606                 // The block is the last one, so a move "down" probably means it changes position
607                 // Where is the instance going to be moved?
608                 $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_DOWN);
609                 $newweight = (empty($pageblocks[$newpos]) ? 0 : max(array_keys($pageblocks[$newpos])) + 1);
611                 blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
612             }
613             else {
614                 // The block is just moving downwards in the same position.
615                 // This configuration will make sure that even if somehow the weights
616                 // become not continuous, block move operations will eventually bring
617                 // the situation back to normal without printing any warnings.
618                 if(!empty($pageblocks[$instance->position][$instance->weight + 1])) {
619                     $other = $pageblocks[$instance->position][$instance->weight + 1];
620                 }
621                 if(!empty($other)) {
622                     --$other->weight;
623                     if (!empty($pinned)) {
624                         $DB->update_record('block_pinned', $other);
625                     } else {
626                         $DB->update_record('block_instance', $other);
627                     }
628                 }
629                 ++$instance->weight;
630                 if (!empty($pinned)) {
631                     $DB->update_record('block_pinned', $instance);
632                 } else {
633                     $DB->update_record('block_instance', $instance);
634                 }
635             }
636         break;
637         case 'moveleft':
638             if(empty($instance))  {
639                 print_error('invalidblockinstance', '', '', $blockaction);
640             }
642             // Where is the instance going to be moved?
643             $newpos = $page->blocks_move_position($instance, BLOCK_MOVE_LEFT);
644             $newweight = (empty($pageblocks[$newpos]) ? 0 : max(array_keys($pageblocks[$newpos])) + 1);
646             blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
647         break;
648         case 'moveright':
649             if(empty($instance))  {
650                 print_error('invalidblockinstance', '', '', $blockaction);
651             }
653             // Where is the instance going to be moved?
654             $newpos    = $page->blocks_move_position($instance, BLOCK_MOVE_RIGHT);
655             $newweight = (empty($pageblocks[$newpos]) ? 0 : max(array_keys($pageblocks[$newpos])) + 1);
657             blocks_execute_repositioning($instance, $newpos, $newweight, $pinned);
658         break;
659         case 'add':
660             // Add a new instance of this block, if allowed
661             $block = blocks_get_record($blockid);
663             if(empty($block) || !$block->visible) {
664                 // Only allow adding if the block exists and is enabled
665                 break;
666             }
668             if(!$block->multiple && blocks_find_block($blockid, $pageblocks) !== false) {
669                 // If no multiples are allowed and we already have one, return now
670                 break;
671             }
673             if(!block_method_result($block->name, 'user_can_addto', $page)) {
674                 // If the block doesn't want to be added...
675                 break;
676             }
678             $newpos = $page->blocks_default_position();
679             if (!empty($pinned)) {
680                 $sql = "SELECT 1, MAX(weight) + 1 AS nextfree
681                           FROM {block_pinned}
682                          WHERE pagetype = ? AND position = ?";
683                 $params = array($page->get_type(), $newpos);
685             } else {
686                 $sql = "SELECT 1, MAX(weight) + 1 AS nextfree
687                           FROM {block_instance}
688                          WHERE pageid = ? AND pagetype = ? AND position = ?";
689                 $params = array($page->get_id(), $page->get_type(), $newpos);
690             }
691             $weight = $DB->get_record_sql($sql, $params);
693             $newinstance = new stdClass;
694             $newinstance->blockid    = $blockid;
695             if (empty($pinned)) {
696                 $newinstance->pageid = $page->get_id();
697             }
698             $newinstance->pagetype   = $page->get_type();
699             $newinstance->position   = $newpos;
700             $newinstance->weight     = empty($weight->nextfree) ? 0 : $weight->nextfree;
701             $newinstance->visible    = 1;
702             $newinstance->configdata = '';
703             if (!empty($pinned)) {
704                 $newinstance->id = $DB->insert_record('block_pinned', $newinstance);
705             } else {
706                 $newinstance->id = $DB->insert_record('block_instance', $newinstance);
707             }
709             // If the new instance was created, allow it to do additional setup
710             if($newinstance && ($obj = block_instance($block->name, $newinstance))) {
711                 // Return value ignored
712                 $obj->instance_create();
713             }
715         break;
716     }
718     if ($redirect) {
719         // In order to prevent accidental duplicate actions, redirect to a page with a clean url
720         redirect($page->url_get_full());
721     }
724 // You can use this to get the blocks to respond to URL actions without much hassle
725 function blocks_execute_url_action(&$PAGE, &$pageblocks,$pinned=false) {
726     $blockaction = optional_param('blockaction', '', PARAM_ALPHA);
728     if (empty($blockaction) || !$PAGE->user_allowed_editing() || !confirm_sesskey()) {
729         return;
730     }
732     $instanceid  = optional_param('instanceid', 0, PARAM_INT);
733     $blockid     = optional_param('blockid',    0, PARAM_INT);
735     if (!empty($blockid)) {
736         blocks_execute_action($PAGE, $pageblocks, strtolower($blockaction), $blockid, $pinned);
738     }
739     else if (!empty($instanceid)) {
740         $instance = blocks_find_instance($instanceid, $pageblocks);
741         blocks_execute_action($PAGE, $pageblocks, strtolower($blockaction), $instance, $pinned);
742     }
745 // This shouldn't be used externally at all, it's here for use by blocks_execute_action()
746 // in order to reduce code repetition.
747 function blocks_execute_repositioning(&$instance, $newpos, $newweight, $pinned=false) {
748     global $DB;
750     // If it's staying where it is, don't do anything, unless overridden
751     if ($newpos == $instance->position) {
752         return;
753     }
755     // Close the weight gap we 'll leave behind
756     if (!empty($pinned)) {
757         $sql = "UPDATE {block_instance}
758                    SET weight = weight - 1
759                  WHERE pagetype = ? AND position = ? AND weight > ?";
760         $params = array($instance->pagetype, $instance->position, $instance->weight);
762     } else {
763         $sql = "UPDATE {block_instance}
764                    SET weight = weight - 1
765                  WHERE pagetype = ? AND pageid = ?
766                        AND position = ? AND weight > ?";
767         $params = array($instance->pagetype, $instance->pageid, $instance->position, $instance->weight);
768     }
769     $DB->execute($sql, $params);
771     $instance->position = $newpos;
772     $instance->weight   = $newweight;
774     if (!empty($pinned)) {
775         $DB->update_record('block_pinned', $instance);
776     } else {
777         $DB->update_record('block_instance', $instance);
778     }
782 /**
783  * Moves a block to the new position (column) and weight (sort order).
784  * @param $instance - The block instance to be moved.
785  * @param $destpos - BLOCK_POS_LEFT or BLOCK_POS_RIGHT. The destination column.
786  * @param $destweight - The destination sort order. If NULL, we add to the end
787  *                      of the destination column.
788  * @param $pinned - Are we moving pinned blocks? We can only move pinned blocks
789  *                  to a new position withing the pinned list. Likewise, we
790  *                  can only moved non-pinned blocks to a new position within
791  *                  the non-pinned list.
792  * @return boolean (success or failure).
793  */
794 function blocks_move_block($page, &$instance, $destpos, $destweight=NULL, $pinned=false) {
795     global $CFG, $DB;
797     if ($pinned) {
798         $blocklist = blocks_get_pinned($page);
799     } else {
800         $blocklist = blocks_get_by_page($page);
801     }
803     if ($blocklist[$instance->position][$instance->weight]->id != $instance->id) {
804         // The source block instance is not where we think it is.
805         return false;
806     }
808     // First we close the gap that will be left behind when we take out the
809     // block from it's current column.
810     if ($pinned) {
811         $closegapsql = "UPDATE {block_instance}
812                            SET weight = weight - 1
813                          WHERE weight > ? AND position = ? AND pagetype = ?";
814         $params = array($instance->weight, $instance->position, $instance->pagetype);
815     } else {
816         $closegapsql = "UPDATE {block_instance}
817                            SET weight = weight - 1
818                          WHERE weight > ? AND position = ?
819                                AND pagetype = ? AND pageid = ?";
820         $params = array($instance->weight, $instance->position, $instance->pagetype, $instance->pageid);
821     }
822     if (!$DB->execute($closegapsql, $params)) {
823         return false;
824     }
826     // Now let's make space for the block being moved.
827     if ($pinned) {
828         $opengapsql = "UPDATE {block_instance}
829                            SET weight = weight + 1
830                          WHERE weight >= ? AND position = ? AND pagetype = ?";
831         $params = array($destweight, $destpos, $instance->pagetype);
832     } else {
833         $opengapsql = "UPDATE {block_instance}
834                           SET weight = weight + 1
835                         WHERE weight >= ? AND position = ?
836                               AND pagetype = ? AND pageid = ?";
837         $params = array($destweight, $destpos, $instance->pagetype, $instance->pageid);
838     }
839     if (!$DB->execute($opengapsql, $params)) {
840         return false;
841     }
843     // Move the block.
844     $instance->position = $destpos;
845     $instance->weight   = $destweight;
847     if ($pinned) {
848         $table = 'block_pinned';
849     } else {
850         $table = 'block_instance';
851     }
852     return $DB->update_record($table, $instance);
856 /**
857  * Returns an array consisting of 2 arrays:
858  * 1) Array of pinned blocks for position BLOCK_POS_LEFT
859  * 2) Array of pinned blocks for position BLOCK_POS_RIGHT
860  */
861 function blocks_get_pinned($page) {
862     global $DB;
864     $visible = true;
866     if (method_exists($page,'edit_always')) {
867         if ($page->edit_always()) {
868             $visible = false;
869         }
870     }
872     $select = "pagetype = ?";
873     $params = array($page->get_type());
875      if ($visible) {
876         $select .= " AND visible = 1";
877      }
879     $blocks = $DB->get_records_select('block_pinned', $select, $params, 'position, weight');
881     $positions = $page->blocks_get_positions();
882     $arr = array();
884     foreach($positions as $key => $position) {
885         $arr[$position] = array();
886     }
888     if(empty($blocks)) {
889         return $arr;
890     }
892     foreach($blocks as $block) {
893         $block->pinned = true; // so we know we can't move it.
894         // make up an instanceid if we can..
895         $block->pageid = $page->get_id();
896         $arr[$block->position][$block->weight] = $block;
897     }
899     return $arr;
903 /**
904  * Similar to blocks_get_by_page(), except that, the array returned includes
905  * pinned blocks as well. Pinned blocks are always appended before normal
906  * block instances.
907  */
908 function blocks_get_by_page_pinned($page) {
909     $pinned = blocks_get_pinned($page);
910     $user = blocks_get_by_page($page);
912     $weights = array();
914     foreach ($pinned as $pos => $arr) {
915         $weights[$pos] = count($arr);
916     }
918     foreach ($user as $pos => $blocks) {
919         if (!array_key_exists($pos,$pinned)) {
920              $pinned[$pos] = array();
921         }
922         if (!array_key_exists($pos,$weights)) {
923             $weights[$pos] = 0;
924         }
925         foreach ($blocks as $block) {
926             $pinned[$pos][$weights[$pos]] = $block;
927             $weights[$pos]++;
928         }
929     }
930     return $pinned;
934 /**
935  * Returns an array of blocks for the page. Pinned blocks are excluded.
936  */
937 function blocks_get_by_page($page) {
938     global $DB;
940     $blocks = $DB->get_records_select('block_instance', "pageid = ? AND pagetype = ?", array($page->get_id(), $page->get_type()),
941                                       'position, weight');
943     $positions = $page->blocks_get_positions();
944     $arr = array();
945     foreach($positions as $key => $position) {
946         $arr[$position] = array();
947     }
949     if(empty($blocks)) {
950         return $arr;
951     }
953     foreach($blocks as $block) {
954         $arr[$block->position][$block->weight] = $block;
955     }
956     return $arr;
960 //This function prints the block to admin blocks as necessary
961 function blocks_print_adminblock(&$page, &$pageblocks) {
962     global $USER;
964     $missingblocks = blocks_get_missing($page, $pageblocks);
966     if (!empty($missingblocks)) {
967         $strblocks = '<div class="title"><h2>';
968         $strblocks .= get_string('blocks');
969         $strblocks .= '</h2>';
970         $stradd    = get_string('add');
971         foreach ($missingblocks as $blockid) {
972             $block = blocks_get_record($blockid);
973             $blockobject = block_instance($block->name);
974             if ($blockobject === false) {
975                 continue;
976             }
977             if(!$blockobject->user_can_addto($page)) {
978                 continue;
979             }
980             $menu[$block->id] = $blockobject->get_title();
981         }
982         asort($menu);
984         $target = $page->url_get_full(array('sesskey' => $USER->sesskey, 'blockaction' => 'add'));
985         $content = popup_form($target.'&amp;blockid=', $menu, 'add_block', '', $stradd .'...', '', '', true);
986         print_side_block($strblocks, $content, NULL, NULL, NULL, array('class' => 'block_adminblock'));
987     }
990 function blocks_repopulate_page($page) {
991     global $CFG, $DB;
993     $allblocks = blocks_get_record();
995     if(empty($allblocks)) {
996         print_error('cannotgetblock');
997     }
999     // Assemble the information to correlate block names to ids
1000     $idforname = array();
1001     foreach($allblocks as $block) {
1002         $idforname[$block->name] = $block->id;
1003     }
1005     /// If the site override has been defined, it is the only valid one.
1006     if (!empty($CFG->defaultblocks_override)) {
1007         $blocknames = $CFG->defaultblocks_override;
1008     }
1009     else {
1010         $blocknames = $page->blocks_get_default();
1011     }
1013     $positions = $page->blocks_get_positions();
1014     $posblocks = explode(':', $blocknames);
1016     // Now one array holds the names of the positions, and the other one holds the blocks
1017     // that are going to go in each position. Luckily for us, both arrays are numerically
1018     // indexed and the indexes match, so we can work straight away... but CAREFULLY!
1020     // Ready to start creating block instances, but first drop any existing ones
1021     $DB->delete_records('block_instance', array('pageid'=>$page->get_id(), 'pagetype'=>$page->get_type()));
1023     // Here we slyly count $posblocks and NOT $positions. This can actually make a difference
1024     // if the textual representation has undefined slots in the end. So we only work with as many
1025     // positions were retrieved, not with all the page says it has available.
1026     $numpositions = count($posblocks);
1027     for($i = 0; $i < $numpositions; ++$i) {
1028         $position = $positions[$i];
1029         $blocknames = explode(',', $posblocks[$i]);
1030         $weight = 0;
1031         foreach($blocknames as $blockname) {
1032             $newinstance = new stdClass;
1033             $newinstance->blockid    = $idforname[$blockname];
1034             $newinstance->pageid     = $page->get_id();
1035             $newinstance->pagetype   = $page->get_type();
1036             $newinstance->position   = $position;
1037             $newinstance->weight     = $weight;
1038             $newinstance->visible    = 1;
1039             $newinstance->configdata = '';
1041             if(!empty($newinstance->blockid)) {
1042                 // Only add block if it was recognized
1043                 $DB->insert_record('block_instance', $newinstance);
1044                 ++$weight;
1045             }
1046         }
1047     }
1049     return true;
1052 function upgrade_blocks_db($continueto) {
1053 /// This function upgrades the blocks tables, if necessary
1054 /// It's called from admin/index.php
1056     global $CFG, $interactive, $DB;
1058     require_once ($CFG->dirroot .'/blocks/version.php');  // Get code versions
1060     if (empty($CFG->blocks_version)) {                  // Blocks have never been installed.
1061         $strdatabaseupgrades = get_string('databaseupgrades');
1062         if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1063         print_header($strdatabaseupgrades, $strdatabaseupgrades,
1064                 build_navigation(array(array('name' => $strdatabaseupgrades, 'link' => null, 'type' => 'misc'))), '',
1065                 upgrade_get_javascript(), false, '&nbsp;', '&nbsp;');
1066         }
1067         upgrade_log_start();
1068         print_heading('blocks');
1069         if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1070         $DB->set_debug(true);
1071         }
1072     /// Both old .sql files and new install.xml are supported
1073     /// but we priorize install.xml (XMLDB) if present
1074         $DB->get_manager()->install_from_xmldb_file($CFG->dirroot . '/blocks/db/install.xml'); //New method
1075         $status = true;
1076         if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1077         $DB->set_debug(false);
1078         }
1079         if ($status) {
1080             if (set_config('blocks_version', $blocks_version)) {
1081                 notify(get_string('databasesuccess'), 'notifysuccess');
1082                 notify(get_string('databaseupgradeblocks', '', $blocks_version), 'notifysuccess');
1083                 if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1084                 print_continue($continueto);
1085                 print_footer('none');
1086                 exit;
1087                 } else if (CLI_UPGRADE && ($interactive > CLI_SEMI) ) {
1088                     console_write(STDOUT,'askcontinue');
1089                     if (read_boolean()){
1090                         return ;
1091                     }else {
1092                         console_write(STDERR,'','',false);
1093                     }
1094                 }
1095             } else {
1096                 print_error('cannotupgradeblock');
1097             }
1098         } else {
1099             print_error('cannotsetupblock');
1100         }
1101     }
1103 /// Upgrading code starts here
1104     $newupgrade = false;
1105     if (is_readable($CFG->dirroot . '/blocks/db/upgrade.php')) {
1106         include_once($CFG->dirroot . '/blocks/db/upgrade.php');  // defines new upgrading function
1107         $newupgrade = true;
1108     }
1110     if ($blocks_version > $CFG->blocks_version) {       // Upgrade tables
1111         $strdatabaseupgrades = get_string('databaseupgrades');
1112         if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1113         print_header($strdatabaseupgrades, $strdatabaseupgrades,
1114                 build_navigation(array(array('name' => $strdatabaseupgrades, 'link' => null, 'type' => 'misc'))), '', upgrade_get_javascript());
1115         }
1116         upgrade_log_start();
1118         print_heading('blocks');
1120     /// Run de old and new upgrade functions for the module
1121         $newupgrade_function = 'xmldb_blocks_upgrade';
1123     /// Then, the new function if exists and the old one was ok
1124         $newupgrade_status = true;
1125         if ($newupgrade && function_exists($newupgrade_function)) {
1126             if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1127                 $DB->set_debug(true);
1128             }
1129             $newupgrade_status = $newupgrade_function($CFG->blocks_version);
1130         } else if ($newupgrade) {
1131             notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
1132                      '/blocks/db/upgrade.php');
1133         }
1134         if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1135             $DB->set_debug(false);
1136         }
1137     /// Now analyze upgrade results
1138         if ($newupgrade_status) {    // No upgrading failed
1139             if (set_config('blocks_version', $blocks_version)) {
1140                 notify(get_string('databasesuccess'), 'notifysuccess');
1141                 notify(get_string('databaseupgradeblocks', '', $blocks_version), 'notifysuccess');
1142                 if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1143                 print_continue($continueto);
1144                 print_footer('none');
1145                 exit;
1146                 }
1147             } else {
1148                 print_error('cannotupgradeblock');
1149             }
1150         } else {
1151             print_error('cannotupgradeblock');
1152         }
1154     } else if ($blocks_version < $CFG->blocks_version) {
1155         upgrade_log_start();
1156         notify('WARNING!!!  The Blocks version you are using is OLDER than the version that made these databases!');
1157     }
1158     upgrade_log_finish();
1161 //This function finds all available blocks and install them
1162 //into blocks table or do all the upgrade process if newer
1163 function upgrade_blocks_plugins($continueto) {
1164     global $CFG, $interactive, $DB;
1166     $blocktitles = array();
1167     $invalidblocks = array();
1168     $validblocks = array();
1169     $notices = array();
1171     //Count the number of blocks in db
1172     $blockcount = $DB->count_records('block');
1173     //If there isn't records. This is the first install, so I remember it
1174     if ($blockcount == 0) {
1175         $first_install = true;
1176     } else {
1177         $first_install = false;
1178     }
1180     $site = get_site();
1182     if (!$blocks = get_list_of_plugins('blocks', 'db') ) {
1183         print_error('noblocks', 'debug');
1184     }
1186     include_once($CFG->dirroot .'/blocks/moodleblock.class.php');
1187     if(!class_exists('block_base')) {
1188         print_error('noblockbase');
1189     }
1191     foreach ($blocks as $blockname) {
1193         if ($blockname == 'NEWBLOCK') {   // Someone has unzipped the template, ignore it
1194             continue;
1195         }
1197         if(!block_is_compatible($blockname)) {
1198             // This is an old-style block
1199             //$notices[] = 'Block '. $blockname .' is not compatible with the current version of Mooodle and needs to be updated by a programmer.';
1200             $invalidblocks[] = $blockname;
1201             continue;
1202         }
1204         $fullblock = $CFG->dirroot .'/blocks/'. $blockname;
1206         if ( is_readable($fullblock.'/block_'.$blockname.'.php')) {
1207             include_once($fullblock.'/block_'.$blockname.'.php');
1208         } else {
1209             $notices[] = 'Block '. $blockname .': '. $fullblock .'/block_'. $blockname .'.php was not readable';
1210             continue;
1211         }
1213         $newupgrade = false;
1214         if ( @is_dir($fullblock .'/db/')) {
1215             if ( @is_readable($fullblock .'/db/upgrade.php')) {
1216                 include_once($fullblock .'/db/upgrade.php');  // defines new upgrading function
1217                 $newupgrade = true;
1218             }
1219         }
1221         $classname = 'block_'.$blockname;
1222         if(!class_exists($classname)) {
1223             $notices[] = 'Block '. $blockname .': '. $classname .' not implemented';
1224             continue;
1225         }
1227         // Here is the place to see if the block implements a constructor (old style),
1228         // an init() function (new style) or nothing at all (error time).
1230         $constructor = get_class_constructor($classname);
1231         if(empty($constructor)) {
1232             // No constructor
1233             $notices[] = 'Block '. $blockname .': class does not have a constructor';
1234             $invalidblocks[] = $blockname;
1235             continue;
1236         }
1238         $block    = new stdClass;     // This may be used to update the db below
1239         $blockobj = new $classname;   // This is what we 'll be testing
1241         // Inherits from block_base?
1242         if(!is_subclass_of($blockobj, 'block_base')) {
1243             $notices[] = 'Block '. $blockname .': class does not inherit from block_base';
1244             continue;
1245         }
1247         // OK, it's as we all hoped. For further tests, the object will do them itself.
1248         if(!$blockobj->_self_test()) {
1249             $notices[] = 'Block '. $blockname .': self test failed';
1250             continue;
1251         }
1252         $block->version = $blockobj->get_version();
1254         if (!isset($block->version)) {
1255             $notices[] = 'Block '. $blockname .': has no version support. It must be updated by a programmer.';
1256             continue;
1257         }
1259         $block->name = $blockname;   // The name MUST match the directory
1260         $blocktitle = $blockobj->get_title();
1262         if ($currblock = $DB->get_record('block', array('name'=>$block->name))) {
1263             if ($currblock->version == $block->version) {
1264                 // do nothing
1265             } else if ($currblock->version < $block->version) {
1266                 if (empty($updated_blocks)) {
1267                     $strblocksetup    = get_string('blocksetup');
1268                     if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1269                     print_header($strblocksetup, $strblocksetup,
1270                             build_navigation(array(array('name' => $strblocksetup, 'link' => null, 'type' => 'misc'))), '',
1271                             upgrade_get_javascript(), false, '&nbsp;', '&nbsp;');
1272                     }
1273                 }
1274                 $updated_blocks = true;
1275                 upgrade_log_start();
1277                 print_heading('New version of '.$blocktitle.' ('.$block->name.') exists');
1278                 @set_time_limit(0);  // To allow slow databases to complete the long SQL
1280             /// Run de old and new upgrade functions for the module
1281                 $newupgrade_function = 'xmldb_block_' . $block->name .'_upgrade';
1283             /// Then, the new function if exists and the old one was ok
1284                 $newupgrade_status = true;
1285                 if ($newupgrade && function_exists($newupgrade_function)) {
1286                     if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1287                         $DB->set_debug(true);
1288                     }
1289                     $newupgrade_status = $newupgrade_function($currblock->version, $block);
1290                 } else if ($newupgrade) {
1291                     notify ('Upgrade function ' . $newupgrade_function . ' was not available in ' .
1292                              $fullblock . '/db/upgrade.php');
1293                 }
1294                 if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1295                     $DB->set_debug(false);
1296                 }
1297             /// Now analyze upgrade results
1298                 if ($newupgrade_status) {    // No upgrading failed
1300                     // Set the block cron on upgrade
1301                     $block->cron = !empty($blockobj->cron) ? $blockobj->cron : 0;
1303                     // OK so far, now update the block record
1304                     $block->id = $currblock->id;
1305                     if (!$DB->update_record('block', $block)) {
1306                         print_error('cannotupdateblock', '', '', $block->name);
1307                     }
1308                     $component = 'block/'.$block->name;
1309                     if (!update_capabilities($component)) {
1310                         print_error('nopermissiontoupdateblock', '', '', $block->name);
1311                     }
1313                     // Update events
1314                     events_update_definition($component);
1316                     // Update message providers
1317                     require_once($CFG->libdir .'/messagelib.php');      // Messagelib functions
1318                     message_update_providers($component);
1320                     notify(get_string('blocksuccess', '', $blocktitle), 'notifysuccess');
1321                 } else {
1322                     notify('Upgrading block '. $block->name .' from '. $currblock->version .' to '. $block->version .' FAILED!');
1323                 }
1324                 if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1325                 echo '<hr />';
1326                 }
1327             } else {
1328                 upgrade_log_start();
1329                 print_error('cannotdowngrade', 'debug', '', array($currblock->version, $block->version));
1330             }
1332         } else {    // block not installed yet, so install it
1334             // If it allows multiples, start with it enabled
1335             if ($blockobj->instance_allow_multiple()) {
1336                 $block->multiple = 1;
1337             }
1339             // Set the block cron on install
1340             $block->cron = !empty($blockobj->cron) ? $blockobj->cron : 0;
1342             // [pj] Normally this would be inline in the if, but we need to
1343             //      check for NULL (necessary for 4.0.5 <= PHP < 4.2.0)
1344             $conflictblock = array_search($blocktitle, $blocktitles);
1345             if($conflictblock !== false && $conflictblock !== NULL) {
1346                 // Duplicate block titles are not allowed, they confuse people
1347                 // AND PHP's associative arrays ;)
1348                 if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1349                     print_error('blocknameconflict', '', '', array($block->name, $conflictblock));
1350                 } else if (CLI_UPGRADE) {
1351                     print_error('blocknameconflict', '', '', array($block->name, $conflictblock));
1352                 }
1353             }
1354             if (empty($updated_blocks)) {
1355                 $strblocksetup    = get_string('blocksetup');
1356                 if (!defined('CLI_UPGRADE') || !CLI_UPGRADE) {
1357                 print_header($strblocksetup, $strblocksetup,
1358                         build_navigation(array(array('name' => $strblocksetup, 'link' => null, 'type' => 'misc'))), '',
1359                         upgrade_get_javascript(), false, '&nbsp;', '&nbsp;');
1360             }
1361             }
1362             $updated_blocks = true;
1363             upgrade_log_start();
1364             print_heading($block->name);
1365             if (!defined('CLI_UPGRADE')||!CLI_UPGRADE) {
1366                 $DB->set_debug(true);
1367             }
1368             @set_time_limit(0);  // To allow slow databases to complete the long SQL
1370         /// Both old .sql files and new install.xml are supported
1371         /// but we priorize install.xml (XMLDB) if present
1372             if (file_exists($fullblock . '/db/install.xml')) {
1373                 $DB->get_manager()->install_from_xmldb_file($fullblock . '/db/install.xml'); //New method
1374             }
1375             $status = true;
1376             if (!defined('CLI_UPGRADE') || !CLI_UPGRADE ) {
1377                 $DB->set_debug(false);
1378             }
1379             if ($status) {
1380                 if ($block->id = $DB->insert_record('block', $block)) {
1381                     $blockobj->after_install();
1382                     $component = 'block/'.$block->name;
1383                     if (!update_capabilities($component)) {
1384                         notify('Could not set up '.$block->name.' capabilities!');
1385                     }
1387                     // Update events
1388                     events_update_definition($component);
1390                     // Update message providers
1391                     require_once($CFG->libdir .'/messagelib.php');      // Messagelib functions
1392                     message_update_providers($component);
1394                     notify(get_string('blocksuccess', '', $blocktitle), 'notifysuccess');
1395                     if (!defined('CLI_UPGRADE')|| !CLI_UPGRADE) {
1396                     echo '<hr />';
1397                     }
1398                 } else {
1399                     print_error('cannotaddblock', '', '', $block->name);
1400                 }
1401             } else {
1402                 print_error('cannotsetupblock', '', '', $block->name);
1403             }
1404         }
1406         $blocktitles[$block->name] = $blocktitle;
1407     }
1409     if(!empty($notices)) {
1410         upgrade_log_start();
1411         foreach($notices as $notice) {
1412             notify($notice);
1413         }
1414     }
1416     // Finally, if we are in the first_install of BLOCKS (this means that we are
1417     // upgrading from Moodle < 1.3), put blocks in all existing courses.
1418     if ($first_install) {
1419         upgrade_log_start();
1420         //Iterate over each course
1421         if ($courses = $DB->get_records('course')) {
1422             foreach ($courses as $course) {
1423                 $page = page_create_object(PAGE_COURSE_VIEW, $course->id);
1424                 blocks_repopulate_page($page);
1425             }
1426         }
1427     }
1429     if (!empty($CFG->siteblocksadded)) {     /// This is a once-off hack to make a proper upgrade
1430         upgrade_log_start();
1431         $page = page_create_object(PAGE_COURSE_VIEW, SITEID);
1432         blocks_repopulate_page($page);
1433         $DB->delete_records('config', array('name'=>'siteblocksadded'));
1434     }
1436     upgrade_log_finish();
1438     if (!empty($updated_blocks)) {
1439         if (!defined('CLI_UPGRADE') || !CLI_UPGRADE) {
1440         print_continue($continueto);
1441         print_footer('none');
1442         die;
1443         } else if ( CLI_UPGRADE && ($interactive > CLI_SEMI) ) {
1444             console_write(STDOUT,'askcontinue');
1445             if (read_boolean()){
1446                 return ;
1447             }else {
1448                 console_write(STDERR,'','',false);
1449             }
1450         }
1451     }
1454 ?>