| [ Index ] |
PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008] |
[Summary view] [Print] [Text view]
1 <?php // $Id: moodleblock.class.php,v 1.92.2.9 2008/08/06 05:08:36 skodak Exp $ 2 3 /** 4 * This file contains the parent class for moodle blocks, block_base. 5 * 6 * @author Jon Papaioannou 7 * @version $Id: moodleblock.class.php,v 1.92.2.9 2008/08/06 05:08:36 skodak Exp $ 8 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License 9 * @package blocks 10 */ 11 12 /// Constants 13 14 /** 15 * Block type of list. Contents of block should be set as an associative array in the content object as items ($this->content->items). Optionally include footer text in $this->content->footer. 16 */ 17 define('BLOCK_TYPE_LIST', 1); 18 19 /** 20 * Block type of text. Contents of block should be set to standard html text in the content object as items ($this->content->text). Optionally include footer text in $this->content->footer. 21 */ 22 define('BLOCK_TYPE_TEXT', 2); 23 24 /** 25 * Class for describing a moodle block, all Moodle blocks derive from this class 26 * 27 * @author Jon Papaioannou 28 * @package blocks 29 */ 30 class block_base { 31 32 /** 33 * Internal var for storing/caching translated strings 34 * @var string $str 35 */ 36 var $str; 37 38 /** 39 * The title of the block to be displayed in the block title area. 40 * @var string $title 41 */ 42 var $title = NULL; 43 44 /** 45 * The type of content that this block creates. Currently support options - BLOCK_TYPE_LIST, BLOCK_TYPE_TEXT 46 * @var int $content_type 47 */ 48 var $content_type = BLOCK_TYPE_TEXT; 49 50 /** 51 * An object to contain the information to be displayed in the block. 52 * @var stdObject $content 53 */ 54 var $content = NULL; 55 56 /** 57 * A string generated by {@link _add_edit_controls()} to display block manipulation links when the user is in editing mode. 58 * @var string $edit_controls 59 */ 60 var $edit_controls = NULL; 61 62 /** 63 * The current version that the block type defines. 64 * @var string $version 65 */ 66 var $version = NULL; 67 68 /** 69 * The initialized instance of this block object. 70 * @var block $instance 71 */ 72 var $instance = NULL; 73 74 /** 75 * An object containing the instance configuration information for the current instance of this block. 76 * @var stdObject $config 77 */ 78 var $config = NULL; 79 80 /** 81 * How often the cronjob should run, 0 if not at all. 82 * @var int $cron 83 */ 84 85 var $cron = NULL; 86 87 /** 88 * Indicates blocked is pinned - can not be moved, always present, does not have own context 89 */ 90 var $pinned = false; 91 92 /// Class Functions 93 94 /** 95 * The class constructor 96 * 97 */ 98 function block_base() { 99 $this->init(); 100 } 101 102 /** 103 * Fake constructor to keep PHP5 happy 104 * 105 */ 106 function __construct() { 107 $this->block_base(); 108 } 109 110 /** 111 * Function that can be overridden to do extra setup after 112 * the database install. (Called once per block, not per instance!) 113 */ 114 function after_install() { 115 } 116 117 /** 118 * Function that can be overridden to do extra cleanup before 119 * the database tables are deleted. (Called once per block, not per instance!) 120 */ 121 function before_delete() { 122 } 123 124 /** 125 * Function that can be overridden to do extra setup after a block instance has been 126 * restored from backup. For example, it may need to alter any dates that the block 127 * stores, if the $restore->course_startdateoffset is set. 128 */ 129 function after_restore($restore) { 130 } 131 132 /** 133 * Enable custom instance data section in backup and restore. 134 * 135 * If return true, then {@link instance_backup()} and 136 * {@link instance_restore()} will be called during 137 * backup/restore routines. 138 * 139 * @return boolean 140 **/ 141 function backuprestore_instancedata_used() { 142 return false; 143 } 144 145 /** 146 * Allows the block class to have a backup routine. Handy 147 * when the block has its own tables that have foreign keys to 148 * other tables (example: user table). 149 * 150 * Note: at the time of writing this comment, the indent level 151 * for the {@link full_tag()} should start at 5. 152 * 153 * @param resource $bf Backup File 154 * @param object $preferences Backup preferences 155 * @return boolean 156 **/ 157 function instance_backup($bf, $preferences) { 158 return true; 159 } 160 161 /** 162 * Allows the block class to restore its backup routine. 163 * 164 * Should not return false if data is empty 165 * because old backups would not contain block instance backup data. 166 * 167 * @param object $restore Standard restore object 168 * @param object $data Object from backup_getid for this block instance 169 * @return boolean 170 **/ 171 function instance_restore($restore, $data) { 172 return true; 173 } 174 175 /** 176 * Will be called before an instance of this block is backed up, so that any links in 177 * in config can be encoded. For example config->text, for the HTML block 178 * @return string 179 */ 180 function get_backup_encoded_config() { 181 return base64_encode(serialize($this->config)); 182 } 183 184 /** 185 * Return the content encoded to support interactivities linking. This function is 186 * called automatically from the backup procedure by {@link backup_encode_absolute_links()}. 187 * 188 * NOTE: There is no block instance when this method is called. 189 * 190 * @param string $content Content to be encoded 191 * @param object $restore Restore preferences object 192 * @return string The encoded content 193 **/ 194 function encode_content_links($content, $restore) { 195 return $content; 196 } 197 198 /** 199 * This function makes all the necessary calls to {@link restore_decode_content_links_worker()} 200 * function in order to decode contents of this block from the backup 201 * format to destination site/course in order to mantain inter-activities 202 * working in the backup/restore process. 203 * 204 * This is called from {@link restore_decode_content_links()} function in the restore process. 205 * 206 * NOTE: There is no block instance when this method is called. 207 * 208 * @param object $restore Standard restore object 209 * @return boolean 210 **/ 211 function decode_content_links_caller($restore) { 212 return true; 213 } 214 215 /** 216 * Return content decoded to support interactivities linking. 217 * This is called automatically from 218 * {@link restore_decode_content_links_worker()} function 219 * in the restore process. 220 * 221 * NOTE: There is no block instance when this method is called. 222 * 223 * @param string $content Content to be dencoded 224 * @param object $restore Restore preferences object 225 * @return string The dencoded content 226 **/ 227 function decode_content_links($content, $restore) { 228 return $content; 229 } 230 231 /** 232 * Returns the block name, as present in the class name, 233 * the database, the block directory, etc etc. 234 * 235 * @return string 236 */ 237 function name() { 238 // Returns the block name, as present in the class name, 239 // the database, the block directory, etc etc. 240 static $myname; 241 if ($myname === NULL) { 242 $myname = strtolower(get_class($this)); 243 $myname = substr($myname, strpos($myname, '_') + 1); 244 } 245 return $myname; 246 } 247 248 /** 249 * Parent class version of this function simply returns NULL 250 * This should be implemented by the derived class to return 251 * the content object. 252 * 253 * @return stdObject 254 */ 255 function get_content() { 256 // This should be implemented by the derived class. 257 return NULL; 258 } 259 260 /** 261 * Returns the class $title var value. 262 * 263 * Intentionally doesn't check if a title is set. 264 * This is already done in {@link _self_test()} 265 * 266 * @return string $this->title 267 */ 268 function get_title() { 269 // Intentionally doesn't check if a title is set. This is already done in _self_test() 270 return $this->title; 271 } 272 273 /** 274 * Returns the class $content_type var value. 275 * 276 * Intentionally doesn't check if content_type is set. 277 * This is already done in {@link _self_test()} 278 * 279 * @return string $this->content_type 280 */ 281 function get_content_type() { 282 // Intentionally doesn't check if a content_type is set. This is already done in _self_test() 283 return $this->content_type; 284 } 285 286 /** 287 * Returns the class $version var value. 288 * 289 * Intentionally doesn't check if a version is set. 290 * This is already done in {@link _self_test()} 291 * 292 * @return string $this->version 293 */ 294 function get_version() { 295 // Intentionally doesn't check if a version is set. This is already done in _self_test() 296 return $this->version; 297 } 298 299 /** 300 * Returns true or false, depending on whether this block has any content to display 301 * and whether the user has permission to view the block 302 * 303 * @return boolean 304 */ 305 function is_empty() { 306 307 if (empty($this->instance->pinned)) { 308 $context = get_context_instance(CONTEXT_BLOCK, $this->instance->id); 309 } else { 310 $context = get_context_instance(CONTEXT_SYSTEM); // pinned blocks do not have own context 311 } 312 313 if ( !has_capability('moodle/block:view', $context) ) { 314 return true; 315 } 316 317 $this->get_content(); 318 return(empty($this->content->text) && empty($this->content->footer)); 319 } 320 321 /** 322 * First sets the current value of $this->content to NULL 323 * then calls the block's {@link get_content()} function 324 * to set its value back. 325 * 326 * @return stdObject 327 */ 328 function refresh_content() { 329 // Nothing special here, depends on content() 330 $this->content = NULL; 331 return $this->get_content(); 332 } 333 334 /** 335 * Display the block! 336 */ 337 function _print_block() { 338 global $COURSE; 339 340 // is_empty() includes a call to get_content() 341 if ($this->is_empty() && empty($COURSE->javascriptportal)) { 342 if (empty($this->edit_controls)) { 343 // No content, no edit controls, so just shut up 344 return; 345 } else { 346 // No content but editing, so show something at least 347 $this->_print_shadow(); 348 } 349 } else { 350 if ($this->hide_header() && empty($this->edit_controls)) { 351 // Header wants to hide, no edit controls to show, so no header it is 352 print_side_block(NULL, $this->content->text, NULL, NULL, $this->content->footer, $this->html_attributes()); 353 } else { 354 // The full treatment, please. Include the title text. 355 print_side_block($this->_title_html(), $this->content->text, NULL, NULL, $this->content->footer, $this->html_attributes(), $this->title); 356 } 357 } 358 } 359 360 /** 361 * Block contents are missing. Simply display an empty block so that 362 * edit controls are accessbile to the user and they are aware that this 363 * block is in place, even if empty. 364 */ 365 function _print_shadow() { 366 print_side_block($this->_title_html(), ' ', NULL, NULL, '', array('class' => 'hidden'), $this->title); 367 } 368 369 370 function _title_html() { 371 global $CFG; 372 373 //Accessibility: validation, can't have <div> inside <h2>, use <span>. 374 $title = '<div class="title">'; 375 376 if (!empty($CFG->allowuserblockhiding)) { 377 //Accessibility: added 'alt' text for the +- icon. 378 //Theme the buttons using, Admin - Miscellaneous - smartpix. 379 $strshow = addslashes_js(get_string('showblocka', 'access', strip_tags($this->title))); 380 $strhide = addslashes_js(get_string('hideblocka', 'access', strip_tags($this->title))); 381 $title .= '<input type="image" src="'.$CFG->pixpath.'/t/switch_minus.gif" '. 382 'id="togglehide_inst'.$this->instance->id.'" '. 383 'onclick="elementToggleHide(this, true, function(el) {'. 384 'return findParentNode(el, \'DIV\', \'sideblock\'); },'. 385 ' \''.$strshow.'\', \''.$strhide.'\'); return false;" '. 386 'alt="'.$strhide.'" title="'.$strhide.'" class="hide-show-image" />'; 387 } 388 389 //Accesssibility: added H2 (was in, weblib.php: print_side_block) 390 $title .= '<h2>'.$this->title.'</h2>'; 391 392 if ($this->edit_controls !== NULL) { 393 $title .= $this->edit_controls; 394 } 395 396 $title .= '</div>'; 397 return $title; 398 } 399 400 /** 401 * Sets class $edit_controls var with correct block manipulation links. 402 * 403 * @uses $CFG 404 * @uses $USER 405 * @param stdObject $options ? 406 * @todo complete documenting this function. Define $options. 407 */ 408 function _add_edit_controls($options) { 409 global $CFG, $USER, $PAGE; 410 411 if (empty($this->instance->pinned)) { 412 $context = get_context_instance(CONTEXT_BLOCK, $this->instance->id); 413 } else { 414 $context = get_context_instance(CONTEXT_SYSTEM); // pinned blocks do not have own context 415 } 416 417 // context for site or course, i.e. participant list etc 418 // check to see if user can edit site or course blocks. 419 // blocks can appear on other pages such as mod and blog pages... 420 421 switch ($this->instance->pagetype) { 422 case 'course-view': 423 if (!has_capability('moodle/site:manageblocks', $context)) { 424 return null; 425 } 426 break; 427 default: 428 429 break; 430 } 431 432 433 if (!isset($this->str)) { 434 $this->str->delete = get_string('delete'); 435 $this->str->moveup = get_string('moveup'); 436 $this->str->movedown = get_string('movedown'); 437 $this->str->moveright = get_string('moveright'); 438 $this->str->moveleft = get_string('moveleft'); 439 $this->str->hide = get_string('hide'); 440 $this->str->show = get_string('show'); 441 $this->str->configure = get_string('configuration'); 442 $this->str->assignroles = get_string('assignroles', 'role'); 443 } 444 445 // RTL support - exchange right and left arrows 446 if (right_to_left()) { 447 $rightarrow = 'left.gif'; 448 $leftarrow = 'right.gif'; 449 } else { 450 $rightarrow = 'right.gif'; 451 $leftarrow = 'left.gif'; 452 } 453 454 $movebuttons = '<div class="commands">'; 455 456 if ($this->instance->visible) { 457 $icon = '/t/hide.gif'; 458 $title = $this->str->hide; 459 } else { 460 $icon = '/t/show.gif'; 461 $title = $this->str->show; 462 } 463 464 if (empty($this->instance->pageid)) { 465 $this->instance->pageid = 0; 466 } 467 if (!empty($PAGE->type) and ($this->instance->pagetype == $PAGE->type) and $this->instance->pageid == $PAGE->id) { 468 $page = $PAGE; 469 } else { 470 $page = page_create_object($this->instance->pagetype, $this->instance->pageid); 471 } 472 $script = $page->url_get_full(array('instanceid' => $this->instance->id, 'sesskey' => $USER->sesskey)); 473 474 if (empty($this->instance->pinned)) { 475 $movebuttons .= '<a class="icon roles" title="'. $this->str->assignroles .'" href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id.'">' . 476 '<img src="'.$CFG->pixpath.'/i/roles.gif" alt="'.$this->str->assignroles.'" /></a>'; 477 } 478 479 if ($this->user_can_edit()) { 480 $movebuttons .= '<a class="icon hide" title="'. $title .'" href="'.$script.'&blockaction=toggle">' . 481 '<img src="'. $CFG->pixpath.$icon .'" alt="'.$title.'" /></a>'; 482 } 483 484 if ($options & BLOCK_CONFIGURE && $this->user_can_edit()) { 485 $movebuttons .= '<a class="icon edit" title="'. $this->str->configure .'" href="'.$script.'&blockaction=config">' . 486 '<img src="'. $CFG->pixpath .'/t/edit.gif" alt="'. $this->str->configure .'" /></a>'; 487 } 488 489 if ($this->user_can_addto($page)) { 490 $movebuttons .= '<a class="icon delete" title="'. $this->str->delete .'" href="'.$script.'&blockaction=delete">' . 491 '<img src="'. $CFG->pixpath .'/t/delete.gif" alt="'. $this->str->delete .'" /></a>'; 492 } 493 494 if ($options & BLOCK_MOVE_LEFT) { 495 $movebuttons .= '<a class="icon left" title="'. $this->str->moveleft .'" href="'.$script.'&blockaction=moveleft">' . 496 '<img src="'. $CFG->pixpath .'/t/'.$leftarrow.'" alt="'. $this->str->moveleft .'" /></a>'; 497 } 498 if ($options & BLOCK_MOVE_UP) { 499 $movebuttons .= '<a class="icon up" title="'. $this->str->moveup .'" href="'.$script.'&blockaction=moveup">' . 500 '<img src="'. $CFG->pixpath .'/t/up.gif" alt="'. $this->str->moveup .'" /></a>'; 501 } 502 if ($options & BLOCK_MOVE_DOWN) { 503 $movebuttons .= '<a class="icon down" title="'. $this->str->movedown .'" href="'.$script.'&blockaction=movedown">' . 504 '<img src="'. $CFG->pixpath .'/t/down.gif" alt="'. $this->str->movedown .'" /></a>'; 505 } 506 if ($options & BLOCK_MOVE_RIGHT) { 507 $movebuttons .= '<a class="icon right" title="'. $this->str->moveright .'" href="'.$script.'&blockaction=moveright">' . 508 '<img src="'. $CFG->pixpath .'/t/'.$rightarrow.'" alt="'. $this->str->moveright .'" /></a>'; 509 } 510 511 $movebuttons .= '</div>'; 512 $this->edit_controls = $movebuttons; 513 } 514 515 /** 516 * Tests if this block has been implemented correctly. 517 * Also, $errors isn't used right now 518 * 519 * @return boolean 520 */ 521 522 function _self_test() { 523 // Tests if this block has been implemented correctly. 524 // Also, $errors isn't used right now 525 $errors = array(); 526 527 $correct = true; 528 if ($this->get_title() === NULL) { 529 $errors[] = 'title_not_set'; 530 $correct = false; 531 } 532 if (!in_array($this->get_content_type(), array(BLOCK_TYPE_LIST, BLOCK_TYPE_TEXT))) { 533 $errors[] = 'invalid_content_type'; 534 $correct = false; 535 } 536 //following selftest was not working when roles&capabilities were used from block 537 /* if ($this->get_content() === NULL) { 538 $errors[] = 'content_not_set'; 539 $correct = false; 540 }*/ 541 if ($this->get_version() === NULL) { 542 $errors[] = 'version_not_set'; 543 $correct = false; 544 } 545 546 $formats = $this->applicable_formats(); 547 if (empty($formats) || array_sum($formats) === 0) { 548 $errors[] = 'no_formats'; 549 $correct = false; 550 } 551 552 $width = $this->preferred_width(); 553 if (!is_int($width) || $width <= 0) { 554 $errors[] = 'invalid_width'; 555 $correct = false; 556 } 557 return $correct; 558 } 559 560 /** 561 * Subclasses should override this and return true if the 562 * subclass block has a config_global.html file. 563 * 564 * @return boolean 565 */ 566 function has_config() { 567 return false; 568 } 569 570 /** 571 * Default behavior: print the config_global.html file 572 * You don't need to override this if you're satisfied with the above 573 * 574 * @uses $CFG 575 * @return boolean 576 */ 577 function config_print() { 578 // Default behavior: print the config_global.html file 579 // You don't need to override this if you're satisfied with the above 580 if (!$this->has_config()) { 581 return false; 582 } 583 global $CFG; 584 print_simple_box_start('center', '', '', 5, 'blockconfigglobal'); 585 include($CFG->dirroot.'/blocks/'. $this->name() .'/config_global.html'); 586 print_simple_box_end(); 587 return true; 588 } 589 590 /** 591 * Default behavior: save all variables as $CFG properties 592 * You don't need to override this if you 're satisfied with the above 593 * 594 * @param array $data 595 * @return boolean 596 */ 597 function config_save($data) { 598 foreach ($data as $name => $value) { 599 set_config($name, $value); 600 } 601 return true; 602 } 603 604 /** 605 * Default case: the block can be used in all course types 606 * @return array 607 * @todo finish documenting this function 608 */ 609 function applicable_formats() { 610 // Default case: the block can be used in courses and site index, but not in activities 611 return array('all' => true, 'mod' => false, 'tag' => false); 612 } 613 614 615 /** 616 * Default case: the block wants to be 180 pixels wide 617 * @return int 618 */ 619 function preferred_width() { 620 return 180; 621 } 622 623 /** 624 * Default return is false - header will be shown 625 * @return boolean 626 */ 627 function hide_header() { 628 return false; 629 } 630 631 /** 632 * Default case: an id with the instance and a class with our name in it 633 * @return array 634 * @todo finish documenting this function 635 */ 636 function html_attributes() { 637 return array('id' => 'inst'.$this->instance->id, 'class' => 'block_'. $this->name()); 638 } 639 640 /** 641 * Given an instance set the class var $instance to it and 642 * load class var $config 643 * @param block $instance 644 * @todo add additional documentation to further explain the format of instance and config 645 */ 646 function _load_instance($instance) { 647 if (!empty($instance->configdata)) { 648 $this->config = unserialize(base64_decode($instance->configdata)); 649 } 650 // [pj] This line below is supposed to be an optimization (we don't need configdata anymore) 651 // but what it does is break in PHP5 because the same instance object will be passed to 652 // this function twice in each page view, and the second time it won't have any configdata 653 // so it won't work correctly. Thus it's commented out. 654 // unset($instance->configdata); 655 $this->instance = $instance; 656 $this->specialization(); 657 } 658 659 /** 660 * This function is called on your subclass right after an instance is loaded 661 * Use this function to act on instance data just after it's loaded and before anything else is done 662 * For instance: if your block will have different title's depending on location (site, course, blog, etc) 663 */ 664 function specialization() { 665 // Just to make sure that this method exists. 666 } 667 668 /** 669 * Is each block of this type going to have instance-specific configuration? 670 * Normally, this setting is controlled by {@link instance_allow_multiple}: if multiple 671 * instances are allowed, then each will surely need its own configuration. However, in some 672 * cases it may be necessary to provide instance configuration to blocks that do not want to 673 * allow multiple instances. In that case, make this function return true. 674 * I stress again that this makes a difference ONLY if {@link instance_allow_multiple} returns false. 675 * @return boolean 676 * @todo finish documenting this function by explaining per-instance configuration further 677 */ 678 function instance_allow_config() { 679 return false; 680 } 681 682 /** 683 * Are you going to allow multiple instances of each block? 684 * If yes, then it is assumed that the block WILL USE per-instance configuration 685 * @return boolean 686 * @todo finish documenting this function by explaining per-instance configuration further 687 */ 688 function instance_allow_multiple() { 689 // Are you going to allow multiple instances of each block? 690 // If yes, then it is assumed that the block WILL USE per-instance configuration 691 return false; 692 } 693 694 /** 695 * Default behavior: print the config_instance.html file 696 * You don't need to override this if you're satisfied with the above 697 * 698 * @uses $CFG 699 * @return boolean 700 * @todo finish documenting this function 701 */ 702 function instance_config_print() { 703 // Default behavior: print the config_instance.html file 704 // You don't need to override this if you're satisfied with the above 705 if (!$this->instance_allow_multiple() && !$this->instance_allow_config()) { 706 return false; 707 } 708 global $CFG; 709 710 if (is_file($CFG->dirroot .'/blocks/'. $this->name() .'/config_instance.html')) { 711 print_simple_box_start('center', '', '', 5, 'blockconfiginstance'); 712 include($CFG->dirroot .'/blocks/'. $this->name() .'/config_instance.html'); 713 print_simple_box_end(); 714 } else { 715 notice(get_string('blockconfigbad'), str_replace('blockaction=', 'dummy=', qualified_me())); 716 } 717 718 return true; 719 } 720 721 /** 722 * Serialize and store config data 723 * @return boolean 724 * @todo finish documenting this function 725 */ 726 function instance_config_save($data,$pinned=false) { 727 $data = stripslashes_recursive($data); 728 $this->config = $data; 729 $table = 'block_instance'; 730 if (!empty($pinned)) { 731 $table = 'block_pinned'; 732 } 733 return set_field($table, 'configdata', base64_encode(serialize($data)), 'id', $this->instance->id); 734 } 735 736 /** 737 * Replace the instance's configuration data with those currently in $this->config; 738 * @return boolean 739 * @todo finish documenting this function 740 */ 741 function instance_config_commit($pinned=false) { 742 $table = 'block_instance'; 743 if (!empty($pinned)) { 744 $table = 'block_pinned'; 745 } 746 return set_field($table, 'configdata', base64_encode(serialize($this->config)), 'id', $this->instance->id); 747 } 748 749 /** 750 * Do any additional initialization you may need at the time a new block instance is created 751 * @return boolean 752 * @todo finish documenting this function 753 */ 754 function instance_create() { 755 return true; 756 } 757 758 /** 759 * Delete everything related to this instance if you have been using persistent storage other than the configdata field. 760 * @return boolean 761 * @todo finish documenting this function 762 */ 763 function instance_delete() { 764 return true; 765 } 766 767 /** 768 * Allows the block class to have a say in the user's ability to edit (i.e., configure) blocks of this type. 769 * The framework has first say in whether this will be allowed (e.g., no editing allowed unless in edit mode) 770 * but if the framework does allow it, the block can still decide to refuse. 771 * @return boolean 772 * @todo finish documenting this function 773 */ 774 function user_can_edit() { 775 return true; 776 } 777 778 /** 779 * Allows the block class to have a say in the user's ability to create new instances of this block. 780 * The framework has first say in whether this will be allowed (e.g., no adding allowed unless in edit mode) 781 * but if the framework does allow it, the block can still decide to refuse. 782 * This function has access to the complete page object, the creation related to which is being determined. 783 * @return boolean 784 * @todo finish documenting this function 785 */ 786 function user_can_addto(&$page) { 787 return true; 788 } 789 790 function get_extra_capabilities() { 791 return array('moodle/block:view'); 792 } 793 } 794 795 /** 796 * Specialized class for displaying a block with a list of icons/text labels 797 * 798 * @author Jon Papaioannou 799 * @package blocks 800 */ 801 802 class block_list extends block_base { 803 var $content_type = BLOCK_TYPE_LIST; 804 805 function is_empty() { 806 807 if (empty($this->instance->pinned)) { 808 $context = get_context_instance(CONTEXT_BLOCK, $this->instance->id); 809 } else { 810 $context = get_context_instance(CONTEXT_SYSTEM); // pinned blocks do not have own context 811 } 812 813 if ( !has_capability('moodle/block:view', $context) ) { 814 return true; 815 } 816 817 $this->get_content(); 818 return (empty($this->content->items) && empty($this->content->footer)); 819 } 820 821 function _print_block() { 822 global $COURSE; 823 824 // is_empty() includes a call to get_content() 825 if ($this->is_empty() && empty($COURSE->javascriptportal)) { 826 if (empty($this->edit_controls)) { 827 // No content, no edit controls, so just shut up 828 return; 829 } else { 830 // No content but editing, so show something at least 831 $this->_print_shadow(); 832 } 833 } else { 834 if ($this->hide_header() && empty($this->edit_controls)) { 835 // Header wants to hide, no edit controls to show, so no header it is 836 print_side_block(NULL, '', $this->content->items, $this->content->icons, 837 $this->content->footer, $this->html_attributes()); 838 } else { 839 // The full treatment, please. Include the title text. 840 print_side_block($this->_title_html(), '', $this->content->items, $this->content->icons, 841 $this->content->footer, $this->html_attributes(), $this->title); 842 } 843 } 844 } 845 846 } 847 848 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 14 11:33:29 2009 | Cross-referenced by PHPXref 0.7 |