00001 <?php
00002
00003 if (!defined( 'MEDIAWIKI' ))
00004 die;
00005
00006 class ChangeTags {
00007 static function formatSummaryRow( $tags, $page ) {
00008 if (!$tags)
00009 return array('',array());
00010
00011 $classes = array();
00012
00013 $tags = explode( ',', $tags );
00014 $displayTags = array();
00015 foreach( $tags as $tag ) {
00016 $displayTags[] = self::tagDescription( $tag );
00017 $classes[] = "mw-tag-$tag";
00018 }
00019
00020 return array( '(' . implode( ', ', $displayTags ) . ')', $classes );
00021 }
00022
00023 static function tagDescription( $tag ) {
00024 $msg = wfMsgExt( "tag-$tag", 'parseinline' );
00025 if ( wfEmptyMsg( "tag-$tag", $msg ) ) {
00026 return htmlspecialchars($tag);
00027 }
00028 return $msg;
00029 }
00030
00031 ## Basic utility method to add tags to a particular change, given its rc_id, rev_id and/or log_id.
00032 static function addTags( $tags, $rc_id=null, $rev_id=null, $log_id=null, $params = null ) {
00033 if ( !is_array($tags) ) {
00034 $tags = array( $tags );
00035 }
00036
00037 $tags = array_filter( $tags );
00038
00039 if (!$rc_id && !$rev_id && !$log_id) {
00040 throw new MWException( "At least one of: RCID, revision ID, and log ID MUST be specified when adding a tag to a change!" );
00041 }
00042
00043 $dbr = wfGetDB( DB_SLAVE );
00044
00045
00046 if (!$rc_id) {
00047 $dbr = wfGetDB( DB_MASTER );
00048 if ($log_id) {
00049 $rc_id = $dbr->selectField( 'recentchanges', 'rc_id', array( 'rc_logid' => $log_id ), __METHOD__ );
00050 } elseif ($rev_id) {
00051 $rc_id = $dbr->selectField( 'recentchanges', 'rc_id', array( 'rc_this_oldid' => $rev_id ), __METHOD__ );
00052 }
00053 } elseif (!$log_id && !$rev_id) {
00054 $dbr = wfGetDB( DB_MASTER );
00055 $log_id = $dbr->selectField( 'recentchanges', 'rc_logid', array( 'rc_id' => $rc_id ), __METHOD__ );
00056 $rev_id = $dbr->selectField( 'recentchanges', 'rc_this_oldid', array( 'rc_id' => $rc_id ), __METHOD__ );
00057 }
00058
00059 $tsConds = array_filter( array( 'ts_rc_id' => $rc_id, 'ts_rev_id' => $rev_id, 'ts_log_id' => $log_id ) );
00060
00061 ## Update the summary row.
00062 $prevTags = $dbr->selectField( 'tag_summary', 'ts_tags', $tsConds, __METHOD__ );
00063 $prevTags = $prevTags ? $prevTags : '';
00064 $prevTags = array_filter( explode( ',', $prevTags ) );
00065 $newTags = array_unique( array_merge( $prevTags, $tags ) );
00066 sort($prevTags);
00067 sort($newTags);
00068
00069 if ( $prevTags == $newTags ) {
00070
00071 return false;
00072 }
00073
00074 $dbw = wfGetDB( DB_MASTER );
00075 $dbw->replace( 'tag_summary', array( 'ts_rev_id', 'ts_rc_id', 'ts_log_id' ), array_filter( array_merge( $tsConds, array( 'ts_tags' => implode( ',', $newTags ) ) ) ), __METHOD__ );
00076
00077
00078 $tagsRows = array();
00079 foreach( $tags as $tag ) {
00080 $tagsRows[] = array_filter( array( 'ct_tag' => $tag, 'ct_rc_id' => $rc_id, 'ct_log_id' => $log_id, 'ct_rev_id' => $rev_id, 'ct_params' => $params ) );
00081 }
00082
00083 $dbw->insert( 'change_tag', $tagsRows, __METHOD__, array('IGNORE') );
00084
00085 return true;
00086 }
00087
00093 static function modifyDisplayQuery( &$tables, &$fields, &$conds,
00094 &$join_conds, &$options, $filter_tag = false ) {
00095 global $wgRequest, $wgUseTagFilter;
00096
00097 if ($filter_tag === false) {
00098 $filter_tag = $wgRequest->getVal( 'tagfilter' );
00099 }
00100
00101
00102 $join_field = '';
00103 if ( in_array('recentchanges', $tables) ) {
00104 $join_cond = 'rc_id';
00105 } elseif( in_array('logging', $tables) ) {
00106 $join_cond = 'log_id';
00107 } elseif ( in_array('revision', $tables) ) {
00108 $join_cond = 'rev_id';
00109 } else {
00110 throw new MWException( "Unable to determine appropriate JOIN condition for tagging." );
00111 }
00112
00113
00114 $tables[] = 'tag_summary';
00115 $join_conds['tag_summary'] = array( 'LEFT JOIN', "ts_$join_cond=$join_cond" );
00116 $fields[] = 'ts_tags';
00117
00118 if ($wgUseTagFilter && $filter_tag) {
00119
00120
00121
00122
00123 $options['USE INDEX'] = array( 'change_tag' => 'change_tag_tag_id' );
00124 unset( $options['FORCE INDEX'] );
00125 $tables[] = 'change_tag';
00126 $join_conds['change_tag'] = array( 'INNER JOIN', "ct_$join_cond=$join_cond" );
00127 $conds['ct_tag'] = $filter_tag;
00128 }
00129 }
00130
00135 static function buildTagFilterSelector( $selected='', $fullForm = false ) {
00136 global $wgUseTagFilter;
00137
00138 if ( !$wgUseTagFilter || !count( self::listDefinedTags() ) )
00139 return $fullForm ? '' : array();
00140
00141 global $wgTitle;
00142
00143 $data = array( wfMsgExt( 'tag-filter', 'parseinline' ), Xml::input( 'tagfilter', 20, $selected ) );
00144
00145 if (!$fullForm) {
00146 return $data;
00147 }
00148
00149 $html = implode( ' ', $data );
00150 $html .= "\n" . Xml::element( 'input', array( 'type' => 'submit', 'value' => wfMsg( 'tag-filter-submit' ) ) );
00151 $html .= "\n" . Xml::hidden( 'title', $wgTitle-> getPrefixedText() );
00152 $html = Xml::tags( 'form', array( 'action' => $wgTitle->getLocalURL(), 'method' => 'get' ), $html );
00153
00154 return $html;
00155 }
00156
00158 static function listDefinedTags() {
00159
00160 global $wgMemc;
00161 $key = wfMemcKey( 'valid-tags' );
00162
00163 if ($tags = $wgMemc->get( $key ))
00164 return $tags;
00165
00166 $emptyTags = array();
00167
00168
00169 $dbr = wfGetDB( DB_SLAVE );
00170 $res = $dbr->select( 'valid_tag', 'vt_tag', array(), __METHOD__ );
00171 while( $row = $res->fetchObject() ) {
00172 $emptyTags[] = $row->vt_tag;
00173 }
00174
00175 wfRunHooks( 'ListDefinedTags', array(&$emptyTags) );
00176
00177 $emptyTags = array_filter( array_unique( $emptyTags ) );
00178
00179
00180 $wgMemc->set( $key, $emptyTags, 300 );
00181 return $emptyTags;
00182 }
00183 }