00001 <?php
00002
00007 class SpecialRecentchangeslinked extends SpecialRecentchanges {
00008 var $rclTargetTitle;
00009
00010 function __construct(){
00011 SpecialPage::SpecialPage( 'Recentchangeslinked' );
00012 $this->includable( true );
00013 }
00014
00015 public function getDefaultOptions() {
00016 $opts = parent::getDefaultOptions();
00017 $opts->add( 'target', '' );
00018 $opts->add( 'showlinkedto', false );
00019 $opts->add( 'tagfilter', '' );
00020 return $opts;
00021 }
00022
00023 public function parseParameters( $par, FormOptions $opts ) {
00024 $opts['target'] = $par;
00025 }
00026
00027 public function feedSetup() {
00028 global $wgRequest;
00029 $opts = parent::feedSetup();
00030 $opts['target'] = $wgRequest->getVal( 'target' );
00031 return $opts;
00032 }
00033
00034 public function getFeedObject( $feedFormat ){
00035 $feed = new ChangesFeed( $feedFormat, false );
00036 $feedObj = $feed->getFeedObject(
00037 wfMsgForContent( 'recentchangeslinked-title', $this->getTargetTitle()->getPrefixedText() ),
00038 wfMsgForContent( 'recentchangeslinked-feed' )
00039 );
00040 return array( $feed, $feedObj );
00041 }
00042
00043 public function doMainQuery( $conds, $opts ) {
00044 global $wgUser, $wgOut;
00045
00046 $target = $opts['target'];
00047 $showlinkedto = $opts['showlinkedto'];
00048 $limit = $opts['limit'];
00049
00050 if ( $target === '' ) {
00051 return false;
00052 }
00053 $title = Title::newFromURL( $target );
00054 if( !$title || $title->getInterwiki() != '' ){
00055 $wgOut->wrapWikiMsg( "<div class=\"errorbox\">\n$1</div><br style=\"clear: both\" />", 'allpagesbadtitle' );
00056 return false;
00057 }
00058
00059 $wgOut->setPageTitle( wfMsg( 'recentchangeslinked-title', $title->getPrefixedText() ) );
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 $dbr = wfGetDB( DB_SLAVE, 'recentchangeslinked' );
00071 $id = $title->getArticleId();
00072 $ns = $title->getNamespace();
00073 $dbkey = $title->getDBkey();
00074
00075 $tables = array( 'recentchanges' );
00076 $select = array( $dbr->tableName( 'recentchanges' ) . '.*' );
00077 $join_conds = array();
00078 $query_options = array();
00079
00080
00081 if( $uid = $wgUser->getId() ) {
00082 $tables[] = 'watchlist';
00083 $select[] = 'wl_user';
00084 $join_conds['watchlist'] = array( 'LEFT JOIN', "wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace" );
00085 }
00086 if ( $wgUser->isAllowed( 'rollback' ) ) {
00087 $tables[] = 'page';
00088 $join_conds['page'] = array('LEFT JOIN', 'rc_cur_id=page_id');
00089 $select[] = 'page_latest';
00090 }
00091
00092 ChangeTags::modifyDisplayQuery( $tables, $select, $conds, $join_conds,
00093 $query_options, $opts['tagfilter'] );
00094
00095
00096
00097
00098 if( $ns == NS_CATEGORY && !$showlinkedto ) {
00099
00100
00101 $link_tables = array( 'categorylinks' );
00102 $showlinkedto = true;
00103 } else {
00104
00105 $link_tables = array( 'pagelinks', 'templatelinks' );
00106
00107 if( $ns == NS_FILE || !$showlinkedto ) $link_tables[] = 'imagelinks';
00108 }
00109
00110 if( $id == 0 && !$showlinkedto )
00111 return false;
00112
00113
00114 $prefix = array( 'pagelinks' => 'pl', 'templatelinks' => 'tl', 'categorylinks' => 'cl', 'imagelinks' => 'il' );
00115
00116 $subsql = array();
00117
00118 foreach( $link_tables as $link_table ) {
00119 $pfx = $prefix[$link_table];
00120
00121
00122 if( $link_table == 'imagelinks' ) $link_ns = NS_FILE;
00123 else if( $link_table == 'categorylinks' ) $link_ns = NS_CATEGORY;
00124 else $link_ns = 0;
00125
00126 if( $showlinkedto ) {
00127
00128 if( $link_ns ) {
00129 if( $ns != $link_ns ) continue;
00130 $subconds = array( "{$pfx}_to" => $dbkey );
00131 } else {
00132 $subconds = array( "{$pfx}_namespace" => $ns, "{$pfx}_title" => $dbkey );
00133 }
00134 $subjoin = "rc_cur_id = {$pfx}_from";
00135 } else {
00136
00137 $subconds = array( "{$pfx}_from" => $id );
00138 if( $link_table == 'imagelinks' || $link_table == 'categorylinks' ) {
00139 $subconds["rc_namespace"] = $link_ns;
00140 $subjoin = "rc_title = {$pfx}_to";
00141 } else {
00142 $subjoin = "rc_namespace = {$pfx}_namespace AND rc_title = {$pfx}_title";
00143 }
00144 }
00145
00146 if( $dbr->unionSupportsOrderAndLimit())
00147 $order = array( 'ORDER BY' => 'rc_timestamp DESC' );
00148 else
00149 $order = array();
00150
00151
00152 $query = $dbr->selectSQLText(
00153 array_merge( $tables, array( $link_table ) ),
00154 $select,
00155 $conds + $subconds,
00156 __METHOD__,
00157 $order + $query_options,
00158 $join_conds + array( $link_table => array( 'INNER JOIN', $subjoin ) )
00159 );
00160
00161 if( $dbr->unionSupportsOrderAndLimit())
00162 $query = $dbr->limitResult( $query, $limit );
00163
00164 $subsql[] = $query;
00165 }
00166
00167 if( count($subsql) == 0 )
00168 return false;
00169 if( count($subsql) == 1 && $dbr->unionSupportsOrderAndLimit() )
00170 $sql = $subsql[0];
00171 else {
00172
00173 $sql = $dbr->unionQueries($subsql, false).' ORDER BY rc_timestamp DESC';
00174 $sql = $dbr->limitResult($sql, $limit, false);
00175 }
00176
00177 $res = $dbr->query( $sql, __METHOD__ );
00178
00179 if( $res->numRows() == 0 )
00180 $this->mResultEmpty = true;
00181
00182 return $res;
00183 }
00184
00185 function getExtraOptions( $opts ){
00186 $opts->consumeValues( array( 'showlinkedto', 'target', 'tagfilter' ) );
00187 $extraOpts = array();
00188 $extraOpts['namespace'] = $this->namespaceFilterForm( $opts );
00189 $extraOpts['target'] = array( wfMsgHtml( 'recentchangeslinked-page' ),
00190 Xml::input( 'target', 40, str_replace('_',' ',$opts['target']) ) .
00191 Xml::check( 'showlinkedto', $opts['showlinkedto'], array('id' => 'showlinkedto') ) . ' ' .
00192 Xml::label( wfMsg("recentchangeslinked-to"), 'showlinkedto' ) );
00193 $tagFilter = ChangeTags::buildTagFilterSelector( $opts['tagfilter'] );
00194 if ($tagFilter)
00195 $extraOpts['tagfilter'] = $tagFilter;
00196 return $extraOpts;
00197 }
00198
00199 function getTargetTitle() {
00200 if ( $this->rclTargetTitle === null ) {
00201 $opts = $this->getOptions();
00202 if ( isset( $opts['target'] ) && $opts['target'] !== '' ) {
00203 $this->rclTargetTitle = Title::newFromText( $opts['target'] );
00204 } else {
00205 $this->rclTargetTitle = false;
00206 }
00207 }
00208 return $this->rclTargetTitle;
00209 }
00210
00211 function setTopText( OutputPage $out, FormOptions $opts ) {
00212 global $wgUser;
00213 $skin = $wgUser->getSkin();
00214 $target = $this->getTargetTitle();
00215 if( $target )
00216 $out->setSubtitle( wfMsg( 'recentchangeslinked-backlink', $skin->link( $target,
00217 $target->getPrefixedText(), array(), array( 'redirect' => 'no' ) ) ) );
00218 }
00219
00220 public function getFeedQuery() {
00221 $target = $this->getTargetTitle();
00222 if( $target ) {
00223 return "target=" . urlencode( $target->getPrefixedDBkey() );
00224 } else {
00225 return false;
00226 }
00227 }
00228
00229 function setBottomText( OutputPage $out, FormOptions $opts ) {
00230 if( isset( $this->mResultEmpty ) && $this->mResultEmpty ){
00231 $out->addWikiMsg( 'recentchangeslinked-noresult' );
00232 }
00233 }
00234 }