MediaWiki
REL1_22
|
00001 <?php 00029 class LinkCache { 00030 // Increment $mClassVer whenever old serialized versions of this class 00031 // becomes incompatible with the new version. 00032 private $mClassVer = 4; 00033 00034 private $mGoodLinks = array(); 00035 private $mGoodLinkFields = array(); 00036 private $mBadLinks = array(); 00037 private $mForUpdate = false; 00038 private $useDatabase = true; 00039 00043 protected static $instance; 00044 00050 static function &singleton() { 00051 if ( self::$instance ) { 00052 return self::$instance; 00053 } 00054 self::$instance = new LinkCache; 00055 return self::$instance; 00056 } 00057 00063 static function destroySingleton() { 00064 self::$instance = null; 00065 } 00066 00074 static function setSingleton( LinkCache $instance ) { 00075 self::$instance = $instance; 00076 } 00077 00083 public function forUpdate( $update = null ) { 00084 return wfSetVar( $this->mForUpdate, $update ); 00085 } 00086 00091 public function getGoodLinkID( $title ) { 00092 if ( array_key_exists( $title, $this->mGoodLinks ) ) { 00093 return $this->mGoodLinks[$title]; 00094 } else { 00095 return 0; 00096 } 00097 } 00098 00106 public function getGoodLinkFieldObj( $title, $field ) { 00107 $dbkey = $title->getPrefixedDBkey(); 00108 if ( array_key_exists( $dbkey, $this->mGoodLinkFields ) ) { 00109 return $this->mGoodLinkFields[$dbkey][$field]; 00110 } else { 00111 return null; 00112 } 00113 } 00114 00119 public function isBadLink( $title ) { 00120 return array_key_exists( $title, $this->mBadLinks ); 00121 } 00122 00133 public function addGoodLinkObj( $id, $title, $len = -1, $redir = null, $revision = false, $model = false ) { 00134 $dbkey = $title->getPrefixedDBkey(); 00135 $this->mGoodLinks[$dbkey] = intval( $id ); 00136 $this->mGoodLinkFields[$dbkey] = array( 00137 'length' => intval( $len ), 00138 'redirect' => intval( $redir ), 00139 'revision' => intval( $revision ), 00140 'model' => intval( $model ) ); 00141 } 00142 00150 public function addGoodLinkObjFromRow( $title, $row ) { 00151 $dbkey = $title->getPrefixedDBkey(); 00152 $this->mGoodLinks[$dbkey] = intval( $row->page_id ); 00153 $this->mGoodLinkFields[$dbkey] = array( 00154 'length' => intval( $row->page_len ), 00155 'redirect' => intval( $row->page_is_redirect ), 00156 'revision' => intval( $row->page_latest ), 00157 'model' => !empty( $row->page_content_model ) ? strval( $row->page_content_model ) : null, 00158 ); 00159 } 00160 00164 public function addBadLinkObj( $title ) { 00165 $dbkey = $title->getPrefixedDBkey(); 00166 if ( !$this->isBadLink( $dbkey ) ) { 00167 $this->mBadLinks[$dbkey] = 1; 00168 } 00169 } 00170 00171 public function clearBadLink( $title ) { 00172 unset( $this->mBadLinks[$title] ); 00173 } 00174 00178 public function clearLink( $title ) { 00179 $dbkey = $title->getPrefixedDBkey(); 00180 unset( $this->mBadLinks[$dbkey] ); 00181 unset( $this->mGoodLinks[$dbkey] ); 00182 unset( $this->mGoodLinkFields[$dbkey] ); 00183 } 00184 00185 public function getGoodLinks() { 00186 return $this->mGoodLinks; 00187 } 00188 00189 public function getBadLinks() { 00190 return array_keys( $this->mBadLinks ); 00191 } 00192 00199 public function addLink( $title ) { 00200 $nt = Title::newFromDBkey( $title ); 00201 if ( $nt ) { 00202 return $this->addLinkObj( $nt ); 00203 } else { 00204 return 0; 00205 } 00206 } 00207 00214 public function useDatabase( $value = null ) { 00215 if ( $value !== null ) { 00216 $this->useDatabase = (bool)$value; 00217 } 00218 return $this->useDatabase; 00219 } 00220 00227 public function addLinkObj( $nt ) { 00228 global $wgAntiLockFlags, $wgContentHandlerUseDB; 00229 00230 wfProfileIn( __METHOD__ ); 00231 00232 $key = $nt->getPrefixedDBkey(); 00233 if ( $this->isBadLink( $key ) || $nt->isExternal() ) { 00234 wfProfileOut( __METHOD__ ); 00235 return 0; 00236 } 00237 $id = $this->getGoodLinkID( $key ); 00238 if ( $id != 0 ) { 00239 wfProfileOut( __METHOD__ ); 00240 return $id; 00241 } 00242 00243 if ( $key === '' ) { 00244 wfProfileOut( __METHOD__ ); 00245 return 0; 00246 } 00247 00248 if( !$this->useDatabase ) { 00249 return 0; 00250 } 00251 00252 # Some fields heavily used for linking... 00253 if ( $this->mForUpdate ) { 00254 $db = wfGetDB( DB_MASTER ); 00255 if ( !( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) ) { 00256 $options = array( 'FOR UPDATE' ); 00257 } else { 00258 $options = array(); 00259 } 00260 } else { 00261 $db = wfGetDB( DB_SLAVE ); 00262 $options = array(); 00263 } 00264 00265 $f = array( 'page_id', 'page_len', 'page_is_redirect', 'page_latest' ); 00266 if ( $wgContentHandlerUseDB ) { 00267 $f[] = 'page_content_model'; 00268 } 00269 00270 $s = $db->selectRow( 'page', $f, 00271 array( 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ), 00272 __METHOD__, $options ); 00273 # Set fields... 00274 if ( $s !== false ) { 00275 $this->addGoodLinkObjFromRow( $nt, $s ); 00276 $id = intval( $s->page_id ); 00277 } else { 00278 $this->addBadLinkObj( $nt ); 00279 $id = 0; 00280 } 00281 00282 wfProfileOut( __METHOD__ ); 00283 return $id; 00284 } 00285 00289 public function clear() { 00290 $this->mGoodLinks = array(); 00291 $this->mGoodLinkFields = array(); 00292 $this->mBadLinks = array(); 00293 } 00294 }