<?php
# See title.doc
-/* private static */ $title_interwiki_cache = array();
+$wgTitleInterwikiCache = array();
# Title class
#
# From text, such as what you would find in a link
/* static */ function newFromText( $text, $defaultNamespace = 0 )
{
- static $trans;
$fname = "Title::newFromText";
wfProfileIn( $fname );
-
- # Note - mixing latin1 named entities and unicode numbered
- # ones will result in a bad link.
- if( !isset( $trans ) ) {
- global $wgInputEncoding;
- $trans = array_flip( get_html_translation_table( HTML_ENTITIES ) );
- if( strcasecmp( "utf-8", $wgInputEncoding ) == 0 ) {
- $trans = array_map( "utf8_encode", $trans );
- }
- }
if( is_object( $text ) ) {
wfDebugDieBacktrace( "Called with object instead of string." );
}
- $text = strtr( $text, $trans );
-
+ global $wgInputEncoding;
+ $text = do_html_entity_decode( $text, ENT_COMPAT, $wgInputEncoding );
+
$text = wfMungeToUtf8( $text );
$t = new Title();
$t->mDbkeyform = str_replace( " ", "_", $text );
- $t->mDefaultNamespace = $defaultNamespace;
-
+ $t->mDefaultNamespace = $defaultNamespace;
+
wfProfileOut( $fname );
+ if ( !is_object( $t ) ) {
+ var_dump( debug_backtrace() );
+ }
if( $t->secureAndSplit() ) {
return $t;
} else {
{
global $wgLang, $wgServer;
$t = new Title();
- $s = urldecode( $url ); # This is technically wrong, as anything
- # we've gotten is already decoded by PHP.
- # Kept for backwards compatibility with
- # buggy URLs we had for a while...
- $s = $url;
+
+ # For compatibility with old buggy URLs. "+" is not valid in titles,
+ # but some URLs used it as a space replacement and they still come
+ # from some external search tools.
+ $s = str_replace( "+", " ", $url );
# For links that came from outside, check for alternate/legacy
# character encoding.
$t->mDbkeyform = str_replace( " ", "_", $s );
if( $t->secureAndSplit() ) {
-
- # check that lenght of title is < cur_title size
- $sql = "SHOW COLUMNS FROM cur LIKE \"cur_title\";";
- $cur_title_object = wfFetchObject(wfQuery( $sql, DB_READ ));
-
- preg_match( "/\((.*)\)/", $cur_title_object->Type, $cur_title_size);
-
- if (strlen($t->mDbkeyform) > $cur_title_size[1] ) {
+ # check that length of title is < cur_title size
+ $dbr =& wfGetDB( DB_SLAVE );
+ $maxSize = $dbr->textFieldSize( 'cur', 'cur_title' );
+ if ( $maxSize != -1 && strlen( $t->mDbkeyform ) > $maxSize ) {
return NULL;
}
/* static */ function newFromID( $id )
{
$fname = "Title::newFromID";
- $row = wfGetArray( "cur", array( "cur_namespace", "cur_title" ),
+ $dbr =& wfGetDB( DB_SLAVE );
+ $row = $dbr->getArray( "cur", array( "cur_namespace", "cur_title" ),
array( "cur_id" => $id ), $fname );
if ( $row !== false ) {
$title = Title::makeTitle( $row->cur_namespace, $row->cur_title );
# Get the prefixed DB key associated with an ID
/* static */ function nameOf( $id )
{
- $sql = "SELECT cur_namespace,cur_title FROM cur WHERE " .
- "cur_id={$id}";
- $res = wfQuery( $sql, DB_READ, "Article::nameOf" );
- if ( 0 == wfNumRows( $res ) ) { return NULL; }
+ $fname = 'Title::nameOf';
+ $dbr =& wfGetDB( DB_SLAVE );
+
+ $s = $dbr->getArray( 'cur', array( 'cur_namespace','cur_title' ), array( 'cur_id' => $id ), $fname );
+ if ( $s === false ) { return NULL; }
- $s = wfFetchObject( $res );
$n = Title::makeName( $s->cur_namespace, $s->cur_title );
return $n;
}
# Missing characters:
# * []|# Needed for link syntax
# * % and + are corrupted by Apache when they appear in the path
- #
+ #
+ # % seems to work though
+ #
+ # The problem with % is that URLs are double-unescaped: once by Apache's
+ # path conversion code, and again by PHP. So %253F, for example, becomes "?".
+ # Our code does not double-escape to compensate for this, indeed double escaping
+ # would break if the double-escaped title was passed in the query string
+ # rather than the path. This is a minor security issue because articles can be
+ # created such that they are hard to view or edit. -- TS
+ #
# Theoretically 0x80-0x9F of ISO 8859-1 should be disallowed, but
# this breaks interlanguage links
- $set = " !\"$&'()*,\\-.\\/0-9:;<=>?@A-Z\\\\^_`a-z{}~\\x80-\\xFF";
+ $set = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z{}~\\x80-\\xFF";
return $set;
}
# The URL contains $1, which is replaced by the title
function getInterwikiLink( $key )
{
- global $wgMemc, $wgDBname, $title_interwiki_cache;
+ global $wgMemc, $wgDBname, $wgInterwikiExpiry, $wgTitleInterwikiCache;
+ $fname = 'Title::getInterwikiLink';
$k = "$wgDBname:interwiki:$key";
- if( array_key_exists( $k, $title_interwiki_cache ) )
- return $title_interwiki_cache[$k]->iw_url;
+ if( array_key_exists( $k, $wgTitleInterwikiCache ) )
+ return $wgTitleInterwikiCache[$k]->iw_url;
$s = $wgMemc->get( $k );
- if( $s ) {
- $title_interwiki_cache[$k] = $s;
+ # Ignore old keys with no iw_local
+ if( $s && isset( $s->iw_local ) ) {
+ $wgTitleInterwikiCache[$k] = $s;
return $s->iw_url;
}
- $dkey = wfStrencode( $key );
- $query = "SELECT iw_url FROM interwiki WHERE iw_prefix='$dkey'";
- $res = wfQuery( $query, DB_READ, "Title::getInterwikiLink" );
- if(!$res) return "";
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'interwiki', array( 'iw_url', 'iw_local' ), array( 'iw_prefix' => $key ), $fname );
+ if(!$res) return "";
- $s = wfFetchObject( $res );
+ $s = $dbr->fetchObject( $res );
if(!$s) {
+ # Cache non-existence: create a blank object and save it to memcached
$s = (object)false;
$s->iw_url = "";
+ $s->iw_local = 0;
}
- $wgMemc->set( $k, $s );
- $title_interwiki_cache[$k] = $s;
+ $wgMemc->set( $k, $s, $wgInterwikiExpiry );
+ $wgTitleInterwikiCache[$k] = $s;
return $s->iw_url;
}
-
+
+ function isLocal() {
+ global $wgTitleInterwikiCache, $wgDBname;
+
+ if ( $this->mInterwiki != "" ) {
+ # Make sure key is loaded into cache
+ $this->getInterwikiLink( $this->mInterwiki );
+ $k = "$wgDBname:interwiki:" . $this->mInterwiki;
+ return (bool)($wgTitleInterwikiCache[$k]->iw_local);
+ } else {
+ return true;
+ }
+ }
+
# Update the cur_touched field for an array of title objects
# Inefficient unless the IDs are already loaded into the link cache
/* static */ function touchArray( $titles, $timestamp = "" ) {
if ( $timestamp == "" ) {
$timestamp = wfTimestampNow();
}
- $sql = "UPDATE cur SET cur_touched='{$timestamp}' WHERE cur_id IN (";
+ $dbw =& wfGetDB( DB_MASTER );
+ $cur = $dbw->tableName( 'cur' );
+ $sql = "UPDATE $cur SET cur_touched='{$timestamp}' WHERE cur_id IN (";
$first = true;
foreach ( $titles as $title ) {
if ( ! $first ) {
$sql .= ",";
}
-
$first = false;
$sql .= $title->getArticleID();
}
$sql .= ")";
if ( ! $first ) {
- wfQuery( $sql, DB_WRITE, "Title::touchArray" );
+ $dbw->query( $sql, "Title::touchArray" );
}
}
$n = $wgLang->getNsText( $this->mNamespace );
if ( "" != $n ) { $n .= ":"; }
$u = str_replace( "$1", $n . $this->mUrlform, $p );
- if ( "" != $this->mFragment ) {
- $u .= "#" . wfUrlencode( $this->mFragment );
- }
return $u;
}
function userCanEdit()
{
global $wgUser;
-
if ( -1 == $this->mNamespace ) { return false; }
+ if ( NS_MEDIAWIKI == $this->mNamespace && !$wgUser->isSysop() ) { return false; }
# if ( 0 == $this->getArticleID() ) { return false; }
if ( $this->mDbkeyform == "_" ) { return false; }
-
+ # protect global styles and js
+ if ( NS_MEDIAWIKI == $this->mNamespace
+ && preg_match("/\\.(css|js)$/", $this->mTextform )
+ && !$wgUser->isSysop() )
+ { return false; }
+ //if ( $this->isCssJsSubpage() and !$this->userCanEditCssJsSubpage() ) { return false; }
+ # protect css/js subpages of user pages
+ # XXX: this might be better using restrictions
+ # XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working
+ if( Namespace::getUser() == $this->mNamespace
+ and preg_match("/\\.(css|js)$/", $this->mTextform )
+ and !$wgUser->isSysop()
+ and !preg_match("/^".preg_quote($wgUser->getName(), '/')."/", $this->mTextform) )
+ { return false; }
$ur = $wgUser->getRights();
foreach ( $this->getRestrictions() as $r ) {
if ( "" != $r && ( ! in_array( $r, $ur ) ) ) {
}
return true;
}
+
+ function userCanRead() {
+ global $wgUser;
+ global $wgWhitelistRead;
+
+ if( 0 != $wgUser->getID() ) return true;
+ if( !is_array( $wgWhitelistRead ) ) return true;
+
+ $name = $this->getPrefixedText();
+ if( in_array( $name, $wgWhitelistRead ) ) return true;
+
+ # Compatibility with old settings
+ if( $this->getNamespace() == NS_MAIN ) {
+ if( in_array( ":" . $name, $wgWhitelistRead ) ) return true;
+ }
+ return false;
+ }
+
+ function isCssJsSubpage() {
+ return ( Namespace::getUser() == $this->mNamespace and preg_match("/\\.(css|js)$/", $this->mTextform ) );
+ }
+ function isCssSubpage() {
+ return ( Namespace::getUser() == $this->mNamespace and preg_match("/\\.css$/", $this->mTextform ) );
+ }
+ function isJsSubpage() {
+ return ( Namespace::getUser() == $this->mNamespace and preg_match("/\\.js$/", $this->mTextform ) );
+ }
+ function userCanEditCssJsSubpage() {
+ # protect css/js subpages of user pages
+ # XXX: this might be better using restrictions
+ global $wgUser;
+ return ( $wgUser->isSysop() or preg_match("/^".preg_quote($wgUser->getName())."/", $this->mTextform) );
+ }
# Accessor/initialisation for mRestrictions
function getRestrictions()
if ( 0 == $id ) { return array(); }
if ( ! $this->mRestrictionsLoaded ) {
- $res = wfGetSQL( "cur", "cur_restrictions", "cur_id=$id" );
+ $dbr =& wfGetDB( DB_SLAVE );
+ $res = $dbr->getField( "cur", "cur_restrictions", "cur_id=$id" );
$this->mRestrictions = explode( ",", trim( $res ) );
$this->mRestrictionsLoaded = true;
}
}
# Is there a version of this page in the deletion archive?
+ # Returns the number of archived revisions
function isDeleted() {
- $ns = $this->getNamespace();
- $t = wfStrencode( $this->getDBkey() );
- $sql = "SELECT COUNT(*) AS n FROM archive WHERE ar_namespace=$ns AND ar_title='$t'";
- if( $res = wfQuery( $sql, DB_READ ) ) {
- $s = wfFetchObject( $res );
- return $s->n;
- }
- return 0;
+ $fname = 'Title::isDeleted';
+ $dbr =& wfGetDB( DB_SLAVE );
+ $n = $dbr->getField( 'archive', 'COUNT(*)', array( 'ar_namespace' => $this->getNamespace(),
+ 'ar_title' => $this->getDBkey() ), $fname );
+ return (int)$n;
}
# Get the article ID from the link cache
# Called from LinksUpdate.php
function invalidateCache() {
$now = wfTimestampNow();
- $ns = $this->getNamespace();
- $ti = wfStrencode( $this->getDBkey() );
- $sql = "UPDATE cur SET cur_touched='$now' WHERE cur_namespace=$ns AND cur_title='$ti'";
- return wfQuery( $sql, DB_WRITE, "Title::invalidateCache" );
+ $dbw =& wfGetDB( DB_MASTER );
+ $success = $dbw->updateArray( 'cur',
+ array( /* SET */
+ 'cur_touched' => wfTimestampNow()
+ ), array( /* WHERE */
+ 'cur_namespace' => $this->getNamespace() ,
+ 'cur_title' => $this->getDBkey()
+ ), 'Title::invalidateCache'
+ );
+ return $success;
}
# Prefixes some arbitrary text with the namespace or interwiki prefix of this object
# Secure and split - main initialisation function for this object
#
# Assumes that mDbkeyform has been set, and is urldecoded
- # and uses undersocres, but not otherwise munged. This function
- # removes illegal characters, splits off the winterwiki and
+ # and uses underscores, but not otherwise munged. This function
+ # removes illegal characters, splits off the interwiki and
# namespace prefixes, sets the other forms, and canonicalizes
# everything.
#
/* private */ function secureAndSplit()
{
- global $wgLang, $wgLocalInterwiki;
+ global $wgLang, $wgLocalInterwiki, $wgCapitalLinks;
$fname = "Title::secureAndSplit";
wfProfileIn( $fname );
# Initialisation
if ( $imgpre === false ) {
$imgpre = ":" . $wgLang->getNsText( Namespace::getImage() ) . ":";
+ # % is needed as well
$rxTc = "/[^" . Title::legalChars() . "]/";
}
# Clean up whitespace
#
$t = preg_replace( "/[\\s_]+/", "_", $this->mDbkeyform );
- if ( "_" == @$t{0} ) {
- $t = substr( $t, 1 );
- }
- $l = strlen( $t );
- if ( $l && ( "_" == $t{$l-1} ) ) {
- $t = substr( $t, 0, $l-1 );
- }
+ $t = preg_replace( '/^_*(.*?)_*$/', '$1', $t );
+
if ( "" == $t ) {
wfProfileOut( $fname );
return false;
$this->mNamespace = NS_MAIN;
} else {
# Namespace or interwiki prefix
- if ( preg_match( "/^((?:i|x|[a-z]{2,3})(?:-[a-z0-9]+)?|[A-Za-z0-9_\\x80-\\xff]+?)_*:_*(.*)$/", $t, $m ) ) {
+ if ( preg_match( "/^(.+?)_*:_*(.*)$/", $t, $m ) ) {
#$p = strtolower( $m[1] );
$p = $m[1];
- if ( $ns = $wgLang->getNsIndex( strtolower( $p ) )) {
+ $lowerNs = strtolower( $p );
+ if ( $ns = Namespace::getCanonicalIndex( $lowerNs ) ) {
+ # Canonical namespace
+ $t = $m[2];
+ $this->mNamespace = $ns;
+ } elseif ( $ns = $wgLang->getNsIndex( $lowerNs )) {
# Ordinary namespace
$t = $m[2];
$this->mNamespace = $ns;
# Reject illegal characters.
#
if( preg_match( $rxTc, $r ) ) {
+ wfProfileOut( $fname );
return false;
}
- # "." and ".." conflict with the directories of those names
- if ( $r === "." || $r === ".." ) {
+ # "." and ".." conflict with the directories of those namesa
+ if ( strpos( $r, "." ) !== false &&
+ ( $r === "." || $r === ".." ||
+ strpos( $r, "./" ) === 0 ||
+ strpos( $r, "/./" !== false ) ||
+ strpos( $r, "/../" !== false ) ) )
+ {
+ wfProfileOut( $fname );
return false;
}
# Initial capital letter
- if( $this->mInterwiki == "") $t = $wgLang->ucfirst( $r );
-
+ if( $wgCapitalLinks && $this->mInterwiki == "") {
+ $t = $wgLang->ucfirst( $r );
+ }
+
# Fill fields
$this->mDbkeyform = $t;
$this->mUrlform = wfUrlencode( $t );
# Get an array of Title objects linking to this title
# Also stores the IDs in the link cache
- function getLinksTo() {
+ # $options may be FOR UPDATE
+ function getLinksTo( $options = '' ) {
global $wgLinkCache;
$id = $this->getArticleID();
- $sql = "SELECT cur_namespace,cur_title,cur_id FROM cur,links WHERE l_from=cur_id AND l_to={$id}";
- $res = wfQuery( $sql, DB_READ, "Title::getLinksTo" );
+
+ if ( $options ) {
+ $db =& wfGetDB( DB_MASTER );
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ }
+ $cur = $db->tableName( 'cur' );
+ $links = $db->tableName( 'links' );
+
+ $sql = "SELECT cur_namespace,cur_title,cur_id FROM $cur,$links WHERE l_from=cur_id AND l_to={$id} $options";
+ $res = $db->query( $sql, "Title::getLinksTo" );
$retVal = array();
- if ( wfNumRows( $res ) ) {
- while ( $row = wfFetchObject( $res ) ) {
- $titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title );
- $wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
- $retVal[] = $titleObj;
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
+ if ( $titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title ) ) {
+ $wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
+ $retVal[] = $titleObj;
+ }
}
}
- wfFreeResult( $res );
+ $db->freeResult( $res );
return $retVal;
}
# Get an array of Title objects linking to this non-existent title
# Also stores the IDs in the link cache
- function getBrokenLinksTo() {
+ function getBrokenLinksTo( $options = '' ) {
global $wgLinkCache;
- $encTitle = wfStrencode( $this->getPrefixedDBkey() );
- $sql = "SELECT cur_namespace,cur_title,cur_id FROM brokenlinks,cur " .
- "WHERE bl_from=cur_id AND bl_to='$encTitle'";
- $res = wfQuery( $sql, DB_READ, "Title::getBrokenLinksTo" );
+
+ if ( $options ) {
+ $db =& wfGetDB( DB_MASTER );
+ } else {
+ $db =& wfGetDB( DB_SLAVE );
+ }
+ $cur = $db->tableName( 'cur' );
+ $brokenlinks = $db->tableName( 'brokenlinks' );
+ $encTitle = $db->strencode( $this->getPrefixedDBkey() );
+
+ $sql = "SELECT cur_namespace,cur_title,cur_id FROM $brokenlinks,$cur " .
+ "WHERE bl_from=cur_id AND bl_to='$encTitle' $options";
+ $res = $db->query( $sql, "Title::getBrokenLinksTo" );
$retVal = array();
- if ( wfNumRows( $res ) ) {
- while ( $row = wfFetchObject( $res ) ) {
+ if ( $db->numRows( $res ) ) {
+ while ( $row = $db->fetchObject( $res ) ) {
$titleObj = Title::makeTitle( $row->cur_namespace, $row->cur_title );
- $wgLinkCache->addGoodLink( $titleObj->getPrefixedDBkey(), $row->cur_id );
+ $wgLinkCache->addGoodLink( $row->cur_id, $titleObj->getPrefixedDBkey() );
$retVal[] = $titleObj;
}
}
- wfFreeResult( $res );
+ $db->freeResult( $res );
return $retVal;
}
# Returns true on success, message name on failure
# auth indicates whether wgUser's permissions should be checked
function moveTo( &$nt, $auth = true ) {
- $fname = "Title::move";
- $oldid = $this->getArticleID();
- $newid = $nt->getArticleID();
-
if( !$this or !$nt ) {
return "badtitletext";
}
+ $fname = "Title::move";
+ $oldid = $this->getArticleID();
+ $newid = $nt->getArticleID();
+
if ( strlen( $nt->getDBkey() ) < 1 ) {
return "articleexists";
}
$won = wfInvertTimestamp( $now );
$newid = $nt->getArticleID();
$oldid = $this->getArticleID();
-
+ $dbw =& wfGetDB( DB_MASTER );
+ $links = $dbw->tableName( 'links' );
+
# Change the name of the target page:
- wfUpdateArray(
- /* table */ 'cur',
+ $dbw->updateArray( 'cur',
/* SET */ array(
'cur_touched' => $now,
'cur_namespace' => $nt->getNamespace(),
# by definition if we've got here it's rather uninteresting.
$redirectText = $wgMwRedir->getSynonym( 0 ) . " [[" . $nt->getPrefixedText() . "]]\n";
- wfUpdateArray(
- /* table */ 'cur',
+ $dbw->updateArray( 'cur',
/* SET */ array(
'cur_touched' => $now,
'cur_timestamp' => $now,
# Fix the redundant names for the past revisions of the target page.
# The redirect should have no old revisions.
- wfUpdateArray(
+ $dbw->updateArray(
/* table */ 'old',
/* SET */ array(
'old_namespace' => $nt->getNamespace(),
$fname
);
- RecentChange::notifyMove( $now, $this, $nt, $wgUser, $comment );
+ RecentChange::notifyMoveOverRedirect( $now, $this, $nt, $wgUser, $comment );
# Swap links
# Load titles and IDs
- $linksToOld = $this->getLinksTo();
- $linksToNew = $nt->getLinksTo();
+ $linksToOld = $this->getLinksTo( 'FOR UPDATE' );
+ $linksToNew = $nt->getLinksTo( 'FOR UPDATE' );
- # Make function to convert Titles to IDs
- $titleToID = create_function('$t', 'return $t->getArticleID();');
-
- # Reassign links to old title
- if ( count( $linksToOld ) ) {
- $sql = "UPDATE links SET l_to=$newid WHERE l_from IN (";
- $sql .= implode( ",", array_map( $titleToID, $linksToOld ) );
- $sql .= ")";
- wfQuery( $sql, DB_WRITE, $fname );
- }
-
- # Reassign links to new title
- if ( count( $linksToNew ) ) {
- $sql = "UPDATE links SET l_to=$oldid WHERE l_from IN (";
- $sql .= implode( ",", array_map( $titleToID, $linksToNew ) );
- $sql .= ")";
- wfQuery( $sql, DB_WRITE, $fname );
- }
+ # Delete them all
+ $sql = "DELETE FROM $links WHERE l_to=$oldid OR l_to=$newid";
+ $dbw->query( $sql, $fname );
+
+ # Reinsert
+ if ( count( $linksToOld ) || count( $linksToNew )) {
+ $sql = "INSERT INTO $links (l_from,l_to) VALUES ";
+ $first = true;
+
+ # Insert links to old title
+ foreach ( $linksToOld as $linkTitle ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $id = $linkTitle->getArticleID();
+ $sql .= "($id,$newid)";
+ }
+
+ # Insert links to new title
+ foreach ( $linksToNew as $linkTitle ) {
+ if ( $first ) {
+ $first = false;
+ } else {
+ $sql .= ",";
+ }
+ $id = $linkTitle->getArticleID();
+ $sql .= "($id, $oldid)";
+ }
- # Note: the insert below must be after the updates above!
+ $dbw->query( $sql, DB_MASTER, $fname );
+ }
# Now, we record the link from the redirect to the new title.
# It should have no other outgoing links...
- $sql = "DELETE FROM links WHERE l_from={$newid}";
- wfQuery( $sql, DB_WRITE, $fname );
- $sql = "INSERT INTO links (l_from,l_to) VALUES ({$newid},{$oldid})";
- wfQuery( $sql, DB_WRITE, $fname );
-
+ $dbw->delete( 'links', array( 'l_from' => $newid ) );
+ $dbw->insertArray( 'links', array( 'l_from' => $newid, 'l_to' => $oldid ) );
+
+ # Clear linkscc
+ LinkCache::linksccClearLinksTo( $oldid );
+ LinkCache::linksccClearLinksTo( $newid );
+
# Purge squid
if ( $wgUseSquid ) {
$urls = array_merge( $nt->getSquidURLs(), $this->getSquidURLs() );
$won = wfInvertTimestamp( $now );
$newid = $nt->getArticleID();
$oldid = $this->getArticleID();
+ $dbw =& wfGetDB( DB_MASTER );
# Rename cur entry
- wfUpdateArray(
- /* table */ 'cur',
+ $dbw->updateArray( 'cur',
/* SET */ array(
'cur_touched' => $now,
'cur_namespace' => $nt->getNamespace(),
$wgLinkCache->clearLink( $nt->getPrefixedDBkey() );
# Insert redirct
- wfInsertArray( 'cur', array(
+ $dbw->insertArray( 'cur', array(
'cur_namespace' => $this->getNamespace(),
'cur_title' => $this->getDBkey(),
'cur_comment' => $comment,
'cur_touched' => $now,
'cur_is_redirect' => 1,
'cur_is_new' => 1,
- 'cur_text' => "#REDIRECT [[" . $nt->getPrefixedText() . "]]\n" )
+ 'cur_text' => "#REDIRECT [[" . $nt->getPrefixedText() . "]]\n" ), $fname
);
- $newid = wfInsertId();
+ $newid = $dbw->insertId();
$wgLinkCache->clearLink( $this->getPrefixedDBkey() );
# Rename old entries
- wfUpdateArray(
+ $dbw->updateArray(
/* table */ 'old',
/* SET */ array(
'old_namespace' => $nt->getNamespace(),
), $fname
);
- # Miscellaneous updates
+ # Record in RC
+ RecentChange::notifyMoveToNew( $now, $this, $nt, $wgUser, $comment );
- RecentChange::notifyMove( $now, $this, $nt, $wgUser, $comment );
+ # Purge squid and linkscc as per article creation
Article::onArticleCreate( $nt );
# Any text links to the old title must be reassigned to the redirect
- $sql = "UPDATE links SET l_to={$newid} WHERE l_to={$oldid}";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->updateArray( 'links', array( 'l_to' => $newid ), array( 'l_to' => $oldid ), $fname );
+ LinkCache::linksccClearLinksTo( $oldid );
# Record the just-created redirect's linking to the page
- $sql = "INSERT INTO links (l_from,l_to) VALUES ({$newid},{$oldid})";
- wfQuery( $sql, DB_WRITE, $fname );
+ $dbw->insertArray( 'links', array( 'l_from' => $newid, 'l_to' => $oldid ), $fname );
# Non-existent target may have had broken links to it; these must
# now be removed and made into good links.
}
# Checks if $this can be moved to $nt
- # Both titles must exist in the database, otherwise it will blow up
+ # Selects for update, so don't call it unless you mean business
function isValidMoveTarget( $nt )
{
$fname = "Title::isValidMoveTarget";
+ $dbw =& wfGetDB( DB_MASTER );
# Is it a redirect?
$id = $nt->getArticleID();
- $sql = "SELECT cur_is_redirect,cur_text FROM cur " .
- "WHERE cur_id={$id}";
- $res = wfQuery( $sql, DB_READ, $fname );
- $obj = wfFetchObject( $res );
+ $obj = $dbw->getArray( 'cur', array( 'cur_is_redirect','cur_text' ),
+ array( 'cur_id' => $id ), $fname, 'FOR UPDATE' );
- if ( 0 == $obj->cur_is_redirect ) {
+ if ( !$obj || 0 == $obj->cur_is_redirect ) {
# Not a redirect
return false;
}
}
# Does the article have a history?
- $row = wfGetArray( 'old', array( 'old_id' ), array(
- 'old_namespace' => $nt->getNamespace(),
- 'old_title' => $nt->getDBkey() )
+ $row = $dbw->getArray( 'old', array( 'old_id' ),
+ array(
+ 'old_namespace' => $nt->getNamespace(),
+ 'old_title' => $nt->getDBkey()
+ ), $fname, 'FOR UPDATE'
);
# Return true if there was no history
return false;
}
+ $fname = "Title::createRedirect";
+ $dbw =& wfGetDB( DB_MASTER );
$now = wfTimestampNow();
$won = wfInvertTimestamp( $now );
+ $seqVal = $dbw->nextSequenceValue( 'cur_cur_id_seq' );
- wfInsertArray( 'cur', array(
+ $dbw->insertArray( 'cur', array(
+ 'cur_id' => $seqVal,
'cur_namespace' => $this->getNamespace(),
'cur_title' => $this->getDBkey(),
'cur_comment' => $comment,
'cur_is_redirect' => 1,
'cur_is_new' => 1,
'cur_text' => "#REDIRECT [[" . $dest->getPrefixedText() . "]]\n"
- ));
- $newid = wfInsertId();
+ ), $fname );
+ $newid = $dbw->insertId();
$this->resetArticleID( $newid );
# Link table
if ( $dest->getArticleID() ) {
- wfInsertArray( 'links', array(
- 'l_to' => $dest->getArticleID(),
- 'l_from' => $newid
- ));
+ $dbw->insertArray( 'links',
+ array(
+ 'l_to' => $dest->getArticleID(),
+ 'l_from' => $newid
+ ), $fname
+ );
} else {
- wfInsertArray( 'brokenlinks', array(
- 'bl_to' => $dest->getPrefixedDBkey(),
- 'bl_from' => $newid
- ));
+ $dbw->insertArray( 'brokenlinks',
+ array(
+ 'bl_to' => $dest->getPrefixedDBkey(),
+ 'bl_from' => $newid
+ ), $fname
+ );
}
Article::onArticleCreate( $this );
return true;
}
+
+ # Get categories to wich belong this title and return an array of
+ # categories names.
+ function getParentCategories( )
+ {
+ global $wgLang,$wgUser;
+
+ $titlekey = $this->getArticleId();
+ $cns = Namespace::getCategory();
+ $sk =& $wgUser->getSkin();
+ $parents = array();
+ $dbr =& wfGetDB( DB_SLAVE );
+ $cur = $dbr->tableName( 'cur' );
+ $categorylinks = $dbr->tableName( 'categorylinks' );
+
+ # get the parents categories of this title from the database
+ $sql = "SELECT DISTINCT cur_id FROM $cur,$categorylinks
+ WHERE cl_from='$titlekey' AND cl_to=cur_title AND cur_namespace='$cns'
+ ORDER BY cl_sortkey" ;
+ $res = $dbr->query ( $sql ) ;
+
+ if($dbr->numRows($res) > 0) {
+ while ( $x = $dbr->fetchObject ( $res ) ) $data[] = $x ;
+ $dbr->freeResult ( $res ) ;
+ } else {
+ $data = '';
+ }
+ return $data;
+ }
+
+ # will get the parents and grand-parents
+ # TODO : not sure what's happening when a loop happen like:
+ # Encyclopedia > Astronomy > Encyclopedia
+ function getAllParentCategories(&$stack)
+ {
+ global $wgUser,$wgLang;
+ $result = '';
+
+ # getting parents
+ $parents = $this->getParentCategories( );
+
+ if($parents == '')
+ {
+ # The current element has no more parent so we dump the stack
+ # and make a clean line of categories
+ $sk =& $wgUser->getSkin() ;
+
+ foreach ( array_reverse($stack) as $child => $parent )
+ {
+ # make a link of that parent
+ $result .= $sk->makeLink($wgLang->getNSText ( Namespace::getCategory() ).":".$parent,$parent);
+ $result .= ' > ';
+ $lastchild = $child;
+ }
+ # append the last child.
+ # TODO : We should have a last child unless there is an error in the
+ # "categorylinks" table.
+ if(isset($lastchild)) { $result .= $lastchild; }
+
+ $result .= "<br/>\n";
+
+ # now we can empty the stack
+ $stack = array();
+
+ } else {
+ # look at parents of current category
+ foreach($parents as $parent)
+ {
+ # create a title object for the parent
+ $tpar = Title::newFromID($parent->cur_id);
+ # add it to the stack
+ $stack[$this->getText()] = $tpar->getText();
+ # grab its parents
+ $result .= $tpar->getAllParentCategories($stack);
+ }
+ }
+
+ if(isset($result)) { return $result; }
+ else { return ''; };
+ }
+
+ # Returns an associative array for selecting this title from cur
+ function curCond() {
+ return array( 'cur_namespace' => $this->mNamespace, 'cur_title' => $this->mDbkeyform );
+ }
+
+ function oldCond() {
+ return array( 'old_namespace' => $this->mNamespace, 'old_title' => $this->mDbkeyform );
+ }
}
?>