* Fix notice on search index update due to non-array
[lhc/web/wiklou.git] / includes / BlockCache.php
1 <?php
2 /**
3 * Contain the blockcache class
4 * @package Cache
5 */
6
7 /**
8 * Object for fast lookup of IP blocks
9 * Represents a memcached value, and in some sense, the entire ipblocks table
10 * @package MediaWiki
11 */
12 class BlockCache
13 {
14 var $mData = false, $mMemcKey;
15
16 /**
17 * Constructor
18 * Create a new BlockCache object
19 *
20 * @param Boolean $deferLoad specifies whether to immediately load the data from memcached.
21 * @param String $dbName specifies the memcached dbName prefix to be used. Defaults to $wgDBname.
22 */
23 function BlockCache( $deferLoad = false, $dbName = '' ) {
24 global $wgDBname;
25
26 if ( $dbName == '' ) {
27 $dbName = $wgDBname;
28 }
29
30 $this->mMemcKey = $dbName.':ipblocks';
31
32 if ( !$deferLoad ) {
33 $this->load();
34 }
35 }
36
37 /**
38 * Load the blocks from the database and save them to memcached
39 * @param bool $bFromSlave Whether to load data from slaves or master
40 */
41 function loadFromDB( $bFromSlave = false ) {
42 global $wgUseMemCached, $wgMemc;
43 $this->mData = array();
44 # Selecting FOR UPDATE is a convenient way to serialise the memcached and DB operations,
45 # which is necessary even though we don't update the DB
46 if ( !$bFromSlave ) {
47 Block::enumBlocks( 'wfBlockCacheInsert', '', EB_FOR_UPDATE );
48 #$wgMemc->set( $this->mMemcKey, $this->mData, 0 );
49 } else {
50 Block::enumBlocks( 'wfBlockCacheInsert', '' );
51 }
52 }
53
54 /**
55 * Load the cache from memcached or, if that's not possible, from the DB
56 */
57 function load( $bFromSlave ) {
58 global $wgUseMemCached, $wgMemc;
59
60 if ( $this->mData === false) {
61 $this->loadFromDB( $bFromSlave );
62 /*
63 // Memcache disabled for performance issues.
64 # Try memcached
65 if ( $wgUseMemCached ) {
66 $this->mData = $wgMemc->get( $this->mMemcKey );
67 }
68
69 if ( !is_array( $this->mData ) ) {
70 $this->loadFromDB( $bFromSlave );
71 }*/
72 }
73 }
74
75 /**
76 * Add a block to the cache
77 *
78 * @param Object &$block Reference to a "Block" object.
79 */
80 function insert( &$block ) {
81 if ( $block->mUser == 0 ) {
82 $nb = $block->getNetworkBits();
83 $ipint = $block->getIntegerAddr();
84 $index = $ipint >> ( 32 - $nb );
85
86 if ( !array_key_exists( $nb, $this->mData ) ) {
87 $this->mData[$nb] = array();
88 }
89
90 $this->mData[$nb][$index] = 1;
91 }
92 }
93
94 /**
95 * Find out if a given IP address is blocked
96 *
97 * @param String $ip IP address
98 * @param bool $bFromSlave True means to load check against slave, else check against master.
99 */
100 function get( $ip, $bFromSlave ) {
101 $this->load( $bFromSlave );
102 $ipint = ip2long( $ip );
103 $blocked = false;
104
105 foreach ( $this->mData as $networkBits => $blockInts ) {
106 if ( array_key_exists( $ipint >> ( 32 - $networkBits ), $blockInts ) ) {
107 $blocked = true;
108 break;
109 }
110 }
111 if ( $blocked ) {
112 # Clear low order bits
113 if ( $networkBits != 32 ) {
114 $ip .= '/'.$networkBits;
115 $ip = Block::normaliseRange( $ip );
116 }
117 $block = new Block();
118 $block->forUpdate( $bFromSlave );
119 $block->load( $ip );
120 } else {
121 $block = false;
122 }
123
124 return $block;
125 }
126
127 /**
128 * Clear the local cache
129 * There was once a clear() to clear memcached too, but I deleted it
130 */
131 function clearLocal() {
132 $this->mData = false;
133 }
134 }
135
136 /**
137 * Add a block to the global $wgBlockCache
138 *
139 * @param Object $block A "Block"-object
140 * @param Any $tag unused
141 */
142 function wfBlockCacheInsert( $block, $tag ) {
143 global $wgBlockCache;
144 $wgBlockCache->insert( $block );
145 }