[ Index ] |
|
Code source de Phorum 5.1.25 |
1 Creating Modules for Phorum5 2 ============================ 3 4 This document describes the Phorum5 module system. It is targeted at 5 developers who want to do customization and extend the functionality 6 of Phorum5. Modules are the preferred way to archieve this in 7 Phorum5. 8 9 For much of this document, we will be talking about an example module 10 "foo". Of course you will not name your module "foo", but something much 11 more appropriate. If you're not familiar with the terms "foo" and "bar", 12 you can visit http://en.wikipedia.org/wiki/Metasyntactic_variable 13 14 Be sure to read at least the **CAUTIONS AND SECURITY ISSUES** section, 15 before making your own modules. 16 17 18 Table of contents: 19 20 1. Introduction 21 1.1 Modules 22 1.2 Hacks 23 1.3 Hooks 24 2. Creating your own modules 25 2.1 What modules are built of 26 2.1.1 Hook functions 27 2.1.2 Module information 28 2.1.3 Other "stuff" 29 2.2 Module structure 30 2.2.1 Single file modules 31 2.2.2 Multiple file modules 32 2.3 Supporting multiple languages 33 2.4 Storing message data 34 2.4.1 From hooks that are run before saving a message to the database 35 2.4.2 From other hooks 36 2.5 Storing user data 37 2.6 Creating custom URLs 38 2.7 Implementing settings for your module 39 2.8 Changing the template 40 2.9 Example modules 41 3. **CAUTIONS AND SECURITY ISSUES** 42 3.1 Make modules, not hacks 43 3.2 Reload your module if you change the module information 44 3.3 How to access the $PHORUM array from your hook functions 45 3.4 How to access additional files in your multi file module 46 3.5 Secure your PHP files agains hackers 47 3.6 Secure your pages from XSS 48 3.7 Prevent namespace collisions 49 3.7.1 (Hook) functions 50 3.7.2 Data stored in $PHORUM 51 3.7.3 Language strings stored in $PHORUM 52 3.7.4 Data stored in messages, users and settings 53 4. Overview of available Phorum hooks 54 4.1 Code hooks 55 4.2 Template hooks 56 5. Support 57 58 59 1. Introduction 60 ------------------------------------------------------------------------------- 61 62 63 1.1 Modules 64 ----------- 65 66 Modules are self contained pieces of software, that can be added to 67 Phorum to change or extend its functionality. Modules can do this 68 without having to change anything in the standard Phorum distribution 69 files or database structure. So installing a module means: drop in 70 the code, go to the admin "Modules" page, enable the module and it 71 works. 72 73 74 1.2 Hacks 75 --------- 76 77 The moment it is neccessary to make changes to the standard Phorum 78 distribution files or database structure to implement some kind of 79 functionality, we're talking about a hack (even if the changes 80 that have to be made are accompanied by a drop in module). 81 82 Although there is nothing wrong with writing hacks, the Phorum team 83 wants to urge you to try if you can write a module before resorting 84 to a hack. Modules are the preferred way of modifying Phorum 85 functionality, because that will make both upgrading your distribution 86 and having your modification adopted by others easier. 87 88 89 1.3 Hooks 90 --------- 91 92 Phorum uses hooks to run its modules. Hooks are points in the 93 application where Phorum stops and runs its data through the modules 94 that are configured to handle the hook. The modules can act upon and 95 change this data. 96 97 The following image visualizes what happens when Phorum reaches 98 a hook point in the application, for which two modules ("foo" and 99 "bar") have been configured. 100 101 102 Phorum 103 Application 104 (1) (1) Phorum is running. 105 | (2) Phorum reaches the 106 | hook named "some_hook". 107 v Phorum (3) Phorum sends data to 108 some_hook >----- data ------+ the module system. 109 (2) (3) | (4) The module "foo" is run. 110 v (5) The module "bar" is run. 111 (4) module "foo" (6) The Phorum data (which 112 | might be modified by the 113 v modules) is sent back 114 (5) module "bar" to Phorum. 115 | (7) Phorum continues running 116 Phorum Modified | with the modified data. 117 Application <---- data ------+ 118 (7) (6) 119 | 120 | 121 v 122 123 124 2. Creating your own modules 125 ------------------------------------------------------------------------------- 126 127 128 2.1 What modules are built of 129 ----------------------------- 130 131 132 2.1.1 Hook functions 133 -------------------- 134 135 A module contains one or more PHP functions that act as hook 136 functions. Hook functions will receive some data in a variable 137 from Phorum and have to return the (possibly modified) data, which 138 will then go either back to Phorum or to the input of another module 139 which also handles the same hook (see 1.3). So the most basic (and 140 useless :-) hook function you could write would look somewhat like this 141 (see 3.7 for an explanation of the naming of the function): 142 143 function phorum_mod_foo_some_hook ($data) { 144 return $data; 145 } 146 147 The exact nature of the data that is sent to the hook functions 148 depends solely on the hook that is run. In chapter 4 of this document 149 you will find a description of all supported hooks, including a 150 specification of the type of data that is sent. 151 152 153 2.1.2 Module information 154 ------------------------ 155 156 For each hook that you want to handle in your module, you will have 157 to point the module system to the function in your module that will 158 handle the hook. Together with some other information, used for 159 describing the module, this is stored in the module information. 160 The module information acts as the glue between Phorum and your 161 module. 162 163 Module information is formatted using lines of plain text. Each line 164 contains a bit of information about the module. The general format 165 of the lines in the module information is: 166 167 <type>: <data> 168 169 Here is a list of the types that can be used: 170 171 +--------+-----------------------------------------------------------+ 172 | <type> | <data> | 173 +--------+-----------------------------------------------------------+ 174 | title | This is the title for the module that is displayed in the | 175 | | "Modules" page of the admin interface. | 176 +--------+-----------------------------------------------------------+ 177 | desc | This is the description that is displayed along with the | 178 | | title in the admin interface, to give a little more | 179 | | information about the module. Using HTML in the <data> | 180 | | part is allowed. | 181 +--------+-----------------------------------------------------------+ 182 | hook | This describes which hook functions are called for which | 183 | | Phorum hooks. The data consists of two fields, separated | 184 | | by a pipe "|" symbol. The first field contains the name | 185 | | of the hook that this module is hooking into. The second | 186 | | field contains the name of the hook function that will be | 187 | | called for the hook. | 188 +--------+-----------------------------------------------------------+ 189 190 It is allowed to use multiple hook lines in your module information, 191 so your module can hook into multiple hooks. When doing this, it 192 is also allowed to use the same hook function for handling different 193 hooks in your module (asuming the hooks are compatible). 194 195 Here's an example of what the module information for our example 196 module "foo" might look like: 197 198 title: Foo example module 199 desc: This is the Foo module for Phorum. Nothing exciting... 200 hook: some_hook|phorum_mod_foo_some_hook 201 hook: some_other_hook|phorum_mod_foo_some_other_hook 202 hook: yet_another_hook|phorum_mod_foo_some_other_hook 203 204 So what this module info for example does, is telling Phorum that 205 when it gets to "some_other_hook", it will have to call the function 206 phorum_mod_foo_some_other_hook() in your module. It also tells 207 that for "yet_another_hook" the same function has to be called. 208 209 210 2.1.3 Other "stuff" 211 ------------------- 212 213 Hook functions and the module information are all the parts needed 214 for creating a working module. However, your module might need 215 extra stuff like template, language and image files. You can 216 store these files along with your module when using the multiple 217 file module structure (see 2.2.2 below). 218 219 If you do not need to store any other stuff with your module, you 220 can also choose to use the single file (see 2.2.1 below) module 221 structure. 222 223 224 2.2 Module structure 225 -------------------- 226 227 228 2.2.1 Single file modules 229 ------------------------- 230 231 Single file modules are useful in case case no additional files have 232 to be distributed with your module. Because the module consist of 233 only one single file, it is very easy to distribute. Beware that the 234 moment you want to support for example a settings screen, multiple 235 languages or custom images, you will have to switch to the multiple 236 file module structure. 237 238 Single file modules consist of one single PHP file, which contains 239 both the module information and the hook functions. For storing the 240 module informaton, a special PHP comment is used. This comment must 241 look like the following: 242 243 /* phorum module info 244 <module information lines go here> 245 */ 246 247 Using the example module info from 2.1.2, the complete single 248 file module would look like this (see 3.5 why we use the 249 check on PHORUM at the start of this file): 250 251 <?php 252 253 if(!defined("PHORUM")) return; 254 255 /* phorum module info 256 title: Foo example module 257 desc: This is the Foo module for Phorum. Nothing exciting... 258 hook: some_hook|phorum_mod_foo_some_hook 259 hook: some_other_hook|phorum_mod_foo_some_other_hook 260 hook: yet_another_hook|phorum_mod_foo_some_other_hook 261 */ 262 263 function phorum_mod_foo_some_hook ($data) { 264 // Do stuff for "some_hook". 265 return $data; 266 } 267 268 function phorum_mod_foo_some_other_hook ($data) { 269 // Do stuff for "some_other_hook" and "yet_another_hook". 270 return $data; 271 } 272 273 ?> 274 275 Installation of a single file module is done by putting the PHP 276 file (e.g. foo.php) directly in the directory {phorum dir}/mods/ 277 and activating the module from the "Modules" screen in your 278 admin interface. 279 280 281 2.2.2 Multiple file modules 282 --------------------------- 283 284 Multiple file modules are useful in case you need additional files 285 to be stored with your module, for example a settings screen, 286 language files or custom images. 287 288 Multiple file modules are stored in their own subdirectory below 289 the directory {phorum dir}/mods/. So if you have a module named 290 "foo", you will have to create a directory {phorum dir}/mods/foo/ for 291 storing all module files. 292 293 Inside this subdirectory, you will have to create a least two files. 294 The first is a file called "info.txt". This file contains the 295 module information for your module (see 2.1.2). The second file 296 is the PHP file which contains the hook functions for your module. 297 The basename of this file should be the same as the name of the 298 module subdirectory. So for our example module "foo", you will have 299 to create a file named "foo.php". 300 301 Using the example module info from 2.1.2, the complete multiple 302 file module would look like this (see 3.5 why we use the 303 check on PHORUM at the start of the PHP file): 304 305 info.txt: 306 307 title: Foo example module 308 desc: This is the Foo module for Phorum. Nothing exciting... 309 hook: some_hook|phorum_mod_foo_some_hook 310 hook: some_other_hook|phorum_mod_foo_some_other_hook 311 hook: yet_another_hook|phorum_mod_foo_some_other_hook 312 313 foo.php: 314 315 <?php 316 317 if(!defined("PHORUM")) return; 318 319 function phorum_mod_foo_some_hook ($data) { 320 // Do stuff for "some_hook". 321 return $data; 322 } 323 324 function phorum_mod_foo_some_other_hook ($data) { 325 // Do stuff for "some_other_hook" and "yet_another_hook". 326 return $data; 327 } 328 329 ?> 330 331 So far, the module has exactly same functionality as the single 332 file module from 2.2.1. From here on, the functionality can be 333 extended. Some of the possibilities are: 334 335 - Using custom files for your module (images, classes, libs, etc.); 336 - Letting your module support multiple languages; 337 - Creating a settings screen for your module; 338 339 340 2.3 Supporting multiple languages 341 --------------------------------- 342 343 (this feature is only available for the multiple file module structure) 344 345 If your module includes text that will be displayed to end users, 346 you should strongly consider making it support multiple languages. 347 This will allow Phorum installations using another language to display 348 output of your module in the same language, instead of the language 349 you have written the module in. 350 351 For supporting multiple languages, the first thing to do is add the 352 following to your module information file (info.txt): 353 354 hook: lang| 355 356 There is no hook function configured here, because the "lang" hook 357 is only used as a marker for Phorum. This only tells Phorum that your 358 module supports multiple languages. 359 360 Next, you must provide at least one language file with your module. 361 Language files are stored in a subdirectory name "lang" inside your 362 module directory. So in our sample module, the full directory would be 363 {phorum dir}/foo/lang/. The language files must be named identical 364 to the main language files that Phorum uses. So, to include both 365 English and French, your module would have the following file 366 structure below the Phorum's mods directory: 367 368 foo/info.txt 369 foo/foo.php 370 foo/lang/english.php 371 foo/lang/french.php 372 373 The structure of your language files will be almost identical to that 374 of the main Phorum language files. However, for your own language files 375 it is advisable to add an extra level in the language variables, to 376 avoid conflicts with other modules or Phorum itself. Here is an 377 example of how you would do that: 378 379 <?php 380 $PHORUM["DATA"]["LANG"]["mod_foo"]["Hello"] = "Hello!"; 381 ?> 382 383 Here, the extra inserted level is ["mod_foo"]. You can add as many 384 lines as you need for your module. To access the above language string, 385 from your module code you would use: 386 387 $PHORUM["DATA"]["LANG"]["mod_foo"]["Hello"] 388 389 From a template file, you would use: 390 391 {LANG->mod_foo->Hello} 392 393 In case a Phorum installation is using a language that your module 394 does not support, Phorum will automatically attempt to fallback to 395 English. So it is highly recommend that you include an english.php 396 language file in all your modules. If both the current language and 397 english.php are not found, Phorum will be unable to load a language 398 for your module and will display empty space instead of language 399 strings. 400 401 Try to reuse strings that are already in the main Phorum language 402 files itself. Only create custom strings when there is no alternative 403 available. Having more text to translate is more work for everybody, 404 especially the Phorum translators. 405 406 407 2.4 Storing message data 408 ------------------------ 409 410 If your module needs to store data along with a Phorum message, 411 you can make use of the meta information array that is attached 412 to each message ($message["meta"]). This array is a regular PHP 413 array, which is stored in the database as serialized data 414 (see http://www.php.net/serialize). Because Phorum and other modules 415 make use of this meta data as well, you should not squash it, 416 neither access the meta data in the database directly. Instead 417 use the methods described in this section. 418 419 Remark: because the meta data is stored as serialized data in the 420 database, it is not possible to include data you store in there 421 in SQL queries. 422 423 When storing information in the meta data from a hook function, you 424 can encounter two different situations, which both need a different 425 way of handling. 426 427 428 2.4.1 From hooks that are run before saving a message to the database 429 --------------------------------------------------------------------- 430 431 There are some hooks that send a full message structure to the 432 hook functions, so these can change the message data before storing 433 the message in the database. Examples are the hooks "pre_post" 434 and "pre_edit". In this case you can simply update the meta 435 information directly. Here's an example of how this would look 436 in your hook function: 437 438 function phorum_mod_foo_pre_post ($message) { 439 $message["meta"]["mod_foo"]["foodata"] = "Some data"; 440 $message["meta"]["mod_foo"]["bardata"] = "Some more data"; 441 return $message; 442 } 443 444 Phorum will take care of storing the updated meta data in the database. 445 446 447 2.4.2 From other hooks 448 ---------------------- 449 450 For other hooks, the proper way to store information in the meta 451 data is to retrieve the current meta data using phorum_db_get_message(), 452 copy the meta data to a new message structure, make changes as needed 453 and use phorum_db_update_message() to update the message in the 454 database. Here is an example of how this could look in your hook 455 function: 456 457 function phorum_mod_foo_some_hook ($data) { 458 459 // Somehow you get the id for the message. Here we asume 460 // that it is stored in the $data parameter. 461 $message_id = $data["message_id"]; 462 463 // Retrieve the current message data. 464 $message = phorum_db_get_message ($message_id); 465 466 // Create updated meta data. 467 $new_message = array("meta" => $message["meta"]); 468 $new_message["meta"]["mod_foo"]["foodata"] = "Some data"; 469 $new_message["meta"]["mod_foo"]["bardata"] = "Some more data"; 470 471 // Store the updated data in the database. 472 phorum_db_update_message($message_id, $new_message); 473 474 return $data; 475 } 476 477 Changing meta data for a message this way will ensure that the 478 existing meta data is kept intact. 479 480 481 2.5 Storing user data 482 --------------------- 483 484 If your module needs to store data along with a Phorum user, 485 you can make use of custom profile fields. In the admin interface, 486 under "Custom Profiles", you can add your own profile fields 487 (see also docs/creating_custom_userfields.txt). 488 489 The custom profile fields will be accessible from within the user 490 data. E.g. if you have created a custom profile field named "foobar", 491 the value of that field will be stored in $user["foobar"]. 492 493 When using a custom profile field for storing module information, 494 you can use a separate field for each piece of data you want to 495 store. But instead, you can also create a single field for storing 496 a complete array of information. Phorum will automatically take care 497 of storing this information (serialized) in the database. You only 498 should make sure that the custom profile field is large enough to 499 store all the data. When your module needs to store multiple fields, 500 this is the preferred way. 501 502 For storing data in the custom profile field, you can make use of the 503 phorum_user_save() function. This function needs the user_id of the 504 user and all fields that need to be updated. Below are two pieces of 505 code which show how our example module might store data for a user 506 (asuming $user_id is the id of the user that must be changed). 507 508 When using multiple fields "mod_foo_foodata" and "mod_foo_bardata": 509 510 $userdata = array( 511 "user_id" => $user_id, 512 "mod_foo_foodata" => "Some user data", 513 "mod_foo_bardata" => "Some more user data" 514 ); 515 phorum_user_save($userdata); 516 517 When using a single custom field "mod_foo" for this module: 518 519 $user = phorum_user_get($user_id); 520 $userdata = array( 521 "user_id" => $user_id, 522 "mod_foo" => array ( 523 "foodata" => "Some user data", 524 "bardata" => "Some more user data" 525 ) 526 ); 527 phorum_user_save($user); 528 529 530 2.6 Creating custom URLs 531 ------------------------- 532 533 Phorum uses the function phorum_get_url() to consistenly build URLs 534 that point to parts of Phorum. It is recommended that you use this 535 function as well when creating links yourself, so special features 536 and future changes will automatically be incorporated in the links 537 you use. 538 539 Here's an example of building an URL, which will open the profile 540 for the user with user_id = 17: 541 542 $url = phorum_get_url(PHORUM_PROFILE_URL, 17); 543 544 The argument list that this function takes, depends on the first 545 argument which tells Phorum what kind of URL has to be built. 546 So when building other URLs, other arguments will probably 547 be used. 548 549 If you need to build a custom URL to link to your own module, you 550 can use phorum_get_url() as well. The way to go is simple. You 551 need to use PHORUM_CUSTOM_URL as the first argument and add all 552 URL building parameters to it. 553 554 The first parameter needs to be the filename of the file to link 555 to, without the (.php) extension. The second parameter needs to 556 be 0 or 1. If it is 1, the current forum_id is added to the URL. 557 All other parameters are added comma separated to the URL. 558 559 Here's an example of building a custom URL which links to the 560 file "myfile.php". The URL has to have the forum_id in it and 561 needs to contain the additional parameter "foo=bar": 562 563 $url = phorum_get_url(PHORUM_CUSTOM_URL, "myfile", 1, "foo=bar"); 564 565 566 2.7 Implementing settings for your module 567 ----------------------------------------- 568 569 (this feature is only available for the multiple file module structure) 570 571 Some modules that you write might need to store settings for later 572 use. For those, you can create a settings page which will be used 573 from within the admin interface. 574 575 The settings page must be put in your modules's directory by the 576 name of "settings.php". So for our example module "foo" the file 577 would go in {phorum dir}/mods/foo/settings.php. In the admin 578 interface under the option "Modules", a link to the settings.php 579 page will automatically be added if the settings.php file is 580 available for your module. 581 582 Although you can do anything you want from your settings.php script, 583 it is recommended that you use the tools that are handed to you 584 by Phorum for building pages and storing settings. 585 586 One of those tools is a PHP object "PhorumInputForm" which 587 can be used to create standard input forms and table displays in 588 the admin interface. The best example here is to look at one of the 589 modules that come with Phorum like "bbcode" or "replace". 590 591 Another tool is the function phorum_db_update_settings() which can 592 be used for storing settings in the database. To store settings using 593 this function you do something like the following: 594 595 $foo_settings["foodata"] = "Some setting data"; 596 $foo_settings["bardata"] = "Some more setting data"; 597 phorum_db_update_settings(array("mod_foo" => $foo_settings)); 598 599 $foo_settings can be anything you like: an array, object, string, etc. 600 The first request after you have stored your settings, the setting 601 data for this example will be available in $PHORUM["mod_foo"]. 602 603 To ensure that your settings file is only loaded from the admin 604 interface, place this line at the top of your settings.php file 605 (see also 3.5): 606 607 if(!defined("PHORUM_ADMIN")) return; 608 609 610 2.8 Changing the templates using template hooks 611 ----------------------------------------------- 612 613 614 2.8.1 When to use a template hook 615 --------------------------------- 616 617 Changing the templates should be avoided as much as possible when 618 writing a module. This will basically turn your mod into a hack, 619 because files have to be edited for it. Inexperienced users might 620 find it hard to install your module if they have to modify files 621 to get it to work. 622 623 If you cannot avoid changing the template, then consider to use 624 template hooks for this. You can use these if your template change 625 involves adding extra code to a template. The advantage is that 626 there's only little code that has to be added to the templates, 627 which makes things less confusing to users that want to install the 628 module. 629 630 631 2.8.2 How to use a template hook 632 -------------------------------- 633 634 To create a template hook, you do the following: 635 636 * Add "{HOOK tpl_some_hook}" to the template at an appropriate spot; 637 638 * Put "hook: tpl_some_hook|phorum_mod_foo_tpl_some_hook" in your 639 module info; 640 641 * Create the hook function phorum_mod_foo_tpl_some_hook() that 642 prints out the code that has to be placed at the position of 643 the "{HOOK tpl_some_hook}" code the the template. 644 645 If you want to pass on the data from template variables to 646 the hook function, you can simply add the variables to the hook 647 definition in the template. Example: 648 649 {HOOK tpl_some_hook DATA1 DATA2} 650 651 The hook function will get the contents of these variables passed in 652 a single array. This can for example be useful if your template hook 653 needs access to loop data. Example: 654 655 {LOOP MESSAGES} 656 ... 657 {HOOK tpl_some_hook MESSAGES} 658 ... 659 {/LOOP MESSAGES} 660 661 662 2.8.3 Preventing collisions in hook names 663 ----------------------------------------- 664 665 You can use any name for "tpl_some_hook", but beware that your 666 name does not collide with an already existing hook name. 667 668 The easiest way to do this is use the techniques from section 3.7. 669 As a rule of thumb, you can use the following format: 670 671 tpl_mod_<modulename>_<identifier> 672 673 Example: If a buttonbar is added in one of the templates for a module 674 named "foo", the name for the hook could be "tpl_mod_foo_buttonbar". 675 676 677 2.9 Example modules 678 ------------------- 679 680 The best way of learning how to write modules is probably looking 681 at existing module code. In your Phorum distribution's docs directory, 682 you will find the directory example_mods. This directory contains a 683 couple of example modules, demonstrating the features described in this 684 document. The modules have no real functional purpose, but they might 685 be easier to read than the real Phorum modules. 686 687 688 3. **CAUTIONS AND SECURITY ISSUES** 689 ------------------------------------------------------------------------------- 690 691 692 3.1 Make modules, not hacks 693 --------------------------- 694 695 Making modules that require database changes are discouraged and may 696 not be accepted as an approved module. We want modules to be as 697 transparent as possible for upgrades. Please attempt to store your 698 data in the proper place. See chapter 2 for more information on that. 699 700 701 3.2 Reload your module if you change the module information 702 ----------------------------------------------------------- 703 704 If you are changing the module info for a module that is already 705 activated in your Phorum installation, you must deactivate and 706 reactivate it to have Phorum reload the changed information. For 707 performance reasons the module information is only read when the 708 module is activated. 709 710 If you have added a new hook function to your module and it seems 711 not to be run, it probably is because you did not do this. 712 713 714 3.3 How to access the $PHORUM array from your hook functions 715 ------------------------------------------------------------ 716 717 The $PHORUM array is in the global scope. From inside a function, 718 you can not directly access this array. So you will have to import 719 the $PHORUM array into your function scope. The Phorum team 720 recommends the following method for doing this (check out the 721 faq.txt to see why we do not use the "global" keyword): 722 723 function phorum_mod_foo_some_hook ($data) { 724 $PHORUM = $GLOBALS["PHORUM"]; 725 726 // Do stuff for "some_hook". 727 728 return $data; 729 } 730 731 732 3.4 How to access additional files in your multi file module 733 ------------------------------------------------------------ 734 735 All standard Phorum pages are run from the Phorum installation 736 directory. The hook functions that you write also work from 737 the same directory. So if you want to access files in your module 738 directory, you will have to specify the relative path to those 739 files. This path looks like: 740 741 ./mods/<module>/<filename> 742 743 So let's say that our module "foo" has a subdirectory "images" 744 which contains "bar.gif", then we could display that image 745 using the HTML code: 746 747 <img src="./mods/foo/images/bar.gif" /> 748 749 Another example: let's say that there is a function library 750 named "my_module_functions.php" in the module, which must be 751 included from then module code, then this is done using: 752 753 include("./mods/foo/my_module_functions.php"); 754 755 756 3.5 Secure your PHP files agains hackers 757 ---------------------------------------- 758 759 To prevent hackers from loading your PHP module files directly, you 760 should add the following to the start of your PHP files: 761 762 if(!defined("PHORUM")) return; 763 764 This will make sure that the file will only work when loaded from 765 the Phorum application. If you are writing pages that are loaded 766 from the admin interface (like a settings screen for your module), 767 then use the following line instead: 768 769 if(!defined("PHORUM_ADMIN")) return; 770 771 This will make sure that the file will only work when loaded from 772 the Phorum admin interface. 773 774 775 3.6 Secure your pages from XSS 776 ------------------------------ 777 778 XSS stands for cross site scripting. This means that hackers 779 can feed HTML data to your application, which is displayed on 780 screen without stripping or escaping the HTML data. This way 781 it can be possible for hackers to feed malicous javascript 782 code into the browser of users on the forum, causing a security 783 risk. If you want to learn more about XSS, please visit 784 http://en.wikipedia.org/wiki/XSS 785 786 To prevent XSS security holes, you must take care that all 787 user input is properly sanitized before displaying it on screen. 788 Sanitizing can be done by either stripping all HTML from 789 the data (e.g. using http://www.php.net/strip_tags) or by escaping 790 all html characters (using http://www.php.net/htmlspecialchars). 791 792 Example: 793 794 If your module needs to display the username for a user on 795 screen, it must not simply do: 796 797 print $user["username"]; 798 799 Instead you must use: 800 801 print htmlspecialchars($user["username"]); 802 803 It's not only for security that you have to sanitize data before 804 displaying it. You must use htmlspecialchars() to prevent some other 805 possible problems as well. Imagine you have a user with the username 806 "<b>ob". Without htmlspecialchars() the username would be interpreted 807 as HTML code, possibly making the full page bold from the username on. 808 809 810 3.7 Prevent namespace collisions 811 -------------------------------- 812 813 When creating modules, you must always be aware that you are 814 working in the same namespace as other modules and Phorum itself. 815 This means that there is a risk of duplicate use of function 816 and variable names. By following a couple of simple rules, you 817 can greatly reduce this risk. 818 819 820 3.7.1 (Hook) functions 821 ---------------------- 822 823 Always construct names for your module functions like this: 824 825 phorum_mod_<module name>_<identifier> 826 827 So if you are writing functions for a module named "foo", all 828 function names will look like: 829 830 phorum_mod_foo_<identifier> 831 832 You can use whatever you like for the <identifier> part. When writing 833 a hook function, it is recommended to use the name of the hook for 834 which you are writing the function (this will make clear what the 835 function does, without having to check the module info). So in case 836 you are writing a hook function for the hook "some_hook", the full 837 function name would be: 838 839 phorum_mod_foo_some_hook 840 841 If your hook function handles multiple hooks at once, then 842 simply use one of the hook's names as the <identifier> or make up 843 something yourself. 844 845 846 3.7.2 Data stored in $PHORUM 847 ---------------------------- 848 849 When storing data in $PHORUM, always prepend the array key name 850 with mod_<module name>. If your module is named "foo", do not use: 851 852 $PHORUM["mydata"] 853 854 but instead: 855 856 $PHORUM["mod_foo_mydata"] 857 858 859 3.7.3 Language strings stored in $PHORUM 860 ---------------------------------------- 861 862 When storing your custom language strings, do not put them directly 863 in $PHORUM["DATA"]["LANG"] like Phorum does, because that might 864 result in conflicting language strings. Instead add an extra data level, 865 which makes sure that your module keeps all language strings to itself. 866 867 If your module is named "foo", you should store language strings in: 868 869 $PHORUM["DATA"]["LANG"]["mod_foo"] 870 871 See also section 2.3. 872 873 874 3.7.4 Data stored in messages, users and settings 875 ------------------------------------------------- 876 877 When using the Phorum provided ways of storing data in messages, 878 users and settings, always prepend the data key with 879 mod_<module name>. SO if your module is named "foo", do not use 880 things like: 881 882 $new_message["meta"]["foodata"] = "Some data"; 883 $user["foodata"] = "Some data"; 884 phorum_db_update_settings(array("settings" => $foo_settings)); 885 886 but instead: 887 888 $new_message["meta"]["mod_foo_foodata"] = "Some data"; 889 $user["mod_foo_foodata"] = "Some data"; 890 phorum_db_update_settings(array("mod_foo" => $foo_settings)); 891 892 See also sections 2.4 (message data), 2.5 (user data) and 2.7 (settings). 893 894 895 4. Overview of available Phorum hooks 896 ------------------------------------------------------------------------------- 897 898 In this chapter you will find an overview of all available Phorum 899 hooks and a description of what they do. 900 901 Remarks: 902 903 * Input is what your module function should expect as parameters. 904 905 * Return is what your module function should return. Most hooks 906 expect the same data structure as was sent. For those items, 907 the Return is listed simply as "Same as Input". 908 909 * Normally, hook functions are allowed to modify the data that was 910 sent as input. If this is not allowed, the input data will be 911 flagged as read-only. 912 913 * In most cases the hook description will provide only one or more 914 of the possible uses for the hook. The full leverage of each hook 915 is only limited by the imagination of the module writer (it's 916 as much a cliche as it is true). 917 918 * It may be that you need to hook into a spot where there is 919 currently no hook available. If that is the case, let the dev 920 team know by posting a message in the development forum 921 on phorum.org, explaining where and why you need an extra hook. 922 Hooks will be added as neccessary, especially while Phorum 5 923 is young. 924 925 926 4.1 Code hooks 927 -------------- 928 929 Code hooks are hooks that are called from within the Phorum core 930 code. These hooks are typically used for modifying Phorum's internal 931 datastructures. 932 933 934 ---------------------------------------------------------------------------- 935 admin_general 936 937 Where : admin interface 938 When : Right before the PhorumInputForm object is shown. 939 Input : The PhorumInputForm object. 940 Return : Same as Input 941 942 This hook can be used for adding items to the form on the 943 "General Settings" page of the admin interface. 944 945 ---------------------------------------------------------------------------- 946 admin_file_purge 947 948 Where : admin interface, option "Purge Stale Files" 949 When : Right before stale files are deleted from the database. 950 Input : An array, containing a description of all stale files. 951 Return : Same as Input 952 953 The primary use of this hook would be to cleanup stale files, created 954 by an alternate storage system for attachments (see after_attach and 955 after_detach as well). The array that is passed on to the hook function 956 contains arrays, which contain the following fields: 957 958 file_id : Internal id to reference the file. 959 filename : Name of the file. 960 filesize : Filesize in KB. 961 add_datetime : Epoch timestamp for the time the file was created. 962 reason : A description why this file is considered to be stale. 963 964 ---------------------------------------------------------------------------- 965 after_attach 966 967 Where : include/posting/action_attachments.php 968 When : Just after a file attachment is saved in the database 969 Input : Two part array where the first element is the message array and 970 the second element is a file array that contains the name, size, 971 and file_id of the newly saved file. 972 Return : Same as Input 973 974 The primary use of this hook would be for creating an alternate storage 975 system for attachments. You would need to use the before_attach hook to 976 remove the file data and in this hook it could be saved properly. You will 977 need to use the file hook to retreive the file data later. 978 979 ---------------------------------------------------------------------------- 980 after_detach 981 982 Where : include/posting/action_attachments.php 983 When : Just after a file attachment is deleted from the database 984 Input : Two part array where the first element is the message array and 985 the second element is a file array that contains the name, size, 986 and file_id of the deleted file. 987 Return : Same as Input 988 989 The primary use of this hook would be for creating an alternate storage 990 system for attachments. Using this hook, you can delete the file from 991 your alternate storage. 992 993 ---------------------------------------------------------------------------- 994 after_header 995 996 Where : Every page, except for the admin interface pages 997 When : Right after the header is displayed. 998 Input : none 999 Return : none 1000 1001 This hook can be used for creating content at the end of the header, 1002 just before the main content is displayed. 1003 1004 ---------------------------------------------------------------------------- 1005 after_login 1006 1007 Where : login.php 1008 When : After a successful login, just before redirecting the 1009 user to a Phorum page. 1010 Input : The redirection URL. 1011 Return : Same as Input 1012 1013 This hook can be used for performing tasks after a successful user 1014 login and for changing the page to which the user will be redirected 1015 (by returning a different redirection URL). If you need to access the 1016 user data, then you can do this through the global $PHORUM variable. 1017 The user data will be in $PHORUM["user"]. 1018 1019 ---------------------------------------------------------------------------- 1020 after_logout 1021 1022 Where : login.php 1023 When : After a logout, just before redirecting the user to 1024 a Phorum page. 1025 Input : The redirection URL. 1026 Return : Same as Input 1027 1028 This hook can be used for performing tasks after a successful user 1029 logout and for changing the page to which the user will be redirected 1030 (by returning a different redirection URL). The user data will still 1031 be availbale in $PHORUM["user"] at this point. 1032 1033 ---------------------------------------------------------------------------- 1034 after_message_save 1035 1036 Where : action_post.php 1037 When : After storing a new message and all database updates are done. 1038 Input : Array containing message data. 1039 Return : Same as Input 1040 1041 This hook can be used for performing actions based on what the message 1042 contained or altering it before it is emailed to the subscribed users. 1043 It is also useful for adding or removing subscriptions. 1044 1045 ---------------------------------------------------------------------------- 1046 after_register 1047 1048 Where : register.php 1049 When : Right after a successful registration of a new user is done 1050 and all confirmation mails are sent. 1051 Input : Array containing the user data of the user (read-only). 1052 Return : Same as Input 1053 1054 This hook can be used for performing tasks (like logging and 1055 notification) after a successful user registration. 1056 1057 ---------------------------------------------------------------------------- 1058 before_attach 1059 1060 Where : include/posting/action_attachments.php 1061 When : Just before a file attachment is saved in the database 1062 Input : Two part array where the first element is the message array and 1063 the second element is a file array that contains the name, size 1064 and data. 1065 Return : Same as Input 1066 1067 The primary use of this hook would be for creating an alternate storage 1068 system for attachments. You would need to use the after_attach hook to 1069 complete the process as you do not yet have the file_id for the file. You 1070 will need to use the file hook to retreive the file data later. 1071 1072 ---------------------------------------------------------------------------- 1073 before_editor 1074 1075 Where : posting.php 1076 When : Just before the message editor is displayed. 1077 Input : Array containing data for the message that will be shown 1078 in the editor screen. 1079 Return : Same as Input 1080 1081 This hook can be used for changing message data, just before the editor 1082 is displayed. This is done after escaping message data for XSS prevention 1083 is done. So in the hook, the module writer will have to be aware that 1084 data is escaped and that he has to escape data himself if needed. 1085 1086 This hook is called every time the editor is displayed. If modifying 1087 the message data does not have to be done on every request (for example 1088 only on the first request when replying to a message), the module will 1089 have to check the state the editor is in. Here's some hints on what 1090 you could do to accomplish this: 1091 1092 * Check the editor mode: this can be done by looking at the "mode" field 1093 in the message data. This field can be one of "post", "reply" and "edit". 1094 1095 * Check if it's the first request: this can be done by looking at the 1096 $_POST array. If no field "message_id" can be found in there, the 1097 editor is handing the first request. 1098 1099 Using this, an example hook function that appends the string "FOO!" 1100 to the subject when replying to a message (how useful ;-) could look 1101 like this: 1102 1103 function phorum_mod_foo_before_editor ($data) 1104 { 1105 if ($data["mode"] == "reply" && ! isset($_POST["message_id])) { 1106 $data["reply"] = $data["reply"] . " FOO!"; 1107 } 1108 1109 return $data; 1110 } 1111 1112 Beware: this hook function only changes message data before it is 1113 displayed in the editor. From the editor, the user can still change 1114 the data. Therefore, this hook cannot be used to control the data which 1115 will be stored in the database. If you need that functionality, then 1116 use the hooks pre_edit and/or pre_post instead. 1117 1118 ---------------------------------------------------------------------------- 1119 before_footer 1120 1121 Where : Every page, except for the admin interface pages 1122 When : Right before the footer is displayed. 1123 Input : none 1124 Return : none 1125 1126 This hook can be used for creating content at the end of the main 1127 content, just before the footer. It can also be used for 1128 performing tasks that have to be executed at the end of each page. 1129 1130 ---------------------------------------------------------------------------- 1131 before_register 1132 1133 Where : register.php 1134 When : Right before a new user is stored in the database. 1135 Input : Array containing the user data of the user. 1136 Return : Same as Input 1137 1138 This hook can be used for performing tasks before user registration. 1139 This hook is useful if you want to add some data to or change some 1140 data in the user data and to check if the user data is correct. 1141 1142 When checking the registration data, the hook can set the "error" field 1143 in the returned user data array. When this field is set after running 1144 the hook, the registration processed will be halted and the error 1145 will be displayed. If you created a custom form field "foo" and you 1146 require that field to be filled in, you could create a hook function 1147 which looks like this: 1148 1149 function phorum_mod_foo_before_register ($data) 1150 { 1151 $myfield = trim($data['your_custom_field']); 1152 if (empty($myfield)) { 1153 $data['error'] = 'You need to fill in my custom field'; 1154 } 1155 1156 return $data; 1157 } 1158 1159 The error must be safely HTML escaped, so if you use untrusted data in 1160 your error, then make sure that it is escaped using htmlspecialchars() 1161 to prevent XSS (see also paragraph 3.6: Secure your pages from XSS). 1162 1163 ---------------------------------------------------------------------------- 1164 buddy_add 1165 1166 Where : pm.php 1167 When : Right after a buddy has been added successfully. 1168 Input : The user id of the buddy that has been added. 1169 Return : Same as Input 1170 1171 This hook can be used for performing actions after a buddy has been 1172 added for a user (e.g. sending the new buddy a PM about this event, 1173 update popularity counters, do logging, synchronizing with other 1174 databases, etc.). 1175 1176 ---------------------------------------------------------------------------- 1177 buddy_delete 1178 1179 Where : pm.php 1180 When : Right after a buddy has been deleted successfully. 1181 Input : The user id of the buddy that has been deleted. 1182 Return : Same as Input 1183 1184 This hook can be used for performing actions after a buddy has 1185 been deleted for a user. 1186 1187 ---------------------------------------------------------------------------- 1188 cc_save_user 1189 1190 Where : control.php 1191 When : Right before data for a user is saved in the control panel. 1192 Input : Array containing the user data to save. 1193 Return : Same as Input 1194 1195 This hook works the same way as the before_register hook, so you can 1196 also use it for changing and checking the user data that will be 1197 saved in the database. There's one difference. If you want to 1198 check a custom field, you'll also need to check the panel which 1199 you are on, because this hook is called from multiple panels. 1200 The panel that you are on, will be stored in the 'panel' field 1201 of the user data. 1202 1203 If you have added a custom field to the template for the option 1204 "Edit My Profile" in the control panel, your hook function will 1205 look like this: 1206 1207 function phorum_mod_foo_cc_save_user ($data) 1208 { 1209 // Only check data for the panel "user". 1210 if ($data['panel'] != "user") return $data; 1211 1212 $myfield = trim($data['your_custom_field']); 1213 if (empty($myfield)) { 1214 $data['error'] = 'You need to fill in my custom field'; 1215 } 1216 1217 return $data; 1218 } 1219 1220 ---------------------------------------------------------------------------- 1221 check_post 1222 1223 Where : post.php 1224 When : Right after performing preliminary posting checks, unless 1225 these checks have returned something bad. 1226 Input : Array containing: 1227 0 => the $_POST array with form data 1228 1 => $error, to return errors in 1229 Return : Same as Input 1230 1231 This hook can be used for modifying data in the $_POST array and for 1232 running additional checks on the data. If an error is put in $error, 1233 Phorum will stop posting the message and show the error to the user 1234 in the post-form. 1235 1236 Beware that $error can already contain an error on input, in case 1237 multiple modules are run for this hook. Therefore you might want to 1238 return immediately in your hook function in case $error is already 1239 set. 1240 1241 Below is an example of how a function for this hook could look. 1242 This example will disallow the use of the word "bar" in the 1243 message body. 1244 1245 function phorum_mod_foo_check_post ($args) { 1246 list ($message, $error) = $args; 1247 if (!empty($error)) return $args; 1248 1249 if (stristr($message["body"], "bar") !== false) { 1250 return array($message, "The body may not contain 'bar'"); 1251 } 1252 1253 return $args; 1254 } 1255 1256 ---------------------------------------------------------------------------- 1257 close_thread 1258 1259 Where : moderation.php 1260 When : Right after a thread has been closed by a moderator. 1261 Input : The id of the thread that has been closed (read-only). 1262 Return : Same as Input 1263 1264 This hook can be used for performing actions like sending notifications 1265 or making log entries after closing threads. 1266 1267 ---------------------------------------------------------------------------- 1268 common 1269 1270 Where : common.php, so in practice every page 1271 When : Right before the end of the common.php include script. 1272 Input : none 1273 Return : none 1274 1275 This hook can be used for applying custom settings or altering 1276 Phorum settings based on external parameters. 1277 1278 ---------------------------------------------------------------------------- 1279 common_no_forum 1280 1281 Where : common.php, so in practice every page 1282 When : Right after no forum settings were found, before doing the redirect 1283 Input : none 1284 Return : none 1285 1286 This hook can be used for returning some other message (i.e. a 404-page) 1287 to the visitor if the requested forum was not found. 1288 1289 ---------------------------------------------------------------------------- 1290 common_post_user 1291 1292 Where : common.php, so in practice every page 1293 When : Right after loading the user from the database, but just 1294 before making descisions on language and template. 1295 Input : none 1296 Return : none 1297 1298 This hook can be used for applying custom settings or altering 1299 Phorum settings based on external parameters. 1300 1301 ---------------------------------------------------------------------------- 1302 common_pre 1303 1304 Where : common.php, so in practice every page 1305 When : Right after loading the settings from the database, but just 1306 before making descisions on language, template and user. 1307 Input : none 1308 Return : none 1309 1310 This hook can be used for applying custom settings or altering 1311 Phorum settings based on external parameters. 1312 1313 ---------------------------------------------------------------------------- 1314 delete 1315 1316 Where : moderation.php 1317 When : Right after deleting a message from the database. 1318 Input : Array of ids for messages that have been deleted (read-only). 1319 Return : none 1320 1321 This hook can be used for cleaning up anything you may have created 1322 with the post_post hook or any other hook that stored data tied to 1323 messages. 1324 1325 ---------------------------------------------------------------------------- 1326 external 1327 1328 The external hook functions are never called from any of the standard 1329 Phorum pages. These functions are called by invoking script.php on the 1330 command line with the --module parameter. This can be used to pipe 1331 output from some arbitrary command to a specific module, which can do 1332 something with that input. If your module does not need any command 1333 line input and is meant to be run on a regular basis, you should 1334 consider using the scheduled hook. 1335 1336 Mind that for using an external hook, the module in which it is 1337 handled must be enabled in your admin interface. So if an external 1338 hook is not running, the containing module might be disabled. 1339 1340 To run the external hook from the command line, you have to be in 1341 the phorum installation directory. So running the external hook of 1342 a module named "external_foo" would be done like this on a UNIX 1343 system prompt: 1344 1345 # cd /your/phorum/dir 1346 # php ./script.php --module=external_foo 1347 1348 For easy use, you can of course put these commands in a script file. 1349 1350 ---------------------------------------------------------------------------- 1351 failed_login 1352 1353 Where : login.php 1354 When : When a user login fails. 1355 Input : An array containing three fields: username, password and location. 1356 The location field specifies where the login failure occurred and 1357 its value can be either "forum" or "admin". 1358 Return : Same as Input 1359 1360 This hook can be used for tracking failing login attempts. This can be used 1361 for things like logging or implementing login failure penalties (like 1362 temporary denying access after X login attempts). 1363 1364 ---------------------------------------------------------------------------- 1365 file 1366 1367 Where : file.php 1368 When : When attachments are requested. 1369 Input : Two part array where the first element is the mime type already 1370 detected by file.php and the second part is the file array that 1371 contains the filename, file_data, filesize, etc. 1372 Return : Same as Input 1373 1374 This hook could be used to count file downloads, or along with after_attach 1375 an alternate file data storage mechanism could be created. 1376 1377 ---------------------------------------------------------------------------- 1378 format 1379 1380 Where : phorum_format_messages() in include/format_functions.php 1381 When : Everytime phorum_format_messages() is called for formatting 1382 a message, just before it is sent to the templates. 1383 Input : Array of messages. 1384 Return : Same as Input 1385 1386 This hook can be used for applying custom formatting to messages. The 1387 message fields that are most applicable for this are "body" and "author". 1388 When writing a module using this hook, you probably want to format 1389 those fields. In practice you can apply formatting to all the fields 1390 you want. 1391 1392 The changes you make to the messages are for displaying purposes 1393 only, so the changes are not stored in the database. 1394 1395 ---------------------------------------------------------------------------- 1396 hide 1397 1398 Where : moderation.php 1399 When : Right after a message has been hidden by a moderator. 1400 Input : The id of the message that has been hidden (read-only). 1401 Return : Same as Input 1402 1403 This hook can be used for performing actions like sending notifications 1404 or making log entries after hiding a message. 1405 1406 ---------------------------------------------------------------------------- 1407 index 1408 1409 Where : include/index_new.php and include/index_classic.php 1410 When : Right before the list of forums is displayed. 1411 Input : Array of forums. 1412 Return : Same as Input 1413 1414 This hook can be used for changing or adding data to the forums 1415 in the list. 1416 1417 ---------------------------------------------------------------------------- 1418 lang 1419 1420 The lang hook is a only a 'marker'. It flags Phorum that your module 1421 supports multiple languages. It does not take a hook function in 1422 your module information. If you do define a hook function, it will 1423 never be called. 1424 1425 Read section 2.3 for information on the use of multiple languages. 1426 1427 ---------------------------------------------------------------------------- 1428 list 1429 1430 Where : list.php 1431 When : Right before the messages are formatted and displayed. 1432 Input : Array of threads (or messages in threaded mode). 1433 Return : Same as Input 1434 1435 This hook can be used for changing or adding data to the messages 1436 in the list. 1437 1438 ---------------------------------------------------------------------------- 1439 moderation 1440 1441 Where : moderation.php 1442 When : At the start of moderation.php 1443 Input : The id of the moderation step which is run (read-only). 1444 Return : none 1445 1446 This hook can be used for logging moderator actions. You can 1447 use the $PHORUM-array to retrieve additional info like the 1448 moderating user's id and similar. 1449 1450 The moderation step id is the variable $mod_step that is used in 1451 moderation.php. Please read that script to see what moderation 1452 steps are available and for what moderation actions they stand. 1453 1454 When checking the moderation step id for a certain step, always use 1455 the contstants that are defined for this in include/constants.php. 1456 The numerical value of this id can change between Phorum releases. 1457 1458 ---------------------------------------------------------------------------- 1459 move_thread 1460 1461 Where : moderation.php 1462 When : Right after a thread has been moved by a moderator. 1463 Input : The id of the thread that has been moved (read-only). 1464 Return : none 1465 1466 This hook can be used for performing actions like sending notifications 1467 or for making log entries after moving a thread. 1468 1469 ---------------------------------------------------------------------------- 1470 pm_sent 1471 1472 Where : include/controlcenter/pm.php 1473 When : Right after a PM and its email notifications have been sent. 1474 Input : Array containing the private message data (read-only). 1475 Return : none 1476 1477 This hook can be used for performing actions after sending a PM. Before 1478 PM notification by email was put in the Phorum core, this hook was 1479 used to send those notifications. 1480 1481 ---------------------------------------------------------------------------- 1482 post_edit 1483 1484 Where : include/moderation_functions.php 1485 When : Right after storing an edited message in the database. 1486 Input : Array containing message data (read-only). 1487 Return : none 1488 1489 This hook can be used for sending notifications or for making log entries 1490 in the database when editing takes place. 1491 1492 ---------------------------------------------------------------------------- 1493 post_post 1494 1495 Where : post.php 1496 When : After all posting work is done and just before the user is 1497 redirected back to the list. 1498 Input : Array containing message data (read-only). 1499 Return : none 1500 1501 This hook can be used for performing actions based on what the message 1502 contained. 1503 1504 ---------------------------------------------------------------------------- 1505 posting_custom_action 1506 1507 Where : posting.php 1508 When : Right after all the initialization tasks are done and 1509 just before the posting script starts its own action processing. 1510 Input : Array containing message data. 1511 Return : Same as Input 1512 1513 This hook can be used by modules to handle (custom) data coming from the 1514 posting form. The module is allowed to change the data that is in the 1515 input message. When a module needs to change the meta data for a 1516 message, then this is the designated hook for that task. 1517 1518 ---------------------------------------------------------------------------- 1519 posting_init 1520 1521 Where : posting.php 1522 When : Right after the posting.php script's configuration setup and 1523 before starting the posting script processing. 1524 Input : none 1525 Return : none 1526 1527 This hook can be used for doing modifications to the environment 1528 of the posting scripts at an early stage. One of the intended purposes 1529 of this hook is to give mods a chance to change the configuration 1530 of the posting fields in $PHORUM["posting_fields"]. 1531 1532 ---------------------------------------------------------------------------- 1533 posting_permission 1534 1535 Where : posting.php 1536 When : Right after Phorum has determined all abilities that apply 1537 to the logged in user. 1538 Input : none 1539 Ouput : none 1540 1541 This hook can be used for setting up custom abilities and permissions 1542 for users, by updating the applicable fields in $GLOBALS["PHORUM"]["DATA"] 1543 (e.g. for giving certain users the right to make postings sticky, without 1544 having to make the full moderator for a forum). 1545 1546 Read the code in posting.php before this hook is called to find out 1547 what fields can be used. 1548 1549 Beware: Only use this hook if you know what you are doing and understand 1550 Phorum's editor permission code. If used wrong, you can open up security 1551 holes in your Phorum installation! 1552 1553 ---------------------------------------------------------------------------- 1554 pre_edit 1555 1556 Where : include/moderation_functions.php 1557 When : Right before storing an edited message in the database. 1558 Input : Array containing message data. 1559 Return : Same as Input 1560 1561 This hook can be used for changing the message data before storing it 1562 in the database. 1563 1564 ---------------------------------------------------------------------------- 1565 pre_post 1566 1567 Where : post.php 1568 When : Right before storing a new message in the database. 1569 Input : Array containing message data. 1570 Return : Same as Input 1571 1572 This hook can be used for changing the message data before storing it 1573 in the database. 1574 1575 ---------------------------------------------------------------------------- 1576 profile 1577 1578 Where : profile.php and include/controlcenter/summary.php 1579 When : Right before a user profile is displayed. 1580 Input : Array containing user profile data. 1581 Return : Same as Input 1582 1583 This hook can be used for making changes to the profile data. This 1584 is for displaying purposes only, so the changes are not stored in the 1585 database. 1586 1587 ---------------------------------------------------------------------------- 1588 quote 1589 1590 Where : reply.php, read.php (for inline reply form support) 1591 When : Right after the message to reply to has been loaded. 1592 Input : Array containing: 1593 0 => The message author 1594 1 => The message body 1595 Return : The quoted body to use in the post form. 1596 1597 When quoting a message for reply, by default Phorum formats quoted 1598 messages using an old school email style of quoting. By using the quote 1599 hook, you can implement a different quoting mechanism. 1600 1601 Your hook function will retrieve an array containing two elements: 1602 the author and the body of the message to be quoted. The return 1603 value for your hook function must be the quoted body that will 1604 be pre-filled into the reply form. 1605 1606 The BBCode module that is distributed with Phorum has a quote hook 1607 function. Because it does not make sense to have more than one quote 1608 hook active, the BBCode module has an option to disable its quote hook 1609 function. You need to make sure that its quote hook function is disabled 1610 when using your own quote hook. 1611 1612 ---------------------------------------------------------------------------- 1613 read 1614 1615 Where : read.php 1616 When : Right before messages are formatted for displaying. 1617 Input : Array of messages. 1618 Return : Same as Input 1619 1620 This hook can be used for making changes to the message data when 1621 reading messages. This is for displaying purposes only, so the 1622 changes are not stored in the database. 1623 1624 ---------------------------------------------------------------------------- 1625 read_user_info 1626 1627 Where : read.php post.php include/moderation_functions.php 1628 When : Right after retrieving user data. 1629 Input : Array of users. 1630 Return : Same as Input 1631 1632 This hook can be used for changing information for the users before 1633 being displayed. For example: add a border around user signatures. 1634 This is for displaying purposes only, so the changes are not stored 1635 in the database. This hook modifies the MESSAGES->user (in read.tpl) 1636 and MESSAGE->user (read_threads.tpl) data that is available in the 1637 templates. 1638 1639 ---------------------------------------------------------------------------- 1640 readthreads 1641 1642 Where : read.php 1643 When : At the start of the threaded read handling, just before 1644 sorting and displaying the threads. 1645 Input : Array of messages. 1646 Return : Same as Input 1647 1648 This hook does exactly the same as the read hook, except that this 1649 one is only applied to messages when viewing the message list in 1650 threaded mode. 1651 1652 ---------------------------------------------------------------------------- 1653 reopen_thread 1654 1655 Where : moderation.php 1656 When : Right after a thread has been reopened by a moderator. 1657 Input : The id of the thread that has been reopened (read-only). 1658 Return : Same as Input 1659 1660 This hook can be used for performing actions like sending notifications 1661 or making log entries after reopening threads. 1662 1663 ---------------------------------------------------------------------------- 1664 report 1665 1666 Where : report.php 1667 When : Just before a reported message is sent to the moderators. 1668 Input : Array with maildata (see report.php for the exact contents). 1669 Return : Same as Input 1670 1671 This hook can be used for changing the report data that will be 1672 sent to the moderators or for performing actions like making log 1673 entries. 1674 1675 ---------------------------------------------------------------------------- 1676 sanity_checks 1677 1678 Where : include/admin/sanity_checks.php 1679 When : Just before the admin interface's sanity checks are run 1680 Input : Array with sanity checks. Each sanity check is an array with: 1681 function => The function that runs the sanity check 1682 description => A description to show in the admin interface 1683 Return : Same as Input 1684 1685 This hook can be used to add custom sanity checks to the admin 1686 interface option "System Sanity Checks". 1687 1688 Each checking function is expected to return an array containing 1689 two elements: 1690 1691 [0] A status, which can be one of 1692 PHORUM_SANITY_OK No problem found 1693 PHORUM_SANITY_WARN Problem found, but no fatal one 1694 PHORUM_SANITY_CRIT Critical problem found 1695 1696 [1] A description of the problem that was found or NULL. 1697 1698 A general checking function looks like this: 1699 1700 function check_foo() { 1701 $check_ok = ...some check...; 1702 if (!$check_ok) { 1703 return array(PHORUM_SANITY_CRIT, "Foo went wrong because ..."); 1704 } else { 1705 return array(PHORUM_SANITY_OK, NULL); 1706 } 1707 } 1708 1709 ---------------------------------------------------------------------------- 1710 scheduled 1711 1712 Scheduled hook functions are similar to external ones, except these 1713 functions do not require any input from the command line. The modules 1714 containing a scheduled hook are invoked by running script.php with 1715 the --scheduled argument (no module name is taken; this argument 1716 will run all scheduled hooks for all available modules). 1717 1718 Like the name of the hook already suggests, this hook can be used for 1719 creating tasks which have to be executed on a regular basis. To 1720 archieve this, you can let script.php run from a scheduling 1721 service (like a cron job on a UNIX system). 1722 1723 In general, scheduled hooks are used for automating tasks you want 1724 to execute without having to perform any manual action. Practical 1725 uses for a scheduled hook could be housekeeping (cleanup of 1726 stale/old data), daily content generation (like sending daily digests 1727 containing all posted messages for that day) or forum statistics 1728 generation. 1729 1730 Mind that for using a scheduled hook, the module in which it is 1731 handled must be enabled in your admin interface. So if a scheduled 1732 hook is not running, the containing module might be disabled. 1733 1734 To run the scheduled hook from the command line or from a scheduling 1735 service, you have to be in the phorum installation directory. So 1736 running the scheduled hooks for your Phorum installation would 1737 be done like this on a UNIX system prompt: 1738 1739 # cd /your/phorum/dir 1740 # php ./script.php --scheduled 1741 1742 When creating a scheduling service entry for running this 1743 automatically, then remind to change the directory as well. 1744 You might also have to use the full path to your PHP binary 1745 (/usr/bin/php or whatever it is on your system), because 1746 the scheduling service might not know the path to it. An entry 1747 for the cron system on UNIX could look like this: 1748 1749 0 0 * * * cd /your/phorum/dir && /usr/bin/php ./script.php --scheduled 1750 1751 Please refer to your system's documentation to see how to 1752 use your system's scheduling service. 1753 1754 ---------------------------------------------------------------------------- 1755 search 1756 1757 Where : search.php 1758 When : Right before messages are formatted for displaying. 1759 Input : Array of messages. 1760 Return : Same as Input 1761 1762 This hook can be used for making changes to the message data when 1763 searching for messages. This is for displaying purposes only, so the 1764 changes are not stored in the database. 1765 1766 ---------------------------------------------------------------------------- 1767 search_action 1768 1769 Where : search.php 1770 When : Right before the search request to the database 1771 Input : Array of search-request data and a continue flag 1772 Return : Same as Input, continue flag can be set to 0 to avoid the db-call 1773 1774 This hook can be used for using another search application / layer instead 1775 of the buildin one. 1776 1777 ---------------------------------------------------------------------------- 1778 send_mail 1779 1780 Where : include/email_functions.php in the function phorum_email_user() 1781 When : Right before email is sent using PHP's mail() function. 1782 Input : Array with maildata (read-only) containing: 1783 addresses => Array of e-mail addresses, 1784 from => The sender address, 1785 subject => The mail subject, 1786 body => The mail body, 1787 bcc => Whether to use Bcc for mailing multiple recipients 1788 Return : true/false - see description 1789 1790 This hook can be used for implementing an alternative mail sending 1791 system (e.g. like the SMTP module does). The hook should return true if 1792 Phorum should still send the mails himself. If you do not want to have 1793 Phorum send the mails also, return false. 1794 1795 ---------------------------------------------------------------------------- 1796 user_check_login 1797 1798 Where : include/users.php 1799 When : Whenever phorum_user_check_login() is called. 1800 Input : Array containing: 1801 username => the username to check 1802 password => the password to check 1803 user_id => empty value 1804 Return : Same as input 1805 1806 This hook can be used to check user authentication against an external 1807 source. If the hook decides that the username and password are okay, 1808 then it can set the user_id field to the user_id of the authenticated 1809 user. If the hook wants to let Phorum use its standard authentication 1810 mechanism, then it can set user_id to FALSE. 1811 1812 Here is an example (not too useful) hook function: 1813 1814 function phorum_mod_foo_user_check_login($login) 1815 { 1816 // Logging in with john / doe will authenticate the user with 1817 // user_id 1234. 1818 if ($login["username"] == "john" && $login["password"] == "doe") { 1819 $login["user_id"] = 1234; 1820 } 1821 // For all other users, we let Phorum do the authentication. 1822 else 1823 { 1824 $login["user_id"] = FALSE; 1825 } 1826 1827 return $login; 1828 } 1829 1830 Mind that when returning a user_id using this hook, the user data for 1831 the user must be available in Phorum's users table. This hook only 1832 handles the authentication step. So if this hook is used for 1833 authenticating against an external source, somehow the user data 1834 has to be put in Phorum's users table. There are multiple ways of 1835 handling this. Here's two of them: 1836 1837 1) Synchronize the data from the external system when it has changed 1838 there. So if a user is created, changed or deleted on the 1839 external system, that system has to update the Phorum users 1840 table with the new information. The advantage of this method, is 1841 that the users table only is updated when changes occur and that 1842 the users table is always up-to-date with the latest information. 1843 1844 2) Synchronize the data on-the-fly from the user_check_login hook. 1845 As long as the user data is available before that hook has 1846 ended, it will be okay for Phorum. The advantage of this method 1847 is that updating the user data is done in an easy way at the 1848 moment a user logs into Phorum. Disadvantages are that the user 1849 data is only updated at the moment the user logs in and that a 1850 user in only known to Phorum after the first time logging in. 1851 1852 Here's an example of how a hook function that uses on-the-fly 1853 updates could look: 1854 1855 function phorum_mod_foo_user_check_login($login) 1856 { 1857 // Check the authentication against the external system. 1858 $username = $login["username"]; 1859 $password = $login["password"]; 1860 if (! externalsystem_checkauth($username, $password)) { 1861 return $login; 1862 } 1863 1864 // Synchronize the external system with Phorum's users table. 1865 $externaluser = externalsystem_getuser($username); 1866 ...code to put $externaluser in Phorum's user table ... 1867 ...and determine the Phorum $user_id to return ... 1868 1869 // Set the user_id to tell Phorum which user logged in. 1870 $login["user_id"] = $user_id; 1871 1872 return $login; 1873 } 1874 1875 ---------------------------------------------------------------------------- 1876 user_list 1877 1878 Where : include/users.php include/controlcenter/groupmod.php 1879 When : Whenever phorum_user_get_list() is called. 1880 Input : Array containing: 1881 <user_id> => <data> 1882 Where <data> is an array containing: 1883 username => the username for the user 1884 displayname => the way to display the username 1885 Return : Same as Input 1886 1887 This hook can be used for reformatting the list of users in some 1888 way, such as changing the sort order or changing the format of 1889 the displayed names. 1890 1891 1892 4.2 Template hooks 1893 ------------------ 1894 1895 Template hooks are called from within Phorum's template files. 1896 These hooks can be used to extend the user interface with custom 1897 elements. From a hook function for one of these template hooks, the 1898 module writer can print the HTML code that has to be added to the 1899 interface at the postition of the hook call in the template. 1900 1901 1902 ---------------------------------------------------------------------------- 1903 tpl_editor_after_subject 1904 1905 Where : posting_messageform.tpl 1906 When : After the Subject: field in the message editor. 1907 Input : none 1908 Return : none 1909 1910 This hook can be used to add custom form fields to the message editor. 1911 In the default template, the hook is run from within a two column table. 1912 Column one contains the labels and column two the form fields. So your 1913 hook function for adding a field to the editor could look like this: 1914 1915 function phorum_mod_foo_tpl_editor_after_subject() 1916 { 1917 $value = isset($_POST["mod_foo"]) ? $_POST["mod_foo"] : ""; 1918 ?> 1919 <tr> 1920 <td> 1921 Foo field 1922 </td> 1923 <td> 1924 <input type="text" name="mod_foo" 1925 value="<?php print htmlspecialchars($value) ?>"/> 1926 </td> 1927 </tr> 1928 <?php 1929 } 1930 1931 ---------------------------------------------------------------------------- 1932 tpl_cc_usersettings 1933 1934 Where : cc_usersettings.tpl 1935 When : After the built-in usersettings fields. 1936 Input : Array containing the user's current profile. 1937 Return : Same as Input 1938 1939 This hook can be used to add extra fields to the settings pages in the 1940 user's control center. Here's an example hook function that will add 1941 an extra field to the "Edit My Profile" page. 1942 1943 function phorum_mod_foo_tpl_cc_usersettings($profile) 1944 { 1945 // Check if we're on the userprofile page of cc_usersettings.tpl. 1946 if (! isset($profile["USERPROFILE"]) || ! $profile["USERPROFILE"]) 1947 return; 1948 1949 $value = isset($profile["shoesize"]) 1950 ? htmlspecialchars($profile["shoesize"]) : ""; 1951 ?> 1952 <tr> 1953 <td>Shoe size</td> 1954 <td><input name="shoesize" type="text" value="<?=$value?>"></td> 1955 </tr> 1956 <?php 1957 } 1958 1959 ---------------------------------------------------------------------------- 1960 tpl_editor_attachment_buttons 1961 1962 Where : posting_attachments_list.tpl 1963 When : Before the delete button for an attachment. 1964 Input : Array containing attachment information. 1965 Return : Same as Input 1966 1967 This hook can be used to add extra buttons to each attachment in the 1968 editor, so you can do custom actions for attachments. 1969 1970 To make your buttons look the same as Phorum's buttons, use the 1971 CSS class "PhorumSubmit". 1972 1973 Here's an example hook function that will add a button to the attachments, 1974 which will send a javascript alert to the user when clicked. 1975 1976 function phorum_mod_foo_tpl_editor_attachment_buttons($data) 1977 { 1978 $id = $data["file_id"]; 1979 ?> 1980 <input type="submit" class="PhorumSubmit" value="Say it!" 1981 onclick="alert('You clicked attachment id <?php print $id ?>')" /> 1982 <?php 1983 } 1984 1985 ---------------------------------------------------------------------------- 1986 tpl_editor_before_textarea 1987 1988 Where : posting_messageform.tpl 1989 When : Before the textarea. 1990 Input : none 1991 Return : none 1992 1993 This hook can be used to add custom user interface elements before the 1994 textarea in the message editor. 1995 1996 ---------------------------------------------------------------------------- 1997 tpl_editor_buttons 1998 1999 Where : posting_buttons.tpl 2000 When : Before the main editor buttons (like Preview, Post and Cancel). 2001 Input : none 2002 Return : none 2003 2004 This hook can be used to add extra buttons to the editor buttons. 2005 2006 To make your buttons look the same as Phorum's buttons, use the 2007 CSS class "PhorumSubmit". 2008 2009 Here's an example hook function that will add a button to the editor, 2010 which will send a javascript alert to the user when clicked. 2011 2012 function phorum_mod_foo_tpl_editor_buttons() 2013 { ?> 2014 <input type="submit" class="PhorumSubmit" value="Say it!" 2015 onclick="alert('Hello, foo!')" /> 2016 <?php 2017 } 2018 2019 2020 6. Support 2021 ------------------------------------------------------------------------------- 2022 2023 If you have questions about creating modules for Phorum, please visit 2024 the website http://phorum.org/ and ask the development team for help in 2025 the Development forum. 2026
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 12:22:27 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |