8if ( !class_exists( 
'UtfNormal' ) ) {
 
    9        require_once( dirname(__FILE__) . 
'/normal/UtfNormal.php' );
 
   12define ( 
'GAID_FOR_UPDATE', 1 );
 
   14# Title::newFromTitle maintains a cache to avoid 
   15# expensive re-normalization of commonly used titles. 
   16# On a batch operation this can become a memory leak 
   17# if not bounded. After hitting this many titles, 
   19define( 
'MW_TITLECACHE_MAX', 1000 );
 
   21# Constants for pr_cascade bitfield 
   22define( 
'CASCADE', 1 );
 
   47        var 
$mTextform;                 # Text form (spaces not underscores) of the main part
 
   50        var 
$mNamespace;                # Namespace index, i.e. one of the NS_xxxx constants
 
   52        var 
$mFragment;                 
# Title fragment (i.e. the bit after the #) 
   53        var 
$mArticleID;                # Article ID, fetched from the link cache on demand
 
   61        var 
$mPrefixedText;             # Text form including 
namespace/interwiki, initialised on demand
 
   63                                        # Zero except in {{transclusion}} tags 
   73                $this->mInterwiki = $this->mUrlform =
 
   74                $this->mTextform = $this->mDbkeyform = 
'';
 
   75                $this->mArticleID = -1;
 
   76                $this->mNamespace = NS_MAIN;
 
   77                $this->mRestrictionsLoaded = 
false;
 
   78                $this->mRestrictions = array();
 
   79                # Dont change the following, NS_MAIN is hardcoded in several place 
   81                $this->mDefaultNamespace = NS_MAIN;
 
   82                $this->mWatched = NULL;
 
   83                $this->mLatestID = 
false;
 
   84                $this->mOldRestrictions = 
false;
 
   96                $t->mDbkeyform = $key;
 
   97                if( 
$t->secureAndSplit() )
 
  114        public static function newFromText( $text, $defaultNamespace = NS_MAIN ) {
 
  115                if( is_object( $text ) ) {
 
  116                        throw new MWException( 
'Title::newFromText given an object' );
 
  137                $t->mDbkeyform = str_replace( 
' ', 
'_', $filteredText );
 
  138                $t->mDefaultNamespace = $defaultNamespace;
 
  140                static $cachedcount = 0 ;
 
  141                if( 
$t->secureAndSplit() ) {
 
  142                        if( $defaultNamespace == NS_MAIN ) {
 
  144                                        # Avoid memory leaks on mass operations... 
  165                global $wgLegalTitleChars;
 
  168                # For compatibility with old buggy URLs. "+" is usually not valid in titles,
 
  169                # but some URLs used it as a space replacement and they still come 
  170                # from some external search tools. 
  171                if ( strpos( $wgLegalTitleChars, 
'+' ) === 
false ) {
 
  172                        $url = str_replace( 
'+', 
' ', $url );
 
  175                $t->mDbkeyform = str_replace( 
' ', 
'_', $url );
 
  176                if( 
$t->secureAndSplit() ) {
 
  193                $fname = 
'Title::newFromID';
 
  194                $dbr = wfGetDB( DB_SLAVE );
 
  195                $row = $dbr->selectRow( 
'page', array( 
'page_namespace', 
'page_title' ),
 
  196                        array( 
'page_id' => $id ), $fname );
 
  197                if ( 
$row !== 
false ) {
 
  209                $dbr = wfGetDB( DB_SLAVE );
 
  210                $res = $dbr->select( 
'page', array( 
'page_namespace', 
'page_title' ),
 
  211                        'page_id IN (' . $dbr->makeList( $ids ) . 
')', __METHOD__ );
 
  214                while ( 
$row = $dbr->fetchObject( 
$res ) ) {
 
  235                $t->mNamespace = intval( $ns );
 
  236                $t->mDbkeyform = str_replace( 
' ', 
'_', $title );
 
  237                $t->mArticleID = ( $ns >= 0 ) ? -1 : 0;
 
  238                $t->mUrlform = wfUrlencode( 
$t->mDbkeyform );
 
  239                $t->mTextform = str_replace( 
'_', 
' ', $title );
 
  255                if( 
$t->secureAndSplit() ) {
 
  277                $mwRedir = MagicWord::get( 
'redirect' );
 
  279                if ( $mwRedir->matchStart( $text ) ) {
 
  281                        if ( preg_match( 
'/\[{2}(.*?)(?:\||\]{2})/', $text, $m ) ) {
 
  282                                # categories are escaped using : for example one can enter: 
  283                                # #REDIRECT [[:Category:Music]]. Need to remove it. 
  284                                if ( substr($m[1],0,1) == 
':') {
 
  285                                        # We don't want to keep the ':' 
  286                                        $m[1] = substr( $m[1], 1 );
 
  290                                # Disallow redirects to Special:Userlogout 
  291                                if ( !is_null($rt) && $rt->isSpecial( 
'Userlogout' ) ) {
 
  299#---------------------------------------------------------------------------- 
  301#---------------------------------------------------------------------------- 
  312                $fname = 
'Title::nameOf';
 
  313                $dbr = wfGetDB( DB_SLAVE );
 
  315                $s = $dbr->selectRow( 
'page', array( 
'page_namespace',
'page_title' ),  array( 
'page_id' => $id ), $fname );
 
  316                if ( $s === 
false ) { 
return NULL; }
 
  327                global $wgLegalTitleChars;
 
  329                $wgLegalTitleChars = 
" %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+";
 
  331                return $wgLegalTitleChars;
 
  346                $lc = SearchEngine::legalSearchChars() . 
'&#;';
 
  347                $t = $wgContLang->stripForSearch( $title );
 
  348                $t = preg_replace( 
"/[^{$lc}]+/", 
' ', 
$t );
 
  349                $t = $wgContLang->lc( 
$t );
 
  352                $t = preg_replace( 
"/([{$lc}]+)'s( |$)/", 
"\\1 \\1's ", 
$t );
 
  353                $t = preg_replace( 
"/([{$lc}]+)s'( |$)/", 
"\\1s ", 
$t );
 
  355                $t = preg_replace( 
"/\\s+/", 
' ', 
$t );
 
  357                if ( $ns == NS_IMAGE ) {
 
  358                        $t = preg_replace( 
"/ (png|gif|jpg|jpeg|ogg)$/", 
"", 
$t );
 
  372                $n = $wgContLang->getNsText( $ns );
 
  373                return $n == 
'' ? $title : 
"$n:$title";
 
  384                global $wgMemc, $wgInterwikiExpiry;
 
  385                global $wgInterwikiCache, $wgContLang;
 
  389                $fname = 
'Title::getInterwikiLink';
 
  391                $key = $wgContLang->lc( $key );
 
  393                $k = wfMemcKey( 
'interwiki', $key );
 
  398                if ($wgInterwikiCache) {
 
  402                $s = $wgMemc->get( $k );
 
  403                # Ignore old keys with no iw_local 
  404                if( $s && isset( $s->iw_local ) && isset($s->iw_trans)) {
 
  409                $dbr = wfGetDB( DB_SLAVE );
 
  410                $res = $dbr->select( 
'interwiki',
 
  411                        array( 
'iw_url', 
'iw_local', 
'iw_trans' ),
 
  412                        array( 
'iw_prefix' => $key ), $fname );
 
  417                $s = $dbr->fetchObject( 
$res );
 
  419                        # Cache non-existence: create a blank object and save it to memcached 
  425                $wgMemc->set( $k, $s, $wgInterwikiExpiry );
 
  439                global $wgInterwikiCache, $wgInterwikiScopes, $wgInterwikiFallbackSite;
 
  443                        $db=dba_open($wgInterwikiCache,
'r',
'cdb');
 
  445                if ($wgInterwikiScopes>=3 and !$site) {
 
  446                        $site = dba_fetch(
'__sites:' . wfWikiID(), $db);
 
  448                                $site = $wgInterwikiFallbackSite;
 
  450                $value = dba_fetch( wfMemcKey( $key ), $db);
 
  451                if ($value==
'' and $wgInterwikiScopes>=3) {
 
  453                        $value = dba_fetch(
"_{$site}:{$key}", $db);
 
  455                if ($value==
'' and $wgInterwikiScopes>=2) {
 
  457                        $value = dba_fetch(
"__global:{$key}", $db);
 
  466                        list($local,$url)=explode(
' ',$value,2);
 
  468                        $s->iw_local=(int)$local;
 
  481                if ( $this->mInterwiki != 
'' ) {
 
  482                        # Make sure key is loaded into cache 
  484                        $k = wfMemcKey( 
'interwiki', $this->mInterwiki );
 
  498                if ($this->mInterwiki == 
'')
 
  500                # Make sure key is loaded into cache 
  502                $k = wfMemcKey( 
'interwiki', $this->mInterwiki );
 
  510                $fragment = str_replace( 
' ', 
'_', $fragment );
 
  512                $replaceArray = array(
 
  516                return strtr( $fragment, $replaceArray );
 
  519#---------------------------------------------------------------------------- 
  521#---------------------------------------------------------------------------- 
  549                global $wgContLang, $wgCanonicalNamespaceNames;
 
  551                if ( 
'' != $this->mInterwiki ) {
 
  558                        if( isset( $wgCanonicalNamespaceNames[$this->mNamespace] ) ) {
 
  562                return $wgContLang->getNsText( $this->mNamespace );
 
  605                if ( $this->mFragment == 
'' ) {
 
  632                $s = $this->
prefix( $this->mDbkeyform );
 
  633                $s = str_replace( 
' ', 
'_', $s );
 
  643                if ( empty( $this->mPrefixedText ) ) { 
 
  644                        $s = $this->
prefix( $this->mTextform );
 
  645                        $s = str_replace( 
'_', 
' ', $s );
 
  646                        $this->mPrefixedText = $s;
 
  659                if( 
'' != $this->mFragment ) {
 
  670                global $wgNamespacesWithSubpages;
 
  671                if( isset( $wgNamespacesWithSubpages[ $this->mNamespace ] ) && $wgNamespacesWithSubpages[ $this->mNamespace ] ) {
 
  672                        $parts = explode( 
'/', $this->
getText() );
 
  673                        # Don't discard the real title if there's no subpage involved 
  674                        if( count( $parts ) > 1 )
 
  675                                unset( $parts[ count( $parts ) - 1 ] );
 
  676                        return implode( 
'/', $parts );
 
  687                global $wgNamespacesWithSubpages;
 
  688                if( isset( $wgNamespacesWithSubpages[ $this->mNamespace ] ) && $wgNamespacesWithSubpages[ $this->mNamespace ] ) {
 
  689                        $parts = explode( 
'/', $this->mTextform );
 
  690                        return( $parts[ count( $parts ) - 1 ] );
 
  692                        return( $this->mTextform );
 
  702                $text = wfUrlencode( str_replace( 
' ', 
'_', $text ) );
 
  703                $text = str_replace( 
'%28', 
'(', str_replace( 
'%29', 
')', $text ) ); # Clean up the URL; per below, 
this might not be safe
 
  712                $s = $this->
prefix( $this->mDbkeyform );
 
  713                $s = str_replace( 
' ', 
'_', $s );
 
  715                $s = wfUrlencode ( $s ) ;
 
  717                # Cleaning up URL to make it look nice -- is this safe? 
  718                $s = str_replace( 
'%28', 
'(', $s );
 
  719                $s = str_replace( 
'%29', 
')', $s );
 
  734                global $wgContLang, $wgServer, $wgRequest;
 
  736                if ( 
'' == $this->mInterwiki ) {
 
  737                        $url = $this->getLocalUrl( 
$query, $variant );
 
  741                        if ($wgRequest->getVal(
'action') != 
'render') {
 
  742                                $url = $wgServer . $url;
 
  749                                # Can this actually happen? Interwikis shouldn't be parsed. 
  750                                # Yes! It can in interwiki transclusion. But... it probably shouldn't. 
  753                        $url = str_replace( 
'$1', 
$namespace . $this->mUrlform, $baseUrl );
 
  754                        $url = wfAppendQuery( $url, 
$query );
 
  757                # Finally, add the fragment. 
  760                wfRunHooks( 
'GetFullURL', array( &$this, &$url, 
$query ) );
 
  773                global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
 
  774                global $wgVariantArticlePath, $wgContLang, $wgUser;
 
  777                if($variant == 
false && $wgContLang->hasVariants() && !$wgUser->isLoggedIn()){
 
  778                        $pref = $wgContLang->getPreferredVariant(
false);
 
  779                        if($pref != $wgContLang->getCode())
 
  795                                if($variant!=
false && $wgContLang->hasVariants()){
 
  796                                        if($wgVariantArticlePath==
false) {
 
  797                                                $variantArticlePath =  
"$wgScript?title=$1&variant=$2"; 
 
  799                                                $variantArticlePath = $wgVariantArticlePath;
 
  801                                        $url = str_replace( 
'$2', urlencode( $variant ), $variantArticlePath );
 
  802                                        $url = str_replace( 
'$1', $dbkey, $url  );
 
  805                                        $url = str_replace( 
'$1', $dbkey, $wgArticlePath );
 
  808                                global $wgActionPaths;
 
  811                                if( !empty( $wgActionPaths ) &&
 
  812                                        preg_match( 
'/^(.*&|)action=([^&]*)(&(.*)|)$/', 
$query, $matches ) )
 
  814                                        $action = urldecode( $matches[2] );
 
  815                                        if( isset( $wgActionPaths[$action] ) ) {
 
  817                                                if( isset( $matches[4] ) ) 
$query .= $matches[4];
 
  818                                                $url = str_replace( 
'$1', $dbkey, $wgActionPaths[$action] );
 
  822                                if ( $url === 
false ) {
 
  826                                        $url = 
"{$wgScript}?title={$dbkey}&{$query}";
 
  832                        if ($wgRequest->getVal(
'action') == 
'render') {
 
  833                                $url = $wgServer . $url;
 
  836                wfRunHooks( 
'GetLocalURL', array( &$this, &$url, 
$query ) );
 
  871                global $wgInternalServer;
 
  873                wfRunHooks( 
'GetInternalURL', array( &$this, &$url, 
$query ) );
 
  883                if ( 
'' != $this->mInterwiki ) { 
return ''; }
 
  902        public function isExternal() { 
return ( 
'' != $this->mInterwiki ); }
 
  913                        if( count( $restrictions ) > 0 ) {
 
  914                                foreach( $restrictions as $restriction ) {
 
  915                                        if( strtolower( $restriction ) != 
'autoconfirmed' )
 
  924                        # If it doesn't exist, it can't be protected 
  936                global $wgRestrictionLevels;
 
  938                # Special pages have inherent protection 
  942                # Check regular protection levels                                
  943                if( $action == 
'edit' || $action == 
'' ) {
 
  945                        foreach( $wgRestrictionLevels as $level ) {
 
  946                                if( in_array( $level, $r ) && $level != 
'' ) {
 
  952                if( $action == 
'move' || $action == 
'' ) {
 
  954                        foreach( $wgRestrictionLevels as $level ) {
 
  955                                if( in_array( $level, $r ) && $level != 
'' ) {
 
  971                if ( is_null( $this->mWatched ) ) {
 
  972                        if ( NS_SPECIAL == $this->mNamespace || !$wgUser->isLoggedIn()) {
 
  973                                $this->mWatched = 
false;
 
  975                                $this->mWatched = $wgUser->isWatched( $this );
 
  994                return $this->
userCan( $action, 
false );
 
 1003        public function userCan( $action, $doExpensiveQueries = 
true ) {
 
 1004                $fname = 
'Title::userCan';
 
 1005                wfProfileIn( $fname );
 
 1007                global $wgUser, $wgNamespaceProtection;
 
 1010                wfRunHooks( 
'userCan', array( &$this, &$wgUser, $action, &
$result ) );
 
 1012                        wfProfileOut( $fname );
 
 1016                if( NS_SPECIAL == $this->mNamespace ) {
 
 1017                        wfProfileOut( $fname );
 
 1021                if ( array_key_exists( $this->mNamespace, $wgNamespaceProtection ) ) {
 
 1023                        if ( !is_array($nsProt) ) $nsProt = array($nsProt);
 
 1024                        foreach( $nsProt as $right ) {
 
 1025                                if( 
'' != $right && !$wgUser->isAllowed( $right ) ) {
 
 1026                                        wfProfileOut( $fname );
 
 1032                if( $this->mDbkeyform == 
'_' ) {
 
 1033                        # FIXME: Is this necessary? Shouldn't be allowed anyway... 
 1034                        wfProfileOut( $fname );
 
 1038                # protect css/js subpages of user pages 
 1039                # XXX: this might be better using restrictions 
 1040                # XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working 
 1042                        && !$wgUser->isAllowed(
'editinterface')
 
 1043                        && !preg_match(
'/^'.preg_quote($wgUser->getName(), 
'/').
'\//', $this->mTextform) ) {
 
 1044                        wfProfileOut( $fname );
 
 1049                        # We /could/ use the protection level on the source page, but it's fairly ugly 
 1050                        #  as we have to establish a precedence hierarchy for pages included by multiple 
 1051                        #  cascade-protected pages. So just restrict it to people with 'protect' permission, 
 1052                        #  as they could remove the protection anyway. 
 1054                        # Cascading protection depends on more than this page... 
 1055                        # Several cascading protected pages may include this page... 
 1056                        # Check each cascading level 
 1057                        # This is only for protection restrictions, not for all actions 
 1058                        if( $cascadingSources > 0 && isset($restrictions[$action]) ) {
 
 1059                                foreach( $restrictions[$action] as $right ) {
 
 1060                                        $right = ( $right == 
'sysop' ) ? 
'protect' : $right;
 
 1061                                        if( 
'' != $right && !$wgUser->isAllowed( $right ) ) {
 
 1062                                                wfProfileOut( $fname );
 
 1071                        if ( $right == 
'sysop' ) {
 
 1074                        if( 
'' != $right && !$wgUser->isAllowed( $right ) ) {
 
 1075                                wfProfileOut( $fname );
 
 1080                if( $action == 
'move' &&
 
 1081                        !( $this->isMovable() && $wgUser->isAllowed( 
'move' ) ) ) {
 
 1082                        wfProfileOut( $fname );
 
 1086                if( $action == 
'create' ) {
 
 1087                        if( (  $this->isTalkPage() && !$wgUser->isAllowed( 
'createtalk' ) ) ||
 
 1088                                ( !$this->isTalkPage() && !$wgUser->isAllowed( 
'createpage' ) ) ) {
 
 1089                                wfProfileOut( $fname );
 
 1094                wfProfileOut( $fname );
 
 1104                return $this->
userCan( 
'edit', $doExpensiveQueries );
 
 1113                return $this->
userCan( 
'create', $doExpensiveQueries );
 
 1122                return $this->
userCan( 
'move', $doExpensiveQueries );
 
 1145                wfRunHooks( 
'userCan', array( &$this, &$wgUser, 
'read', &
$result ) );
 
 1150                if( $wgUser->isAllowed(
'read') ) {
 
 1153                        global $wgWhitelistRead;
 
 1165                        if( $wgWhitelistRead && in_array( $name, $wgWhitelistRead ) ) {
 
 1169                        # Compatibility with old settings 
 1170                        if( $wgWhitelistRead && $this->
getNamespace() == NS_MAIN ) {
 
 1171                                if( in_array( 
':' . $name, $wgWhitelistRead ) ) {
 
 1192                global $wgNamespacesWithSubpages;
 
 1194                if( isset( $wgNamespacesWithSubpages[ $this->mNamespace ] ) ) {
 
 1195                        return ( strpos( $this->
getText(), 
'/' ) !== 
false && $wgNamespacesWithSubpages[ $this->mNamespace ] == 
true );
 
 1206                return ( NS_USER == $this->mNamespace and preg_match(
"/\\/.*\\.(?:css|js)$/", $this->mTextform ) );
 
 1214                        $skinNames = Skin::getSkinNames();
 
 1224                $subpage = explode( 
'/', $this->mTextform );
 
 1225                $subpage = $subpage[ count( $subpage ) - 1 ];
 
 1226                return( str_replace( array( 
'.css', 
'.js' ), array( 
'', 
'' ), $subpage ) );
 
 1233                return ( NS_USER == $this->mNamespace and preg_match(
"/\\/.*\\.css$/", $this->mTextform ) );
 
 1240                return ( NS_USER == $this->mNamespace and preg_match(
"/\\/.*\\.js$/", $this->mTextform ) );
 
 1251                return ( $wgUser->isAllowed(
'editinterface') or preg_match(
'/^'.preg_quote($wgUser->getName(), 
'/').
'\//', $this->mTextform) );
 
 1261                return ( $sources > 0 );
 
 1273                global $wgEnableCascadingProtection, $wgRestrictionTypes;
 
 1275                # Define our dimension of restrictions types 
 1276                $pagerestrictions = array();
 
 1277                foreach( $wgRestrictionTypes as $action )
 
 1278                        $pagerestrictions[$action] = array();
 
 1280                if (!$wgEnableCascadingProtection)
 
 1281                        return array( 
false, $pagerestrictions );
 
 1283                if ( isset( $this->mCascadeSources ) && $get_pages ) {
 
 1284                        return array( $this->mCascadeSources, $this->mCascadingRestrictions );
 
 1285                } 
else if ( isset( $this->mHasCascadingRestrictions ) && !$get_pages ) {
 
 1286                        return array( $this->mHasCascadingRestrictions, $pagerestrictions );
 
 1289                wfProfileIn( __METHOD__ );
 
 1291                $dbr = wfGetDb( DB_SLAVE );
 
 1294                        $tables = array (
'imagelinks', 
'page_restrictions');
 
 1295                        $where_clauses = array(
 
 1298                                'pr_cascade' => 1 );
 
 1300                        $tables = array (
'templatelinks', 
'page_restrictions');
 
 1301                        $where_clauses = array(
 
 1305                                'pr_cascade' => 1 );
 
 1309                        $cols = array(
'pr_page', 
'page_namespace', 
'page_title', 
'pr_expiry', 
'pr_type', 
'pr_level' );
 
 1310                        $where_clauses[] = 
'page_id=pr_page';
 
 1313                        $cols = array( 
'pr_expiry' );
 
 1316                $res = $dbr->select( $tables, $cols, $where_clauses, __METHOD__ );
 
 1318                $sources = $get_pages ? array() : 
false;
 
 1319                $now = wfTimestampNow();
 
 1320                $purgeExpired = 
false;
 
 1322                while( 
$row = $dbr->fetchObject( 
$res ) ) {
 
 1323                        $expiry = Block::decodeExpiry( 
$row->pr_expiry );
 
 1324                        if( $expiry > $now ) {
 
 1326                                        $page_id = 
$row->pr_page;
 
 1327                                        $page_ns = 
$row->page_namespace;
 
 1328                                        $page_title = 
$row->page_title;
 
 1330                                        # Add groups needed for each restriction type if its not already there 
 1331                                        # Make sure this restriction type still exists 
 1332                                        if ( isset($pagerestrictions[
$row->pr_type]) && !in_array(
$row->pr_level, $pagerestrictions[
$row->pr_type]) ) {
 
 1333                                                $pagerestrictions[
$row->pr_type][]=
$row->pr_level;
 
 1340                                $purgeExpired = 
true;
 
 1343                if( $purgeExpired ) {
 
 1347                wfProfileOut( __METHOD__ );
 
 1350                        $this->mCascadeSources = $sources;
 
 1351                        $this->mCascadingRestrictions = $pagerestrictions;
 
 1353                        $this->mHasCascadingRestrictions = $sources;
 
 1356                return array( $sources, $pagerestrictions );
 
 1360                if (!$this->mRestrictionsLoaded) {
 
 1372                $dbr = wfGetDb( DB_SLAVE );
 
 1374                $this->mRestrictions[
'edit'] = array();
 
 1375                $this->mRestrictions[
'move'] = array();
 
 1377                # Backwards-compatibility: also load the restrictions from the page record (old format). 
 1379                if ( $oldFashionedRestrictions == NULL ) {
 
 1380                        $oldFashionedRestrictions = $dbr->selectField( 
'page', 
'page_restrictions', array( 
'page_id' => $this->getArticleId() ), __METHOD__ );
 
 1383                if ($oldFashionedRestrictions != 
'') {
 
 1385                        foreach( explode( 
':', trim( $oldFashionedRestrictions ) ) as $restrict ) {
 
 1386                                $temp = explode( 
'=', trim( $restrict ) );
 
 1387                                if(count($temp) == 1) {
 
 1389                                        $this->mRestrictions[
"edit"] = explode( 
',', trim( $temp[0] ) );
 
 1390                                        $this->mRestrictions[
"move"] = explode( 
',', trim( $temp[0] ) );
 
 1392                                        $this->mRestrictions[$temp[0]] = explode( 
',', trim( $temp[1] ) );
 
 1396                        $this->mOldRestrictions = 
true;
 
 1397                        $this->mCascadeRestriction = 
false;
 
 1398                        $this->mRestrictionsExpiry = Block::decodeExpiry(
'');
 
 1402                if( $dbr->numRows( 
$res ) ) {
 
 1403                        # Current system - load second to make them override. 
 1404                        $now = wfTimestampNow();
 
 1405                        $purgeExpired = 
false;
 
 1407                        while (
$row = $dbr->fetchObject( 
$res ) ) {
 
 1408                                # Cycle through all the restrictions. 
 1412                                $expiry = Block::decodeExpiry( 
$row->pr_expiry );
 
 1415                                if ( !$expiry || $expiry > $now ) {
 
 1416                                        $this->mRestrictionsExpiry = $expiry;
 
 1417                                        $this->mRestrictions[
$row->pr_type] = explode( 
',', trim( 
$row->pr_level ) );
 
 1419                                        $this->mCascadeRestriction |= 
$row->pr_cascade;
 
 1422                                        $purgeExpired = 
true;
 
 1426                        if( $purgeExpired ) {
 
 1431                $this->mRestrictionsLoaded = 
true;
 
 1435                if( !$this->mRestrictionsLoaded ) {
 
 1436                        $dbr = wfGetDB( DB_SLAVE );
 
 1438                        $res = $dbr->select( 
'page_restrictions', 
'*',
 
 1439                                array ( 
'pr_page' => $this->getArticleId() ), __METHOD__ );
 
 1449                $dbw = wfGetDB( DB_MASTER );
 
 1450                $dbw->delete( 
'page_restrictions',
 
 1451                        array( 
'pr_expiry < ' . $dbw->addQuotes( $dbw->timestamp() ) ),
 
 1463                        if( !$this->mRestrictionsLoaded ) {
 
 1466                        return isset( $this->mRestrictions[$action] )
 
 1467                                        ? $this->mRestrictions[$action]
 
 1479                $fname = 
'Title::isDeleted';
 
 1483                        $dbr = wfGetDB( DB_SLAVE );
 
 1484                        $n = $dbr->selectField( 
'archive', 
'COUNT(*)', array( 
'ar_namespace' => $this->
getNamespace(),
 
 1485                                'ar_title' => $this->
getDBkey() ), $fname );
 
 1487                                $n += $dbr->selectField( 
'filearchive', 
'COUNT(*)',
 
 1488                                        array( 
'fa_name' => $this->
getDBkey() ), $fname );
 
 1502                $linkCache =& LinkCache::singleton();
 
 1504                        $oldUpdate = $linkCache->forUpdate( 
true );
 
 1505                        $this->mArticleID = $linkCache->addLinkObj( $this );
 
 1506                        $linkCache->forUpdate( $oldUpdate );
 
 1508                        if ( -1 == $this->mArticleID ) {
 
 1509                                $this->mArticleID = $linkCache->addLinkObj( $this );
 
 1516                if ($this->mLatestID !== 
false)
 
 1519                $db = wfGetDB(DB_SLAVE);
 
 1520                return $this->mLatestID = $db->selectField( 
'revision',
 
 1523                        'Title::getLatestRevID' );
 
 1537                $linkCache =& LinkCache::singleton();
 
 1540                if ( 0 == $newid ) { $this->mArticleID = -1; }
 
 1541                else { $this->mArticleID = $newid; }
 
 1542                $this->mRestrictionsLoaded = 
false;
 
 1543                $this->mRestrictions = array();
 
 1551                global $wgUseFileCache;
 
 1553                if ( wfReadOnly() ) {
 
 1557                $dbw = wfGetDB( DB_MASTER );
 
 1560                                'page_touched' => $dbw->timestamp()
 
 1564                        ), 
'Title::invalidateCache' 
 1567                if ($wgUseFileCache) {
 
 1568                        $cache = 
new HTMLFileCache($this);
 
 1569                        @unlink($cache->fileCacheName());
 
 1585                if ( 
'' != $this->mInterwiki ) {
 
 1586                        $p = $this->mInterwiki . 
':';
 
 1588                if ( 0 != $this->mNamespace ) {
 
 1605                global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;
 
 1608                static $rxTc = 
false;
 
 1610                        # % is needed as well 
 1614                $this->mInterwiki = $this->mFragment = 
'';
 
 1619                # Strip Unicode bidi override characters. 
 1620                # Sometimes they slip into cut-n-pasted page titles, where the 
 1621                # override chars get included in list displays. 
 1622                $dbkey = str_replace( 
"\xE2\x80\x8E", 
'', $dbkey ); 
 
 1623                $dbkey = str_replace( 
"\xE2\x80\x8F", 
'', $dbkey ); 
 
 1625                # Clean up whitespace 
 1627                $dbkey = preg_replace( 
'/[ _]+/', 
'_', $dbkey );
 
 1628                $dbkey = trim( $dbkey, 
'_' );
 
 1630                if ( 
'' == $dbkey ) {
 
 1635                        # Contained illegal UTF-8 sequences or forbidden Unicode chars. 
 1639                $this->mDbkeyform = $dbkey;
 
 1641                # Initial colon indicates main namespace rather than specified default 
 1642                # but should not create invalid {ns,title} pairs such as {0,Project:Foo} 
 1643                if ( 
':' == $dbkey{0} ) {
 
 1644                        $this->mNamespace = NS_MAIN;
 
 1645                        $dbkey = substr( $dbkey, 1 ); # 
remove the colon but 
continue processing
 
 1646                        $dbkey = trim( $dbkey, 
'_' ); # 
remove any subsequent whitespace
 
 1649                # Namespace or interwiki prefix 
 1653                        if ( preg_match( 
"/^(.+?)_*:_*(.*)$/S", $dbkey, $m ) ) {
 
 1655                                if ( $ns = $wgContLang->getNsIndex( $p )) {
 
 1656                                        # Ordinary namespace 
 1658                                        $this->mNamespace = $ns;
 
 1661                                                # Can't make a local interwiki link to an interwiki link. 
 1662                                                # That's just crazy! 
 1668                                        $this->mInterwiki = $wgContLang->lc( $p );
 
 1670                                        # Redundant interwiki prefix to the local wiki 
 1671                                        if ( 0 == strcasecmp( $this->mInterwiki, $wgLocalInterwiki ) ) {
 
 1672                                                if( $dbkey == 
'' ) {
 
 1673                                                        # Can't have an empty self-link 
 1676                                                $this->mInterwiki = 
'';
 
 1678                                                # Do another namespace split... 
 1682                                        # If there's an initial colon after the interwiki, that also 
 1683                                        # resets the default namespace 
 1684                                        if ( $dbkey !== 
'' && $dbkey[0] == 
':' ) {
 
 1685                                                $this->mNamespace = NS_MAIN;
 
 1686                                                $dbkey = substr( $dbkey, 1 );
 
 1689                                # If there's no recognized interwiki or namespace, 
 1690                                # then let the colon expression be part of the title. 
 1695                # We already know that some pages won't be in the database! 
 1697                if ( 
'' != $this->mInterwiki || NS_SPECIAL == $this->mNamespace ) {
 
 1698                        $this->mArticleID = 0;
 
 1700                $fragment = strstr( $dbkey, 
'#' );
 
 1701                if ( 
false !== $fragment ) {
 
 1703                        $dbkey = substr( $dbkey, 0, strlen( $dbkey ) - strlen( $fragment ) );
 
 1704                        # remove whitespace again: prevents "Foo_bar_#" 
 1705                        # becoming "Foo_bar_" 
 1706                        $dbkey = preg_replace( 
'/_*$/', 
'', $dbkey );
 
 1709                # Reject illegal characters. 
 1711                if( preg_match( $rxTc, $dbkey ) ) {
 
 1720                if ( strpos( $dbkey, 
'.' ) !== 
false &&
 
 1721                     ( $dbkey === 
'.' || $dbkey === 
'..' ||
 
 1722                       strpos( $dbkey, 
'./' ) === 0  ||
 
 1723                       strpos( $dbkey, 
'../' ) === 0 ||
 
 1724                       strpos( $dbkey, 
'/./' ) !== 
false ||
 
 1725                       strpos( $dbkey, 
'/../' ) !== 
false ) )
 
 1733                if( strpos( $dbkey, 
'~~~' ) !== 
false ) {
 
 1744                if ( ( $this->mNamespace != NS_SPECIAL && strlen( $dbkey ) > 255 ) ||
 
 1745                  strlen( $dbkey ) > 512 ) 
 
 1758                if( $wgCapitalLinks && $this->mInterwiki == 
'') {
 
 1759                        $dbkey = $wgContLang->ucfirst( $dbkey );
 
 1768                        $this->mInterwiki == 
'' &&
 
 1769                        $this->mNamespace != NS_MAIN ) {
 
 1774                if ( $dbkey !== 
'' && 
':' == $dbkey{0} ) {
 
 1779                $this->mDbkeyform = $dbkey;
 
 1782                $this->mTextform = str_replace( 
'_', 
' ', $dbkey );
 
 1797                $this->mFragment = str_replace( 
'_', 
' ', substr( $fragment, 1 ) );
 
 1829                $linkCache =& LinkCache::singleton();
 
 1832                        $db = wfGetDB( DB_MASTER );
 
 1834                        $db = wfGetDB( DB_SLAVE );
 
 1837                $res = $db->select( array( 
'page', $table ),
 
 1838                        array( 
'page_namespace', 
'page_title', 
'page_id' ),
 
 1840                                "{$prefix}_from=page_id",
 
 1842                                "{$prefix}_title"     => $this->getDbKey() ),
 
 1843                        'Title::getLinksTo',
 
 1847                if ( $db->numRows( 
$res ) ) {
 
 1848                        while ( 
$row = $db->fetchObject( 
$res ) ) {
 
 1850                                        $linkCache->addGoodLinkObj( 
$row->page_id, $titleObj );
 
 1851                                        $retVal[] = $titleObj;
 
 1855                $db->freeResult( 
$res );
 
 1881                        $db = wfGetDB( DB_MASTER );
 
 1883                        $db = wfGetDB( DB_SLAVE );
 
 1886                $res = $db->safeQuery(
 
 1887                          "SELECT pl_namespace, pl_title 
 1890                               ON pl_namespace=page_namespace 
 1891                              AND pl_title=page_title 
 1893                              AND page_namespace IS NULL 
 1895                        $db->tableName( 
'pagelinks' ),
 
 1896                        $db->tableName( 
'page' ),
 
 1897                        $this->getArticleId(),
 
 1901                if ( $db->numRows( 
$res ) ) {
 
 1902                        while ( 
$row = $db->fetchObject( 
$res ) ) {
 
 1906                $db->freeResult( 
$res );
 
 1926                if($wgContLang->hasVariants()){
 
 1927                        $variants = $wgContLang->getVariants();
 
 1928                        foreach($variants as $vCode){
 
 1929                                if($vCode==$wgContLang->getCode()) 
continue; 
 
 1939                if ( $wgUseSquid ) {
 
 1941                        $u = 
new SquidUpdate( $urls );
 
 1951                return $this->
moveTo( $nt, 
false );
 
 1964                if( !$this or !$nt ) {
 
 1965                        return 'badtitletext';
 
 1967                if( $this->
equals( $nt ) ) {
 
 1970                if( !$this->isMovable() || !$nt->isMovable() ) {
 
 1971                        return 'immobile_namespace';
 
 1975                $newid = $nt->getArticleID();
 
 1977                if ( strlen( $nt->getDBkey() ) < 1 ) {
 
 1978                        return 'articleexists';
 
 1980                if ( ( 
'' == $this->
getDBkey() ) ||
 
 1982                     ( 
'' == $nt->getDBkey() ) ) {
 
 1983                        return 'badarticleerror';
 
 1987                                !$this->
userCan( 
'edit' ) || !$nt->userCan( 
'edit' ) ||
 
 1988                                !$this->userCan( 
'move' ) || !$nt->userCan( 
'move' ) ) ) {
 
 1989                        return 'protectedpage';
 
 1992                # The move is allowed only if (1) the target doesn't exist, or 
 1993                # (2) the target is a redirect to the source, and has no history 
 1994                # (so we can undo bad moves right after they're done). 
 1996                if ( 0 != $newid ) { # Target 
exists; check 
for validity
 
 1998                                return 'articleexists';
 
 2013                if( is_string( $err ) ) {
 
 2018                if( $nt->exists() ) {
 
 2020                        $pageCountChange = 0;
 
 2021                } 
else { # Target didn
't exist, do normal move. 
 2022                        $this->moveToNewTitle( $nt, $reason ); 
 2023                        $pageCountChange = 1; 
 2025                $redirid = $this->getArticleID(); 
 2027                # Fixing category links (those without piped 'alternate
' names) to be sorted under the new title 
 2028                $dbw = wfGetDB( DB_MASTER ); 
 2029                $categorylinks = $dbw->tableName( 'categorylinks
' ); 
 2030                $sql = "UPDATE $categorylinks SET cl_sortkey=" . $dbw->addQuotes( $nt->getPrefixedText() ) . 
 2031                        " WHERE cl_from=" . $dbw->addQuotes( $pageid ) . 
 2032                        " AND cl_sortkey=" . $dbw->addQuotes( $this->getPrefixedText() ); 
 2033                $dbw->query( $sql, 'SpecialMovepage::doSubmit
' ); 
 2037                $oldnamespace = $this->getNamespace() & ~1; 
 2038                $newnamespace = $nt->getNamespace() & ~1; 
 2039                $oldtitle = $this->getDBkey(); 
 2040                $newtitle = $nt->getDBkey(); 
 2042                if( $oldnamespace != $newnamespace || $oldtitle != $newtitle ) { 
 2043                        WatchedItem::duplicateEntries( $this, $nt ); 
 2046                # Update search engine 
 2047                $u = new SearchUpdate( $pageid, $nt->getPrefixedDBkey() ); 
 2049                $u = new SearchUpdate( $redirid, $this->getPrefixedDBkey(), '' ); 
 2053                if( $this->isContentPage() && !$nt->isContentPage() ) { 
 2054                        # No longer a content page 
 2055                        # Not viewed, edited, removing 
 2056                        $u = new SiteStatsUpdate( 0, 1, -1, $pageCountChange ); 
 2057                } elseif( !$this->isContentPage() && $nt->isContentPage() ) { 
 2058                        # Now a content page 
 2059                        # Not viewed, edited, adding 
 2060                        $u = new SiteStatsUpdate( 0, 1, +1, $pageCountChange ); 
 2061                } elseif( $pageCountChange ) { 
 2063                        $u = new SiteStatsUpdate( 0, 0, 0, 1 ); 
 2072                wfRunHooks( 'TitleMoveComplete
', array( &$this, &$nt, &$wgUser, $pageid, $redirid ) ); 
 2083        private function moveOverExistingRedirect( &$nt, $reason = '' ) { 
 2086                $comment = wfMsgForContent( '1movedto2_redir
', $this->getPrefixedText(), $nt->getPrefixedText() ); 
 2089                        $comment .= ": $reason"; 
 2092                $now = wfTimestampNow(); 
 2093                $newid = $nt->getArticleID(); 
 2094                $oldid = $this->getArticleID(); 
 2095                $dbw = wfGetDB( DB_MASTER ); 
 2096                $linkCache =& LinkCache::singleton(); 
 2098                # Delete the old redirect. We don't save it to history since
 
 2099                # by definition if we've got here it's rather uninteresting. 
 2100                # We have to remove it so that the next step doesn't trigger 
 2101                # a conflict on the unique namespace+title index... 
 2102                $dbw->delete( 
'page', array( 
'page_id' => $newid ), $fname );
 
 2104                # Save a null revision in the page's history notifying of the move 
 2105                $nullRevision = Revision::newNullRevision( $dbw, $oldid, 
$comment, 
true );
 
 2106                $nullRevId = $nullRevision->insertOn( $dbw );
 
 2108                # Change the name of the target page: 
 2109                $dbw->update( 
'page',
 
 2111                                'page_touched'   => $dbw->timestamp($now),
 
 2112                                'page_namespace' => $nt->getNamespace(),
 
 2113                                'page_title'     => $nt->getDBkey(),
 
 2114                                'page_latest'    => $nullRevId,
 
 2116                         array( 
'page_id' => $oldid ),
 
 2119                $linkCache->clearLink( $nt->getPrefixedDBkey() );
 
 2121                # Recreate the redirect, this time in the other direction. 
 2122                $mwRedir = MagicWord::get( 
'redirect' );
 
 2123                $redirectText = $mwRedir->getSynonym( 0 ) . 
' [[' . $nt->getPrefixedText() . 
"]]\n";
 
 2124                $redirectArticle = 
new Article( $this );
 
 2125                $newid = $redirectArticle->insertOn( $dbw );
 
 2126                $redirectRevision = 
new Revision( array(
 
 2129                        'text'    => $redirectText ) );
 
 2130                $redirectRevision->insertOn( $dbw );
 
 2131                $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
 
 2135                $log = 
new LogPage( 
'move' );
 
 2136                $log->addEntry( 
'move_redir', $this, $reason, array( 1 => $nt->getPrefixedText() ) );
 
 2138                # Now, we record the link from the redirect to the new title. 
 2139                # It should have no other outgoing links... 
 2140                $dbw->delete( 
'pagelinks', array( 
'pl_from' => $newid ), $fname );
 
 2141                $dbw->insert( 
'pagelinks',
 
 2143                                'pl_from'      => $newid,
 
 2144                                'pl_namespace' => $nt->getNamespace(),
 
 2145                                'pl_title'     => $nt->getDbKey() ),
 
 2149                if ( $wgUseSquid ) {
 
 2150                        $urls = array_merge( $nt->getSquidURLs(), $this->getSquidURLs() );
 
 2151                        $u = 
new SquidUpdate( $urls );
 
 2162                $fname = 
'MovePageForm::moveToNewTitle';
 
 2168                $newid = $nt->getArticleID();
 
 2170                $dbw = wfGetDB( DB_MASTER );
 
 2171                $now = $dbw->timestamp();
 
 2172                $linkCache =& LinkCache::singleton();
 
 2174                # Save a null revision in the page's history notifying of the move 
 2175                $nullRevision = Revision::newNullRevision( $dbw, $oldid, 
$comment, 
true );
 
 2176                $nullRevId = $nullRevision->insertOn( $dbw );
 
 2179                $dbw->update( 
'page',
 
 2181                                'page_touched'   => $now,
 
 2182                                'page_namespace' => $nt->getNamespace(),
 
 2183                                'page_title'     => $nt->getDBkey(),
 
 2184                                'page_latest'    => $nullRevId,
 
 2186                         array( 
'page_id' => $oldid ),
 
 2190                $linkCache->clearLink( $nt->getPrefixedDBkey() );
 
 2193                $mwRedir = MagicWord::get( 
'redirect' );
 
 2194                $redirectText = $mwRedir->getSynonym( 0 ) . 
' [[' . $nt->getPrefixedText() . 
"]]\n";
 
 2195                $redirectArticle = 
new Article( $this );
 
 2196                $newid = $redirectArticle->insertOn( $dbw );
 
 2197                $redirectRevision = 
new Revision( array(
 
 2200                        'text'    => $redirectText ) );
 
 2201                $redirectRevision->insertOn( $dbw );
 
 2202                $redirectArticle->updateRevisionOn( $dbw, $redirectRevision, 0 );
 
 2206                $log = 
new LogPage( 
'move' );
 
 2207                $log->addEntry( 
'move', $this, $reason, array( 1 => $nt->getPrefixedText()) );
 
 2209                # Purge caches as per article creation 
 2210                Article::onArticleCreate( $nt );
 
 2212                # Record the just-created redirect's linking to the page 
 2213                $dbw->insert( 
'pagelinks',
 
 2215                                'pl_from'      => $newid,
 
 2216                                'pl_namespace' => $nt->getNamespace(),
 
 2217                                'pl_title'     => $nt->getDBkey() ),
 
 2220                # Purge old title from squid 
 2221                # The new title, and links to the new title, are purged in Article::onArticleCreate() 
 2233                $fname = 
'Title::isValidMoveTarget';
 
 2234                $dbw = wfGetDB( DB_MASTER );
 
 2237                $id  = $nt->getArticleID();
 
 2238                $obj = $dbw->selectRow( array( 
'page', 
'revision', 
'text'),
 
 2239                        array( 
'page_is_redirect',
'old_text',
'old_flags' ),
 
 2240                        array( 
'page_id' => $id, 
'page_latest=rev_id', 
'rev_text_id=old_id' ),
 
 2241                        $fname, 
'FOR UPDATE' );
 
 2243                if ( !$obj || 0 == $obj->page_is_redirect ) {
 
 2245                        wfDebug( __METHOD__ . 
": not a redirect\n" );
 
 2248                $text = Revision::getRevisionText( $obj );
 
 2250                # Does the redirect point to the source? 
 2251                # Or is it a broken self-redirect, usually caused by namespace collisions? 
 2253                if ( preg_match( 
"/\\[\\[\\s*([^\\]\\|]*)]]/", $text, $m ) ) {
 
 2255                        if( !is_object( $redirTitle ) ||
 
 2256                                ( $redirTitle->getPrefixedDBkey() != $this->getPrefixedDBkey() &&
 
 2257                                $redirTitle->getPrefixedDBkey() != $nt->getPrefixedDBkey() ) ) {
 
 2258                                wfDebug( __METHOD__ . 
": redirect points to other page\n" );
 
 2263                        wfDebug( __METHOD__ . 
": failsafe\n" );
 
 2267                # Does the article have a history? 
 2268                $row = $dbw->selectRow( array( 
'page', 
'revision'),
 
 2270                        array( 
'page_namespace' => $nt->getNamespace(),
 
 2271                                'page_title' => $nt->getDBkey(),
 
 2272                                'page_id=rev_page AND page_latest != rev_id' 
 2273                        ), $fname, 
'FOR UPDATE' 
 2276                # Return true if there was no history 
 2277                return $row === 
false;
 
 2290                $titlekey = $this->getArticleId();
 
 2291                $dbr = wfGetDB( DB_SLAVE );
 
 2292                $categorylinks = $dbr->tableName( 
'categorylinks' );
 
 2295                $sql = 
"SELECT * FROM $categorylinks" 
 2296                     .
" WHERE cl_from='$titlekey'" 
 2297                         .
" AND cl_from <> '0'" 
 2298                         .
" ORDER BY cl_sortkey";
 
 2300                $res = $dbr->query ( $sql ) ;
 
 2302                if($dbr->numRows(
$res) > 0) {
 
 2303                        while ( $x = $dbr->fetchObject ( 
$res ) )
 
 2305                                $data[$wgContLang->getNSText ( NS_CATEGORY ).
':'.$x->cl_to] = $this->
getFullText();
 
 2306                        $dbr->freeResult ( 
$res ) ;
 
 2321                if($parents != 
'') {
 
 2322                        foreach($parents as $parent => $current) {
 
 2323                                if ( array_key_exists( $parent, $children ) ) {
 
 2324                                        # Circular reference 
 2325                                        $stack[$parent] = array();
 
 2329                                                $stack[$parent] = $nt->getParentCategoryTree( $children + array($parent => 1) );
 
 2347                return array( 
'page_namespace' => $this->mNamespace, 
'page_title' => $this->mDbkeyform );
 
 2357                $dbr = wfGetDB( DB_SLAVE );
 
 2358                return $dbr->selectField( 
'revision', 
'rev_id',
 
 2359                        'rev_page=' . intval( $this->getArticleId() ) .
 
 2360                        ' AND rev_id<' . intval( $revision ) . 
' ORDER BY rev_id DESC' );
 
 2370                $dbr = wfGetDB( DB_SLAVE );
 
 2371                return $dbr->selectField( 
'revision', 
'rev_id',
 
 2372                        'rev_page=' . intval( $this->getArticleId() ) .
 
 2373                        ' AND rev_id>' . intval( $revision ) . 
' ORDER BY rev_id' );
 
 2384                $dbr = wfGetDB( DB_SLAVE );
 
 2385                return $dbr->selectField( 
'revision', 
'count(*)',
 
 2386                        'rev_page = ' . intval( $this->getArticleId() ) .
 
 2387                        ' AND rev_id > ' . intval( $old ) .
 
 2388                        ' AND rev_id < ' . intval( $new ) );
 
 2399                return $this->
getInterwiki() === $title->getInterwiki()
 
 2401                        && $this->getDbkey() === $title->getDbkey();
 
 2409                return $this->getArticleId() != 0;
 
 2420                  || NS_SPECIAL == $this->mNamespace;
 
 2429                $u = 
new HTMLCacheUpdate( $this, 
'pagelinks' );
 
 2433                        $u = 
new HTMLCacheUpdate( $this, 
'categorylinks' );
 
 2442                $dbr = wfGetDB( DB_SLAVE );
 
 2443                $touched = $dbr->selectField( 
'page', 
'page_touched',
 
 2453                global $wgTitle, $wgScriptPath, $wgServer;
 
 2455                return "$wgServer$wgScriptPath/trackback.php?article=" 
 2456                        . htmlspecialchars(urlencode($wgTitle->getPrefixedDBkey()));
 
 2460                $url = htmlspecialchars($this->
getFullURL());
 
 2461                $title = htmlspecialchars($this->
getText());
 
 2465<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" 
 2466         xmlns:dc=\"http://purl.org/dc/elements/1.1/\" 
 2467         xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\"> 
 2470   dc:identifier=\"$url\" 
 2472   trackback:ping=\"$tburl\" /> 
 2485                                return 'nstab-main';
 
 2488                                return 'nstab-user';
 
 2490                                return 'nstab-media';
 
 2492                                return 'nstab-special';
 
 2494                        case NS_PROJECT_TALK:
 
 2495                                return 'nstab-project';
 
 2498                                return 'nstab-image';
 
 2500                        case NS_MEDIAWIKI_TALK:
 
 2501                                return 'nstab-mediawiki';
 
 2503                        case NS_TEMPLATE_TALK:
 
 2504                                return 'nstab-template';
 
 2507                                return 'nstab-help';
 
 2509                        case NS_CATEGORY_TALK:
 
 2510                                return 'nstab-category';
 
 2512                                return 'nstab-' . $wgContLang->lc( $this->getSubjectNsText() );
 
 2522                        list( $thisName,  ) = SpecialPage::resolveAliasWithSubpage( $this->
getDBkey() );
 
 2523                        if ( $name == $thisName ) {
 
 2536                        $canonicalName = SpecialPage::resolveAlias( $this->mDbkeyform );
 
 2537                        if ( $canonicalName ) {
 
 2538                                $localName = SpecialPage::getLocalNameFor( $canonicalName );
 
 2539                                if ( $localName != $this->mDbkeyform ) {
 
const GAID_FOR_UPDATE(!class_exists( 'UtfNormal'))
See title.txt.
static decodeCharReferences( $text)
Decode any character references, numeric or named entities, in the text and return a UTF-8 string.
getTouched()
Get the last touched timestamp.
getNamespace()
Get the namespace index, i.e.
static newFromDBkey( $key)
Create a new Title from a prefixed DB key.
isProtected( $action='')
Does the title correspond to a protected article?
userCanRead()
Would anybody with sufficient privileges be able to move this page? Some pages just aren't movable.
static $titleCache
Static cache variables.
invalidateCache()
Updates page_touched for this page; called from LinksUpdate.php.
equals( $title)
Compare with another title.
getNextRevisionID( $revision)
Get the revision ID of the next revision.
isValidMoveOperation(&$nt, $auth=true)
Check whether a given move operation would be valid.
nameOf( $id)
Get the prefixed DB key associated with an ID.
userCanMove( $doExpensiveQueries=true)
Can $wgUser move this page?
$mHasCascadingRestrictions
getRestrictions( $action)
Accessor/initialisation for mRestrictions.
moveTo(&$nt, $auth=true, $reason='')
Move a title to a new location.
$mTextform
All member variables should be considered private Please use the accessor functions.
secureAndSplit()
Secure and split - main initialisation function for this object.
getBrokenLinksFrom( $options='')
Get an array of Title objects referring to non-existent articles linked from this page.
getSkinFromCssJsSubpage()
Trim down a .css or .js subpage title to get the corresponding skin name.
loadRestrictions( $oldFashionedRestrictions=NULL)
getDefaultNamespace()
Get the default namespace index, for when there is no namespace.
userCanEdit( $doExpensiveQueries=true)
Can $wgUser edit this page?
getFragment()
Get the Title fragment (i.e.
isCascadeProtected()
Cascading protection: Return true if cascading restrictions apply to this page, false if not.
getIndexTitle()
Get title for search index.
getPrefixedURL()
Get a URL-encoded title (not an actual URL) including interwiki.
areRestrictionsCascading()
isSpecial( $name)
Returns true if this title resolves to the named special page.
static newFromID( $id)
Create a new Title from an article ID.
getEscapedText()
Get the HTML-escaped displayable text form.
escapeLocalURL( $query='')
Get an HTML-escaped version of the URL form, suitable for using in a link, without a server name or f...
getFullText()
Get the prefixed title with spaces, plus any fragment (part beginning with '#')
userCan( $action, $doExpensiveQueries=true)
Can $wgUser perform $action on this page?
static newFromURL( $url)
Create a new Title from URL-encoded text.
isLocal()
Determine whether the object refers to a page within this project.
moveNoAuth(&$nt)
Move this page without authentication.
$mCascadeRestrictionSources
loadRestrictionsFromRow( $res, $oldFashionedRestrictions=NULL)
Loads a string into mRestrictions array.
fixSpecialName()
If the Title refers to a special page alias which is not the local default, returns a new Title which...
static legalChars()
Get a regex character class describing the legal characters in a link.
static & makeTitle( $ns, $title)
Create a new Title from a namespace index and a DB key.
isSemiProtected( $action='edit')
Is this page "semi-protected" - the only protection is autoconfirm?
isCssJsSubpage()
Is this a .css or .js subpage of a user page?
getPrefixedDBkey()
Get the prefixed database key form.
getNsText()
Get the namespace text.
getInternalURL( $query='', $variant=false)
Get the URL form for an internal link.
static purgeExpiredRestrictions()
Purge expired restrictions from the page_restrictions table.
getCascadeProtectionSources( $get_pages=true)
Cascading protection: Get the source of any cascading restrictions on this page.
isTrans()
Determine whether the object refers to a page within this project and is transcludable.
resetArticleID( $newid)
This clears some fields in this object, and clears any associated keys in the "bad links" section of ...
getTemplateLinksTo( $options='')
Get an array of Title objects using this Title as a template Also stores the IDs in the link cache.
escapeFullURL( $query='')
Get an HTML-escaped version of the URL form, suitable for using in a link, including the server name ...
static newFromRedirect( $text)
Create a new Title for a redirect.
touchLinks()
Update page_touched timestamps and send squid purge messages for pages linking to this title.
userIsWatching()
Is $wgUser is watching this page?
isExternal()
Is this Title interwiki?
getFragmentForURL()
Get the fragment in URL form, including the "#" character if there is one.
getSubpageUrlForm()
Get a URL-encoded form of the subpage text.
getDBkey()
Get the main part with underscores.
quickUserCan( $action)
Can $wgUser perform $action on this page? This skips potentially expensive cascading permission check...
prefix( $name)
Prefix some arbitrary text with the namespace or interwiki prefix of this object.
userCanEditCssJsSubpage()
Protect css/js subpages of user pages: can $wgUser edit this page?
isValidCssJsSubpage()
Is this a valid .css or .js subpage of a user page? Check that the corresponding skin exists.
getFullURL( $query='', $variant=false)
Get a real URL referring to this title, with interwiki link and fragment.
getPartialURL()
Get the URL-encoded form of the main part.
getBaseText()
Get the base name, i.e.
getText()
Simple accessors.
pageCond()
Get an associative array for selecting this title from the "page" table.
getPreviousRevisionID( $revision)
Get the revision ID of the previous revision.
isJsSubpage()
Is this a .js subpage of a user page?
static newFromIDs( $ids)
Make an array of titles from an array of IDs.
static newMainPage()
Create a new Title for the Main Page.
isCssSubpage()
Is this a .css subpage of a user page?
static indexTitle( $ns, $title)
Get a string representation of a title suitable for including in a search index.
exists()
Check if page exists.
isValidMoveTarget( $nt)
Checks if $this can be moved to a given Title.
getSquidURLs()
Get a list of URLs to purge from the Squid cache when this page changes.
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
static escapeFragmentForURL( $fragment)
Escape a text fragment, say from a link, for a URL.
getArticleID( $flags=0)
Get the article ID for this Title from the link cache, adding it if necessary.
getParentCategoryTree( $children=array())
Get a tree of parent categories.
getInterwikiLink( $key)
Returns the URL associated with an interwiki prefix.
isDeleted()
Is there a version of this page in the deletion archive?
moveOverExistingRedirect(&$nt, $reason='')
Move page to a title which is at present a redirect to the source page.
getLinksTo( $options='', $table='pagelinks', $prefix='pl')
Get a Title object associated with the talk page of this article.
static makeTitleSafe( $ns, $title)
Create a new Title from a namespace index and a DB key.
userCanCreate( $doExpensiveQueries=true)
Can $wgUser create this page?
getEditURL()
Get the edit URL for this Title.
getParentCategories()
Get categories to which this Title belongs and return an array of categories' names.
getLocalURL( $query='', $variant=false)
Get a URL with no fragment or server name.
getNamespaceKey()
Generate strings used for xml 'id' names in monobook tabs.
isSubpage()
Is this a talk page of some sort?
moveToNewTitle(&$nt, $reason='')
Move page to non-existing title.
setFragment( $fragment)
Set the fragment for this title This is kind of bad, since except for this rarely-used function,...
static makeName( $ns, $title)
static getInterwikiCached( $key)
Fetch interwiki prefix data from local cache in constant database.
getInterwiki()
Get the namespace text of the subject (rather than talk) page.
getSubpageText()
Get the lowest-level subpage name, i.e.
getPrefixedText()
Get the prefixed title with spaces.
isAlwaysKnown()
Should a link should be displayed as a known link, just based on its title?
countRevisionsBetween( $old, $new)
Get the number of revisions between the given revision IDs.
static wfUrlencode( $s)
From GlobalFunctions.php.
if($err=$client->getError()) $namespace
if(!is_array($argv)) $options