[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/docs/ -> hook_system.html (source)

   1  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
   2  <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en" xml:lang="en">
   3  <head>
   4  
   5  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
   6  <meta http-equiv="content-style-type" content="text/css" />
   7  <meta http-equiv="content-language" content="en" />
   8  <meta http-equiv="imagetoolbar" content="no" />
   9  <meta name="resource-type" content="document" />
  10  <meta name="distribution" content="global" />
  11  <meta name="copyright" content="phpBB Group" />
  12  <meta name="keywords" content="" />
  13  <meta name="description" content="Hook System explanation" />
  14  <title>phpBB3 &bull; Hook System</title>
  15  
  16  <style type="text/css">
  17  /* <![CDATA[ */
  18  
  19  /*
  20      The original "prosilver" theme for phpBB3
  21      Created by subBlue design :: http://www.subBlue.com
  22  */
  23  
  24  * { margin: 0; padding: 0; }
  25  
  26  html { font-size: 100%; height: 100%; margin-bottom: 1px; }
  27  
  28  body {
  29      font-family: Verdana, Helvetica, Arial, sans-serif;
  30      color: #828282;
  31      background-color: #FFFFFF;
  32      font-size: 12px;
  33      margin: 0;
  34      padding: 12px 0;
  35  }
  36  
  37  img { border-width: 0; }
  38  
  39  p {
  40      line-height: 1.3em;
  41      font-size: 1.1em;
  42      margin-bottom: 1.5em;
  43  }
  44  
  45  hr {
  46      border: 0 none #FFFFFF;
  47      border-top: 1px solid #CCCCCC;
  48      height: 1px;
  49      margin: 5px 0;
  50      display: block;
  51      clear: both;
  52  }
  53  
  54  html, body {
  55      color: #536482;
  56      background-color: #FFFFFF;
  57  }
  58  
  59  #doc-description h1 {
  60      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  61      margin-right: 200px;
  62      color: #FFFFFF;
  63      margin-top: 15px;
  64      font-weight: bold;
  65      font-size: 2em;
  66      color: #fff;
  67  }
  68  
  69  h1 {
  70      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  71      font-weight: normal;
  72      color: #000;
  73      font-size: 2em;
  74      margin: 0.8em 0 0.2em 0;
  75  }
  76  
  77  h2 {
  78      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
  79      font-weight: normal;
  80      color: #28313F;
  81      font-size: 1.5em;
  82      margin: 0.8em 0 0.2em 0;
  83  }
  84  
  85  h3 {
  86      font-family: Arial, Helvetica, sans-serif;
  87      font-weight: bold;
  88      border-bottom: 1px solid #CCCCCC;
  89      margin-bottom: 3px;
  90      padding-bottom: 2px;
  91      font-size: 1.05em;
  92      color: #115098;
  93      margin-top: 20px;
  94  }
  95  
  96  .good { color: green; }
  97  .bad { color: red; }
  98  
  99  .version {
 100      margin-top: 20px;
 101      text-align: left;
 102      font-size: 70%;
 103      color: #006600;
 104      border-top: 1px solid #ccc;
 105  }
 106  
 107  code {
 108      color: #006600;
 109      font-weight: normal;
 110      font-family: 'Courier New', monospace;
 111      border-color: #D1D7DC;
 112      border-width: 1px;
 113      border-style: solid;
 114      background-color: #FAFAFA;
 115  }
 116  
 117  #wrap {
 118      padding: 0 20px;
 119      min-width: 650px;
 120  }
 121  
 122  #simple-wrap {
 123      padding: 6px 10px;
 124  }
 125  
 126  #page-body {
 127      margin: 4px 0;
 128      clear: both;
 129  }
 130  
 131  #page-footer {
 132      clear: both;
 133  }
 134  
 135  #logo {
 136      float: left;
 137      width: auto;
 138      padding: 10px 13px 0 10px;
 139  }
 140  
 141  a#logo:hover {
 142      text-decoration: none;
 143  }
 144  
 145  #doc-description {
 146      float: left;
 147      width: 70%;
 148  }
 149  
 150  #doc-description h1 {
 151      margin-right: 0;
 152  }
 153  
 154  .headerbar {
 155      background: #ebebeb none repeat-x 0 0;
 156      color: #FFFFFF;
 157      margin-bottom: 4px;
 158      padding: 0 5px;
 159  }
 160  
 161  span.corners-top, span.corners-bottom, span.corners-top span, span.corners-bottom span {
 162      font-size: 1px;
 163      line-height: 1px;
 164      display: block;
 165      height: 5px;
 166      background-repeat: no-repeat;
 167  }
 168  
 169  span.corners-top {
 170      background-image: none;
 171      background-position: 0 0;
 172      margin: 0 -5px;
 173  }
 174  
 175  span.corners-top span {
 176      background-image: none;
 177      background-position: 100% 0;
 178  }
 179  
 180  span.corners-bottom {
 181      background-image: none;
 182      background-position: 0 100%;
 183      margin: 0 -5px;
 184      clear: both;
 185  }
 186  
 187  span.corners-bottom span {
 188      background-image: none;
 189      background-position: 100% 100%;
 190  }
 191  
 192  .paragraph {
 193      padding: 0 10px;
 194      margin-bottom: 4px;
 195      background-repeat: no-repeat;
 196      background-position: 100% 0;
 197      background-color: #ECF3F7;
 198  }
 199  
 200  .paragraph:target .content {
 201      color: #000000;
 202  }
 203  
 204  .paragraph:target h3 a {
 205      color: #000000;
 206  }
 207  
 208  .content {
 209      color: #333333;
 210  }
 211  
 212  .content h2, .panel h2 {
 213      color: #115098;
 214      border-bottom-color:  #CCCCCC;
 215  }
 216  
 217  a:link    { color: #898989; text-decoration: none; }
 218  a:visited    { color: #898989; text-decoration: none; }
 219  a:hover    { color: #d3d3d3; text-decoration: underline; }
 220  a:active    { color: #d2d2d2; text-decoration: none; }
 221  
 222  hr {
 223      border-color: #FFFFFF;
 224      border-top-color: #CCCCCC;
 225  }
 226  
 227  .menu {
 228      background-color: #cadceb;
 229  }
 230  
 231  .headerbar {
 232      background-color: #12A3EB;
 233      background-image: url("bg_header.gif");
 234      color: #FFFFFF;
 235  }
 236  
 237  .panel {
 238      background-color: #ECF1F3;
 239      color: #28313F;
 240  }
 241  
 242  
 243  span.corners-top {
 244      background-image: url("corners_left.png");
 245  }
 246  
 247  span.corners-top span {
 248      background-image: url("corners_right.png");
 249  }
 250  
 251  span.corners-bottom {
 252      background-image: url("corners_left.png");
 253  }
 254  
 255  span.corners-bottom span {
 256      background-image: url("corners_right.png");
 257  }
 258  
 259  .error {
 260      color: #BC2A4D;
 261  }
 262  
 263  a:link    { color: #105289; }
 264  a:visited    { color: #105289; }
 265  a:hover    { color: #D31141; }
 266  a:active    { color: #368AD2; }
 267  
 268  .paragraph span.corners-top, .paragraph span.corners-bottom {
 269      margin: 0 -10px;
 270  }
 271  
 272  .content {
 273      padding: 0;
 274      line-height: 1.48em;
 275      color: #333333;
 276  }
 277  
 278  .content h2, .panel h2 {
 279      color: #115098;
 280      border-bottom-color:  #CCCCCC;
 281  }
 282  
 283  .notice {
 284      border-top-color:  #CCCCCC;
 285  }
 286  
 287  .codebox {
 288      padding: 3px;
 289      background-color: #FFFFFF;
 290      border: 1px solid #C9D2D8;
 291      font-size: 1em;
 292      margin-bottom: 10px;
 293      display: block;
 294      font: 0.9em Monaco, "Andale Mono","Courier New", Courier, mono;
 295      line-height: 1.3em;
 296  }
 297  
 298  * html hr { margin: 0; }
 299  * html span.corners-top, * html span.corners-bottom { background-image: url("corners_left.gif"); }
 300  * html span.corners-top span, * html span.corners-bottom span { background-image: url("corners_right.gif"); }
 301  
 302  .back2top {
 303      clear: both;
 304      height: 11px;
 305      text-align: right;
 306  }
 307  
 308  .content ol {
 309      margin-left: 25px;
 310  }
 311  
 312  /* ]]> */
 313  </style>
 314  
 315  </head>
 316  
 317  <body id="phpbb" class="section-docs">
 318  
 319  <div id="wrap">
 320      <a id="top" name="top" accesskey="t"></a>
 321      <div id="page-header">
 322          <div class="headerbar">
 323              <div class="inner"><span class="corners-top"><span></span></span>
 324  
 325              <div id="doc-description">
 326                  <a href="../index.php" id="logo"><img src="site_logo.gif" alt="" /></a>
 327                  <h1>Hook System</h1>
 328                  <p>This is an explanation of how to use the phpBB3 hook system.</p>
 329                  <p style="display: none;"><a href="#start_here">Skip</a></p>
 330              </div>
 331  
 332              <span class="corners-bottom"><span></span></span></div>
 333          </div>
 334      </div>
 335  
 336      <a name="start_here"></a>
 337  
 338      <div id="page-body">
 339  
 340      <h1>Hook System</h1>
 341  
 342      <div class="paragraph menu">
 343          <div class="inner"><span class="corners-top"><span></span></span>
 344  
 345          <div class="content">
 346  
 347              <ol>
 348                  <li><a href="#intro">Introduction</a></li>
 349                  <li><a href="#use">Allow hooks in functions/methods</a></li>
 350                  <li><a href="#register">Registering hooks</a></li>
 351                  <li><a href="#return">Result returning</a></li>
 352                  <li><a href="#embed">Embedding your hook files/classes/methods</a></li>
 353                  <li><a href="#disclaimer">Copyright and disclaimer</a></li>
 354              </ol>
 355  
 356          </div>
 357  
 358          <span class="corners-bottom"><span></span></span></div>
 359      </div>
 360  
 361      <hr />
 362  
 363      <a name="intro"></a><h2>1. Introduction</h2>
 364  
 365      <div class="paragraph">
 366          <div class="inner"><span class="corners-top"><span></span></span>
 367  
 368          <div class="content">
 369  
 370  <h3>What is it?</h3>
 371  
 372  <p>The hook system allows applicaton and mod developers to hook into phpBB's or their own functions.</p>
 373  
 374  <h3>Pre-defined hookable phpBB3 functions</h3>
 375  
 376  <p>In phpBB3 there are four functions you are able to hook into with your custom functions:</p>
 377  
 378  <p><code>phpbb_user_session_handler();</code> which is called within user::setup after the session and the user object is correctly initialized.<br />
 379  <code>append_sid($url, $params = false, $is_amp = true, $session_id = false);</code> which is called for building urls (appending the session id)<br />
 380  <code>$template-&gt;display($handle, $include_once = true);</code> which is called directly before outputting the (not-yet-compiled) template.<br />
 381  <code>exit_handler();</code> which is called at the very end of phpBB3's execution.</p>
 382  
 383  <p>Please note: The <code>$template-&gt;display</code> hook takes a third <code>$template</code> argument, which is the template instance being used, which should be used instead of the global.</p>
 384  
 385  <p>There are also valid external constants you may want to use if you embed phpBB3 into your application:</p>
 386  
 387  <div class="codebox"><pre>
 388  PHPBB_MSG_HANDLER (overwrite message handler)
 389  PHPBB_DB_NEW_LINK (overwrite new_link parameter for sql_connect)
 390  PHPBB_ROOT_PATH   (overwrite $phpbb_root_path)
 391  PHPBB_ADMIN_PATH  (overwrite $phpbb_admin_path)
 392  PHPBB_USE_BOARD_URL_PATH (use generate_board_url() for image paths instead of $phpbb_root_path)
 393  </pre></div>
 394  
 395  <p>If the <code>PHPBB_USE_BOARD_URL_PATH</code> constant is set to true, phpBB uses generate_board_url() (this will return the boards url with the script path included) on all instances where web-accessible images are loaded. The exact locations are:</p>
 396  
 397  <ul>
 398      <li>/includes/session.php - user::img()</li>
 399      <li>/includes/functions_content.php - smiley_text()</li>
 400  </ul>
 401  
 402  <p>Path locations for the following template variables are affected by this too:</p>
 403  
 404  <ul>
 405      <li>{T_THEME_PATH} - styles/xxx/theme</li>
 406      <li>{T_TEMPLATE_PATH} - styles/xxx/template</li>
 407      <li>{T_SUPER_TEMPLATE_PATH} - styles/xxx/template</li>
 408      <li>{T_IMAGESET_PATH} - styles/xxx/imageset</li>
 409      <li>{T_IMAGESET_LANG_PATH} - styles/xxx/imageset/yy</li>
 410      <li>{T_IMAGES_PATH} - images/</li>
 411      <li>{T_SMILIES_PATH} - $config['smilies_path']/</li>
 412      <li>{T_AVATAR_PATH} - $config['avatar_path']/</li>
 413      <li>{T_AVATAR_GALLERY_PATH} - $config['avatar_gallery_path']/</li>
 414      <li>{T_ICONS_PATH} - $config['icons_path']/</li>
 415      <li>{T_RANKS_PATH} - $config['ranks_path']/</li>
 416      <li>{T_UPLOAD_PATH} - $config['upload_path']/</li>
 417      <li>{T_STYLESHEET_LINK} - styles/xxx/theme/stylesheet.css (or link to style.php if css is parsed dynamically)</li>
 418      <li>New template variable {BOARD_URL} for the board url + script path.</li>
 419  </ul>
 420  
 421  
 422          </div>
 423  
 424          <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
 425  
 426          <span class="corners-bottom"><span></span></span></div>
 427      </div>
 428  
 429      <a name="use"></a><h2>2. Allow hooks in functions/methods</h2>
 430  
 431      <div class="paragraph">
 432          <div class="inner"><span class="corners-top"><span></span></span>
 433  
 434          <div class="content">
 435  
 436  <p>The following examples explain how phpBB3 utilize the in-build hook system. You will be more interested in registering your hooks, but showing you this may help you understand the system better along the way.</p>
 437  
 438  <p>First of all, this is how a function need to be layed out if you want to allow it to be hookable...</p>
 439  
 440  <div class="codebox"><pre>
 441  function my_own_function($my_first_parameter, $my_second_parameter)
 442  {
 443      global $phpbb_hook;
 444  
 445      if ($phpbb_hook-&gt;call_hook(__FUNCTION__, $my_first_parameter, $my_second_parameter))
 446      {
 447          if ($phpbb_hook-&gt;hook_return(__FUNCTION__))
 448          {
 449              return $phpbb_hook-&gt;hook_return_result(__FUNCTION__);
 450          }
 451      }
 452  
 453      [YOUR CODE HERE]
 454  }
 455  </pre></div>
 456  
 457  <p>Above, the call_hook function should always be mapping your function call... in regard to the number of parameters passed.</p>
 458  
 459  <p>This is how you could make a method being hookable...</p>
 460  
 461  <div class="codebox"><pre>
 462  class my_hookable_object
 463  {
 464  	function hook_me($my_first_parameter, $my_second_parameter)
 465      {
 466          global $phpbb_hook;
 467  
 468          if ($phpbb_hook-&gt;call_hook(array(__CLASS__, __FUNCTION__), $my_first_parameter, $my_second_parameter))
 469          {
 470              if ($phpbb_hook-&gt;hook_return(array(__CLASS__, __FUNCTION__)))
 471              {
 472                  return $phpbb_hook-&gt;hook_return_result(array(__CLASS__, __FUNCTION__));
 473              }
 474          }
 475  
 476          [YOUR CODE HERE]
 477      }
 478  }
 479  </pre></div>
 480  
 481  <p>The only difference about calling it is the way you define the first parameter. For a function it is only <code>__FUNCTION__</code>, for a method it is <code>array(__CLASS__, __FUNCTION__)</code>. In PHP4 __CLASS__ is always returning the class in lowercase.</p>
 482  
 483  <p>Now, in phpBB there are some pre-defined hooks available, but how do you make your own hookable function available (and therefore allowing others to hook into it)? For this, there is the add_hook() method:</p>
 484  
 485  <div class="codebox"><pre>
 486  // Adding your own hookable function:
 487  $phpbb_hook-&gt;add_hook('my_own_function');
 488  
 489  // Adding your own hookable method:
 490  $phpbb_hook-&gt;add_hook(array('my_hookable_object', 'hook_me'));
 491  </pre></div>
 492  
 493  <p>You are also able to remove the possibility of hooking a function/method by calling <code>$phpbb_hook-&gt;remove_hook()</code> with the same parameters as add_hook().<br />
 494  This comes in handy if you want to force some hooks not to be called - at all.</p>
 495  
 496          </div>
 497  
 498          <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
 499  
 500          <span class="corners-bottom"><span></span></span></div>
 501      </div>
 502  
 503      <a name="register"></a><h2>3. Registering hooks</h2>
 504  
 505      <div class="paragraph">
 506          <div class="inner"><span class="corners-top"><span></span></span>
 507  
 508          <div class="content">
 509  
 510          <h3>Registering hooks</h3>
 511  
 512  <p>Now to actually defining your functions which should be called. For this we take the append_sid() function as an example (this function is able to be hooked by default). We create two classes, one being static and a function:</p>
 513  
 514  <div class="codebox"><pre>
 515  class my_append_sid_class
 516  {
 517      // Our functions
 518  	function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 519      {
 520          // Get possible previous results
 521          $result = $hook-&gt;previous_hook_result('append_sid');
 522  
 523          return $result['result'] . '&lt;br /&gt;And i was the second one.';
 524      }
 525  }
 526  
 527  // Yet another class :o
 528  class my_second_append_sid_class
 529  {
 530  	function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 531      {
 532          // Get possible previous results
 533          $result = $hook-&gt;previous_hook_result('append_sid');
 534  
 535          echo $result['result'] . '&lt;br /&gt;I was called as the third one.';
 536      }
 537  }
 538  
 539  // And a normal function
 540  function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 541  {
 542      // Get possible previous results
 543      $result = $hook-&gt;previous_hook_result('append_sid');
 544  
 545      return 'I was called as the first one';
 546  }
 547  
 548  // Initializing the second class
 549  $my_second_append_sid_class = new my_second_append_sid_class();
 550  </pre></div>
 551  
 552  <p>Make sure you add the same parameters to your function as is defined for the hookable function with one exception: The first variable is always <code>&amp;$hook</code>... this is the hook object itself you are able to operate on.</p>
 553  
 554  <p>Now we register the hooks one by one with the <code>$phpbb_hook-&gt;register()</code> method:</p>
 555  
 556  <div class="codebox"><pre>
 557  // Now, we register our append_sid &quot;replacements&quot; in a stacked way...
 558  // Registering the function (this is called first)
 559  $phpbb_hook-&gt;register('append_sid', 'my_append_sid');
 560  
 561  // Registering the first class
 562  $phpbb_hook-&gt;register('append_sid', array('my_append_sid_class', 'my_append_sid'));
 563  $phpbb_hook-&gt;register('append_sid', array(&amp;$my_second_append_sid_class, 'my_append_sid'));
 564  </pre></div>
 565  
 566  <p>With this you are even able to make your own functions that are already hooked itself being hooked again...</p>
 567  
 568  <div class="codebox"><pre>
 569  // Registering hook, which will be called
 570  $phpbb_hook-&gt;register('append_sid', 'my_own_append_sid');
 571  
 572  // Add hook to our called hook function
 573  $phpbb_hook-&gt;add_hook('my_own_append_sid');
 574  
 575  // Register added hook
 576  $phpbb_hook-&gt;register('my_own_append_sid', 'also_my_own_append_sid');
 577  </pre></div>
 578  
 579          <h3>Special treatment/chains</h3>
 580  
 581          <p>The <code>register</code> method is able to take a third argument to specify a special 'chain' mode. The valid modes are <code>first</code>, <code>last</code> and <code>standalone</code></p>
 582  
 583          <p><code>$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid', 'first')</code> would make sure that the function is called in the beginning of the chain. It is possible that more than one function is called within the first block - here the FIFO principle is used.</p>
 584  
 585          <p><code>$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid', 'last')</code> would make sure that the function is called at the very end of the chain. It is possible that more than one function is called within the last block - here the FIFO principle is used.</p>
 586  
 587          <p><code>$phpbb_hook-&gt;register('append_sid', 'my_own_append_sid', 'standalone')</code> makes sure only the defined function is called. All other functions are removed from the chain and no other functions are added to it later on. If two applications try to trigger the standalone mode a PHP notice will be printed and the second function being discarded.</p>
 588  
 589          <h3>Only allowing hooks for some objects</h3>
 590  
 591          <p>Because the hook system is not able to differate between initialized objects and only operate on the class, you need to solve this on the code level.</p>
 592  
 593          <p>One possibility would be to use a property:</p>
 594  
 595          <div class="codebox"><pre>
 596  class my_hookable_object
 597  {
 598  	function blabla()
 599      {
 600      }
 601  }
 602  
 603  class my_hookable_object2 extends my_hookable_object
 604  {
 605      var $call_hook = true;
 606  
 607  	function hook_me($my_first_parameter, $my_second_parameter)
 608      {
 609          if ($this-&gt;call_hook)
 610          {
 611              global $phpbb_hook;
 612  
 613              if ($phpbb_hook-&gt;call_hook(array(__CLASS__, __FUNCTION__), $my_first_parameter, $my_second_parameter))
 614              {
 615                  if ($phpbb_hook-&gt;hook_return(array(__CLASS__, __FUNCTION__)))
 616                  {
 617                      return $phpbb_hook-&gt;hook_return_result(array(__CLASS__, __FUNCTION__));
 618                  }
 619              }
 620          }
 621  
 622          return 'not hooked';
 623      }
 624  }
 625  
 626  function hooking(&amp;$hook, $first, $second)
 627  {
 628      return 'hooked';
 629  }
 630  
 631  $first_object = new my_hookable_object2();
 632  $second_object = new my_hookable_object2();
 633  
 634  $phpbb_hook-&gt;add_hook(array('my_hookable_object2', 'hook_me'));
 635  
 636  $phpbb_hook-&gt;register(array('my_hookable_object2', 'hook_me'), 'hooking');
 637  
 638  // Do not call the hook for $first_object
 639  $first_object-&gt;call_hook = false;
 640  
 641  echo $first_object-&gt;hook_me('first', 'second') . '&lt;br /&gt;';
 642  echo $second_object-&gt;hook_me('first', 'second') . '&lt;br /&gt;';
 643  </pre></div>
 644  
 645  <p>OUTPUT:</p>
 646  
 647  <div class="codebox"><pre>
 648  not hooked
 649  hooked
 650  </pre></div>
 651  
 652          <p>A different possibility would be using a function variable (which could be left out on passing the function variables to the hook):</p>
 653  
 654          <div class="codebox"><pre>
 655  class my_hookable_object
 656  {
 657  	function blabla()
 658      {
 659      }
 660  }
 661  
 662  class my_hookable_object2 extends my_hookable_object
 663  {
 664  	function hook_me($my_first_parameter, $my_second_parameter, $hook_me = true)
 665      {
 666          if ($hook_me)
 667          {
 668              global $phpbb_hook;
 669  
 670              if ($phpbb_hook-&gt;call_hook(array(__CLASS__, __FUNCTION__), $my_first_parameter, $my_second_parameter))
 671              {
 672                  if ($phpbb_hook-&gt;hook_return(array(__CLASS__, __FUNCTION__)))
 673                  {
 674                      return $phpbb_hook-&gt;hook_return_result(array(__CLASS__, __FUNCTION__));
 675                  }
 676              }
 677          }
 678  
 679          return 'not hooked';
 680      }
 681  }
 682  
 683  function hooking(&amp;$hook, $first, $second)
 684  {
 685      return 'hooked';
 686  }
 687  
 688  $first_object = new my_hookable_object2();
 689  $second_object = new my_hookable_object2();
 690  
 691  $phpbb_hook-&gt;add_hook(array('my_hookable_object2', 'hook_me'));
 692  
 693  $phpbb_hook-&gt;register(array('my_hookable_object2', 'hook_me'), 'hooking');
 694  
 695  echo $first_object-&gt;hook_me('first', 'second', false) . '&lt;br /&gt;';
 696  echo $second_object-&gt;hook_me('first', 'second') . '&lt;br /&gt;';
 697          </pre></div>
 698  
 699          <p>OUTPUT:</p>
 700  
 701          <div class="codebox"><pre>
 702  not hooked
 703  hooked
 704          </pre></div>
 705  
 706          </div>
 707  
 708          <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
 709  
 710          <span class="corners-bottom"><span></span></span></div>
 711      </div>
 712  
 713      <a name="return"></a><h2>4. Result returning</h2>
 714  
 715      <div class="paragraph">
 716          <div class="inner"><span class="corners-top"><span></span></span>
 717  
 718          <div class="content">
 719  
 720  <p>Generally, the distinction has to be made if a function returns the result obtained from the called function or continue the execution. Based on the needs of the application this may differ. Therefore, the function returns the results only if the called hook function is returning a result.</p>
 721  
 722  <h3>Case 1 - Returning the result</h3>
 723  
 724  <p>Imagine the following function supporting hooks:</p>
 725  
 726  <div class="codebox"><pre>
 727  function append_sid($url, $params = false, $is_amp = true, $session_id = false)
 728  {
 729      global $_SID, $_EXTRA_URL, $phpbb_hook;
 730  
 731      // Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropiatly.
 732      // They could mimick most of what is within this function
 733      if ($phpbb_hook-&gt;call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
 734      {
 735          if ($phpbb_hook-&gt;hook_return(__FUNCTION__))
 736          {
 737              return $phpbb_hook-&gt;hook_return_result(__FUNCTION__);
 738          }
 739      }
 740  
 741      [...]
 742  }
 743  </pre></div>
 744  
 745  <p>Now, the following function is yours. Since you return a value, the append_sid() function itself is returning it as is:</p>
 746  
 747  <div class="codebox"><pre>
 748  // The function called
 749  function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 750  {
 751      // Get possible previous results
 752      $result = $hook-&gt;previous_hook_result('append_sid');
 753  
 754      return 'Since i return something the append_sid() function will return my result.';
 755  }
 756  </pre></div>
 757  
 758  <p>To be able to get the results returned from functions higher in the change the <code>previous_hook_result()</code> method should always be used, it returns an <code>array('result' => [your result])</code> construct.</p>
 759  
 760  <h3>Case 2 - Not Returning any result</h3>
 761  
 762  <p>Sometimes applications want to return nothing and therefore force the underlying function to continue it's execution:</p>
 763  
 764  <div class="codebox"><pre>
 765  function append_sid($url, $params = false, $is_amp = true, $session_id = false)
 766  {
 767      global $_SID, $_EXTRA_URL, $phpbb_hook;
 768  
 769      // Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropiatly.
 770      // They could mimick most of what is within this function
 771      if ($phpbb_hook-&gt;call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
 772      {
 773          if ($phpbb_hook-&gt;hook_return(__FUNCTION__))
 774          {
 775              return $phpbb_hook-&gt;hook_return_result(__FUNCTION__);
 776          }
 777      }
 778  
 779      [...]
 780  }
 781  
 782  // The function called
 783  function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 784  {
 785      // Get possible previous results
 786      $result = $hook-&gt;previous_hook_result('append_sid');
 787  
 788      [...]
 789  
 790      // I only rewrite some variables, but return nothing. Therefore, the append_sid() function will not return my (non)result.
 791  }
 792  </pre></div>
 793  
 794  <p>Please Note: The decision to return or not return is solely made of the very last function call within the hook chain. An example:</p>
 795  
 796  <div class="codebox"><pre>
 797  // The function called
 798  function my_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 799  {
 800      // Get possible previous results
 801      $result = $hook-&gt;previous_hook_result('append_sid');
 802  
 803      // $result is not filled
 804  
 805      return 'FILLED';
 806  }
 807  
 808  // This function is registered too and gets executed after my_append_sid()
 809  function my_own_append_sid(&amp;$hook, $url, $params = false, $is_amp = true, $session_id = false)
 810  {
 811      $result = $hook->previous_hook_result('append_sid');
 812  
 813      // $result is actually filled with $result['result'] = 'FILLED'
 814      // But i return nothing, therefore append_sid() continues it's execution.
 815  }
 816  
 817  // The way both functions are registered.
 818  $phpbb_hook->register('append_sid', 'my_append_sid');
 819  $phpbb_hook->register('append_sid', 'my_own_append_sid');
 820  </pre></div>
 821  
 822          </div>
 823  
 824          <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
 825  
 826          <span class="corners-bottom"><span></span></span></div>
 827      </div>
 828  
 829      <a name="embed"></a><h2>5. Embedding your hook files/classes/methods</h2>
 830  
 831      <div class="paragraph">
 832          <div class="inner"><span class="corners-top"><span></span></span>
 833  
 834          <div class="content">
 835  
 836  <p>There are basically two methods you are able to choose from:</p>
 837  
 838  <p>1) Add a file to includes/hooks/. The file need to be prefixed by <code>hook_</code>. This file is included within common.php, you are able to register your hooks, include other files or functions, etc. It is advised to only include other files if needed (within a function call for example).</p>
 839  
 840  <p>Please be aware that you need to purge your cache within the ACP to make your newly placed file available to phpBB3.</p>
 841  
 842  <p>2) The second method is meant for those wanting to wrap phpBB3 without placing a custom file to the hooks directory. This is mostly done by including phpBB's files within the application file. To be able to register your hooks you need to create a function within your application:</p>
 843  
 844  <div class="codebox"><pre>
 845  // My function which gets executed within the hooks constuctor
 846  function phpbb_hook_register(&amp;$hook)
 847  {
 848      $hook-&gt;register('append_sid', 'my_append_sid');
 849  }
 850  
 851  [...]
 852  </pre></div>
 853  
 854  <p>You should get the idea. ;)</p>
 855  
 856          </div>
 857  
 858          <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
 859  
 860          <span class="corners-bottom"><span></span></span></div>
 861      </div>
 862  
 863      <a name="disclaimer"></a><h2>6. Copyright and disclaimer</h2>
 864  
 865      <div class="paragraph">
 866          <div class="inner"><span class="corners-top"><span></span></span>
 867  
 868          <div class="content">
 869  
 870      <p>This application is opensource software released under the <a href="http://opensource.org/licenses/gpl-2.0.php">GNU General Public License v2</a>. Please see source code and the docs directory for more details. This package and its contents are Copyright (c) <a href="https://www.phpbb.com/">phpBB Group</a>, All Rights Reserved.</p>
 871  
 872          </div>
 873  
 874          <div class="back2top"><a href="#wrap" class="top">Back to Top</a></div>
 875  
 876          <span class="corners-bottom"><span></span></span></div>
 877      </div>
 878  
 879      <div id="page-footer">
 880          <div class="version">&nbsp;</div>
 881      </div>
 882  </div></div>
 883  
 884  <div>
 885      <a id="bottom" name="bottom" accesskey="z"></a>
 886  </div>
 887  
 888  </body>
 889  </html>


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1