[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/cache/ -> LinkCache.php (source)

   1  <?php
   2  /**
   3   * Page existence cache.
   4   *
   5   * This program is free software; you can redistribute it and/or modify
   6   * it under the terms of the GNU General Public License as published by
   7   * the Free Software Foundation; either version 2 of the License, or
   8   * (at your option) any later version.
   9   *
  10   * This program is distributed in the hope that it will be useful,
  11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13   * GNU General Public License for more details.
  14   *
  15   * You should have received a copy of the GNU General Public License along
  16   * with this program; if not, write to the Free Software Foundation, Inc.,
  17   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18   * http://www.gnu.org/copyleft/gpl.html
  19   *
  20   * @file
  21   * @ingroup Cache
  22   */
  23  
  24  /**
  25   * Cache for article titles (prefixed DB keys) and ids linked from one source
  26   *
  27   * @ingroup Cache
  28   */
  29  class LinkCache {
  30      // Increment $mClassVer whenever old serialized versions of this class
  31      // becomes incompatible with the new version.
  32      private $mClassVer = 4;
  33  
  34      private $mGoodLinks = array();
  35      private $mGoodLinkFields = array();
  36      private $mBadLinks = array();
  37      private $mForUpdate = false;
  38  
  39      /**
  40       * @var LinkCache
  41       */
  42      protected static $instance;
  43  
  44      /**
  45       * Get an instance of this class.
  46       *
  47       * @return LinkCache
  48       */
  49      static function &singleton() {
  50          if ( self::$instance ) {
  51              return self::$instance;
  52          }
  53          self::$instance = new LinkCache;
  54  
  55          return self::$instance;
  56      }
  57  
  58      /**
  59       * Destroy the singleton instance, a new one will be created next time
  60       * singleton() is called.
  61       * @since 1.22
  62       */
  63  	static function destroySingleton() {
  64          self::$instance = null;
  65      }
  66  
  67      /**
  68       * Set the singleton instance to a given object.
  69       * Since we do not have an interface for LinkCache, you have to be sure the
  70       * given object implements all the LinkCache public methods.
  71       * @param LinkCache $instance
  72       * @since 1.22
  73       */
  74  	static function setSingleton( LinkCache $instance ) {
  75          self::$instance = $instance;
  76      }
  77  
  78      /**
  79       * General accessor to get/set whether SELECT FOR UPDATE should be used
  80       *
  81       * @param bool $update
  82       * @return bool
  83       */
  84  	public function forUpdate( $update = null ) {
  85          return wfSetVar( $this->mForUpdate, $update );
  86      }
  87  
  88      /**
  89       * @param string $title
  90       * @return int
  91       */
  92  	public function getGoodLinkID( $title ) {
  93          if ( array_key_exists( $title, $this->mGoodLinks ) ) {
  94              return $this->mGoodLinks[$title];
  95          } else {
  96              return 0;
  97          }
  98      }
  99  
 100      /**
 101       * Get a field of a title object from cache.
 102       * If this link is not good, it will return NULL.
 103       * @param Title $title
 104       * @param string $field ('length','redirect','revision','model')
 105       * @return string|null
 106       */
 107  	public function getGoodLinkFieldObj( $title, $field ) {
 108          $dbkey = $title->getPrefixedDBkey();
 109          if ( array_key_exists( $dbkey, $this->mGoodLinkFields ) ) {
 110              return $this->mGoodLinkFields[$dbkey][$field];
 111          } else {
 112              return null;
 113          }
 114      }
 115  
 116      /**
 117       * @param string $title
 118       * @return bool
 119       */
 120  	public function isBadLink( $title ) {
 121          return array_key_exists( $title, $this->mBadLinks );
 122      }
 123  
 124      /**
 125       * Add a link for the title to the link cache
 126       *
 127       * @param int $id Page's ID
 128       * @param Title $title
 129       * @param int $len Text's length
 130       * @param int $redir Whether the page is a redirect
 131       * @param int $revision Latest revision's ID
 132       * @param string|null $model Latest revision's content model ID
 133       */
 134  	public function addGoodLinkObj( $id, $title, $len = -1, $redir = null,
 135          $revision = 0, $model = null
 136      ) {
 137          $dbkey = $title->getPrefixedDBkey();
 138          $this->mGoodLinks[$dbkey] = (int)$id;
 139          $this->mGoodLinkFields[$dbkey] = array(
 140              'length' => (int)$len,
 141              'redirect' => (int)$redir,
 142              'revision' => (int)$revision,
 143              'model' => $model ? (string)$model : null,
 144          );
 145      }
 146  
 147      /**
 148       * Same as above with better interface.
 149       * @since 1.19
 150       * @param Title $title
 151       * @param stdClass $row Object which has the fields page_id, page_is_redirect,
 152       *  page_latest and page_content_model
 153       */
 154  	public function addGoodLinkObjFromRow( $title, $row ) {
 155          $dbkey = $title->getPrefixedDBkey();
 156          $this->mGoodLinks[$dbkey] = intval( $row->page_id );
 157          $this->mGoodLinkFields[$dbkey] = array(
 158              'length' => intval( $row->page_len ),
 159              'redirect' => intval( $row->page_is_redirect ),
 160              'revision' => intval( $row->page_latest ),
 161              'model' => !empty( $row->page_content_model ) ? strval( $row->page_content_model ) : null,
 162          );
 163      }
 164  
 165      /**
 166       * @param Title $title
 167       */
 168  	public function addBadLinkObj( $title ) {
 169          $dbkey = $title->getPrefixedDBkey();
 170          if ( !$this->isBadLink( $dbkey ) ) {
 171              $this->mBadLinks[$dbkey] = 1;
 172          }
 173      }
 174  
 175  	public function clearBadLink( $title ) {
 176          unset( $this->mBadLinks[$title] );
 177      }
 178  
 179      /**
 180       * @param Title $title
 181       */
 182  	public function clearLink( $title ) {
 183          $dbkey = $title->getPrefixedDBkey();
 184          unset( $this->mBadLinks[$dbkey] );
 185          unset( $this->mGoodLinks[$dbkey] );
 186          unset( $this->mGoodLinkFields[$dbkey] );
 187      }
 188  
 189  	public function getGoodLinks() {
 190          return $this->mGoodLinks;
 191      }
 192  
 193  	public function getBadLinks() {
 194          return array_keys( $this->mBadLinks );
 195      }
 196  
 197      /**
 198       * Add a title to the link cache, return the page_id or zero if non-existent
 199       *
 200       * @param string $title Title to add
 201       * @return int
 202       */
 203  	public function addLink( $title ) {
 204          $nt = Title::newFromDBkey( $title );
 205          if ( $nt ) {
 206              return $this->addLinkObj( $nt );
 207          } else {
 208              return 0;
 209          }
 210      }
 211  
 212      /**
 213       * Add a title to the link cache, return the page_id or zero if non-existent
 214       *
 215       * @param Title $nt Title object to add
 216       * @return int
 217       */
 218  	public function addLinkObj( $nt ) {
 219          global $wgAntiLockFlags, $wgContentHandlerUseDB;
 220  
 221          wfProfileIn( __METHOD__ );
 222  
 223          $key = $nt->getPrefixedDBkey();
 224          if ( $this->isBadLink( $key ) || $nt->isExternal() ) {
 225              wfProfileOut( __METHOD__ );
 226  
 227              return 0;
 228          }
 229          $id = $this->getGoodLinkID( $key );
 230          if ( $id != 0 ) {
 231              wfProfileOut( __METHOD__ );
 232  
 233              return $id;
 234          }
 235  
 236          if ( $key === '' ) {
 237              wfProfileOut( __METHOD__ );
 238  
 239              return 0;
 240          }
 241  
 242          # Some fields heavily used for linking...
 243          if ( $this->mForUpdate ) {
 244              $db = wfGetDB( DB_MASTER );
 245              if ( !( $wgAntiLockFlags & ALF_NO_LINK_LOCK ) ) {
 246                  $options = array( 'FOR UPDATE' );
 247              } else {
 248                  $options = array();
 249              }
 250          } else {
 251              $db = wfGetDB( DB_SLAVE );
 252              $options = array();
 253          }
 254  
 255          $f = array( 'page_id', 'page_len', 'page_is_redirect', 'page_latest' );
 256          if ( $wgContentHandlerUseDB ) {
 257              $f[] = 'page_content_model';
 258          }
 259  
 260          $s = $db->selectRow( 'page', $f,
 261              array( 'page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey() ),
 262              __METHOD__, $options );
 263          # Set fields...
 264          if ( $s !== false ) {
 265              $this->addGoodLinkObjFromRow( $nt, $s );
 266              $id = intval( $s->page_id );
 267          } else {
 268              $this->addBadLinkObj( $nt );
 269              $id = 0;
 270          }
 271  
 272          wfProfileOut( __METHOD__ );
 273  
 274          return $id;
 275      }
 276  
 277      /**
 278       * Clears cache
 279       */
 280  	public function clear() {
 281          $this->mGoodLinks = array();
 282          $this->mGoodLinkFields = array();
 283          $this->mBadLinks = array();
 284      }
 285  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1