Difference between revisions of "Extension:DatabaseFetchHook.php"
(avoid stubs) |
|||
Line 1: | Line 1: | ||
<?php | <?php | ||
− | # Extension:DatabaseFetchHook{{php}}{{Category:Extensions|DatabaseFetchHook}} | + | # Extension:DatabaseFetchHook{{php}}{{Category:Extensions|DatabaseFetchHook}}{{Category:Code that uses voodoo|DatabaseFetchHook}} |
# - See http://www.mediawiki.org/wiki/Extension:DatabaseFetchHook for installation and usage details | # - See http://www.mediawiki.org/wiki/Extension:DatabaseFetchHook for installation and usage details | ||
# - Started: 2007-03-05 | # - Started: 2007-03-05 |
Revision as of 10:02, 23 October 2007
<?php
- Extension:DatabaseFetchHookTemplate:Php
In computer programming, "Voodoo", or "Magic" refers to techniques that are secret or not widely known, and may be deliberately kept secret. The Jargon File makes a distinction between "deep magic", which refers to code based on esoteric theoretical knowledge; "black magic" (voodoo), which refers to code based on techniques that appear to work but which lack a theoretical explanation; and "heavy wizardry", which refers to code based on obscure or undocumented intricacies of particular hardware or software.
At Organic Design the most common of these is extending an instance's class at runtime after it has been instantiated, a technique that can be used to provide additional hooks into existing code without requiring modification of code-base files. Another is reading in a class file, declaring it under a different name, then sub-classing that with a new class of the original name - that way the environment uses the new extended class thinking it's the original one.
See also
- Adding a variable to a class instance at runtime - demonstrated in many different languages
- - See http://www.mediawiki.org/wiki/Extension:DatabaseFetchHook for installation and usage details
- - Started: 2007-03-05
- - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('DFH_VERSION','2.0.0, 2007-10-11');
$wgExtensionCredits['parserhook'][] = array( 'name' => "DatabaseFetchHook", 'author' => 'User:Nad', 'description' => 'Dynamically adds a new hook to intercept the database fetchObject and fetchRow methods', 'url' => 'http://www.mediawiki.org/wiki/Extension:DatabaseFetchHook', 'version' => DFH_VERSION );
$wgExtensionFunctions[] = 'wfSetupDatabaseFetchHook'; function wfSetupDatabaseFetchHook() { global $wgLoadBalancer,$wgDBtype;
wfGetDB(); # This ensures that $wgLoadBalancer is not a stub object when we subclass it
# Create a replica of the Database class which calls the hook in its fetch methods $type = ucfirst($wgDBtype); eval("class Database{$type}2 extends Database{$type}".' {
function fetchObject($res) { $row = parent::fetchObject($res); wfRunHooks("DatabaseFetchHook", array(&$this,&$row)); return $row; }
function fetchRow($res) { $row = parent::fetchRow($res); wfRunHooks("DatabaseFetchHook", array(&$this,&$row)); return $row; } }');
# Create a replica of the LoadBalancer class which uses the new Database class for its connection objects $LoadBalancer = get_class($wgLoadBalancer); $LoadBalancer2 = $LoadBalancer."2"; eval("class $LoadBalancer2 extends $LoadBalancer".' { function reallyOpenConnection(&$server) { $server["type"] .= "2"; $db =& parent::reallyOpenConnection($server); return $db; } }');
# Replace the global $wgLoadBalancer object with an identical instance of the new LoadBalancer2 class $wgLoadBalancer->closeAll(); # Close any open connections as they will be of the original Database class $oldLoadBalancer = $wgLoadBalancer; $wgLoadBalancer = new $LoadBalancer2($oldLoadBalancer->mServers); foreach(array_keys(get_class_vars($LoadBalancer)) as $k) $wgLoadBalancer->$k = $oldLoadBalancer->$k;
}
?>