MediaWiki  REL1_22
LinkCache.php
Go to the documentation of this file.
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 }