http://www.mediawiki.org/wiki/Special:Code/MediaWiki/54291

Revision: 54291
Author:   btongminh
Date:     2009-08-03 17:48:01 +0000 (Mon, 03 Aug 2009)

Log Message:
-----------
(bug 19004) Added support for tags to the API. Patch by Matthew Britton.

Modified Paths:
--------------
    trunk/phase3/CREDITS
    trunk/phase3/RELEASE-NOTES
    trunk/phase3/includes/AutoLoader.php
    trunk/phase3/includes/ChangeTags.php
    trunk/phase3/includes/api/ApiQuery.php
    trunk/phase3/includes/api/ApiQueryLogEvents.php
    trunk/phase3/includes/api/ApiQueryRecentChanges.php
    trunk/phase3/includes/api/ApiQueryRevisions.php
    trunk/phase3/includes/api/ApiQueryUserContributions.php
    trunk/phase3/includes/specials/SpecialTags.php

Added Paths:
-----------
    trunk/phase3/includes/api/ApiQueryTags.php

Modified: trunk/phase3/CREDITS
===================================================================
--- trunk/phase3/CREDITS        2009-08-03 17:04:17 UTC (rev 54290)
+++ trunk/phase3/CREDITS        2009-08-03 17:48:01 UTC (rev 54291)
@@ -83,6 +83,7 @@
 * Marcin Cieślak
 * Marcus Buck
 * Marooned
+* Matthew Britton
 * Max Semenik
 * Michael De La Rue
 * Michael Walsh

Modified: trunk/phase3/RELEASE-NOTES
===================================================================
--- trunk/phase3/RELEASE-NOTES  2009-08-03 17:04:17 UTC (rev 54290)
+++ trunk/phase3/RELEASE-NOTES  2009-08-03 17:48:01 UTC (rev 54291)
@@ -426,6 +426,7 @@
 * (bug 19907) $wgCrossSiteAJAXdomains added to allow specified (or all)
   external domains to access api.php via AJAX, if the browser supports the 
   Access-Control-Allow-Origin HTTP header
+* (bug 19004) Added support for tags to the API.
 
 === Languages updated in 1.16 ===
 

Modified: trunk/phase3/includes/AutoLoader.php
===================================================================
--- trunk/phase3/includes/AutoLoader.php        2009-08-03 17:04:17 UTC (rev 
54290)
+++ trunk/phase3/includes/AutoLoader.php        2009-08-03 17:48:01 UTC (rev 
54291)
@@ -304,6 +304,7 @@
        'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
        'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php',
        'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
+       'ApiQueryTags' => 'includes/api/ApiQueryTags.php',
        'ApiQueryUserInfo' => 'includes/api/ApiQueryUserInfo.php',
        'ApiQueryUsers' => 'includes/api/ApiQueryUsers.php',
        'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',

Modified: trunk/phase3/includes/ChangeTags.php
===================================================================
--- trunk/phase3/includes/ChangeTags.php        2009-08-03 17:04:17 UTC (rev 
54290)
+++ trunk/phase3/includes/ChangeTags.php        2009-08-03 17:48:01 UTC (rev 
54291)
@@ -185,4 +185,35 @@
                $wgMemc->set( $key, $emptyTags, 300 );
                return $emptyTags;
        }
+       
+       /** Returns associative array of tag names and hitcounts */
+       static function getHitCounts() {
+       
+               global $wgMemc;
+               $key = wfMemcKey( 'hitcounts' );
+               
+               if ($hitcounts = $wgMemc->get( $key ))
+                       return $hitcounts;
+               
+               $dbr = wfGetDB( DB_SLAVE );
+               $hitcounts = array();
+               
+               // Fetch defined tags
+               $res = $dbr->select( 'valid_tag', 'vt_tag', array(), __METHOD__ 
);
+               while( $row = $res->fetchObject() ) {
+                       $hitcounts[$row->vt_tag] = 0;
+               }
+               
+               // Fetch hit counts
+               $res = $dbr->select( 'change_tag', array('ct_tag', 'count(*) AS 
hitcount'),     array(), __METHOD__, array('GROUP BY' => 'ct_tag', 'ORDER BY' 
=> 'hitcount DESC') );
+               
+               while( $row = $res->fetchObject() ) {
+                       $hitcounts[$row->ct_tag] = $row->hitcount;
+               }
+               
+               // Short-term caching
+               $wgMemc->set( $key, $hitcounts, 300 );
+               return $hitcounts;
+       }
+       
 }

Modified: trunk/phase3/includes/api/ApiQuery.php
===================================================================
--- trunk/phase3/includes/api/ApiQuery.php      2009-08-03 17:04:17 UTC (rev 
54290)
+++ trunk/phase3/includes/api/ApiQuery.php      2009-08-03 17:48:01 UTC (rev 
54291)
@@ -74,6 +74,7 @@
                'logevents' => 'ApiQueryLogEvents',
                'recentchanges' => 'ApiQueryRecentChanges',
                'search' => 'ApiQuerySearch',
+               'tags' => 'ApiQueryTags',
                'usercontribs' => 'ApiQueryContributions',
                'watchlist' => 'ApiQueryWatchlist',
                'watchlistraw' => 'ApiQueryWatchlistRaw',

Modified: trunk/phase3/includes/api/ApiQueryLogEvents.php
===================================================================
--- trunk/phase3/includes/api/ApiQueryLogEvents.php     2009-08-03 17:04:17 UTC 
(rev 54290)
+++ trunk/phase3/includes/api/ApiQueryLogEvents.php     2009-08-03 17:48:01 UTC 
(rev 54291)
@@ -51,6 +51,7 @@
                $this->fld_timestamp = in_array('timestamp', $prop);
                $this->fld_comment = in_array('comment', $prop);
                $this->fld_details = in_array('details', $prop);
+               $this->fld_tags = in_array('tags', $prop);
 
                list($tbl_logging, $tbl_page, $tbl_user) = 
$db->tableNamesN('logging', 'page', 'user');
 
@@ -85,6 +86,16 @@
                $this->addFieldsIf('log_comment', $this->fld_comment);
                $this->addFieldsIf('log_params', $this->fld_details);
                
+               if($this->fld_tags || !is_null($params['tag'])) {
+                       $this->addTables('tag_summary');
+                       $this->addJoinConds(array('tag_summary' => array('LEFT 
JOIN', 'log_id=ts_log_id')));
+                       $this->addFields('ts_tags');
+               }
+               
+               if( !is_null($params['tag']) ) {
+                       $this->addWhereFld('ts_tags', $params['tag']);
+               }
+               
                if( !is_null($params['type']) ) {
                        $this->addWhereFld('log_type', $params['type']);
                        $index = 'type_time';
@@ -247,6 +258,10 @@
                        }
                }
 
+               if ($this->fld_tags && isset($row->ts_tags)) {
+                       $vals['tags'] = $row->ts_tags;
+               }
+               
                return $vals;
        }
 
@@ -265,6 +280,7 @@
                                        'timestamp',
                                        'comment',
                                        'details',
+                                       'tags'
                                )
                        ),
                        'type' => array (
@@ -285,6 +301,7 @@
                        ),
                        'user' => null,
                        'title' => null,
+                       'tag' => null,
                        'limit' => array (
                                ApiBase :: PARAM_DFLT => 10,
                                ApiBase :: PARAM_TYPE => 'limit',
@@ -304,6 +321,7 @@
                        'dir' => 'In which direction to enumerate.',
                        'user' => 'Filter entries to those made by the given 
user.',
                        'title' => 'Filter entries to those related to a page.',
+                       'tag' => 'Only list entries with this tag',
                        'limit' => 'How many total event entries to return.'
                );
        }

Modified: trunk/phase3/includes/api/ApiQueryRecentChanges.php
===================================================================
--- trunk/phase3/includes/api/ApiQueryRecentChanges.php 2009-08-03 17:04:17 UTC 
(rev 54290)
+++ trunk/phase3/includes/api/ApiQueryRecentChanges.php 2009-08-03 17:48:01 UTC 
(rev 54291)
@@ -42,7 +42,7 @@
 
        private $fld_comment = false, $fld_user = false, $fld_flags = false,
                        $fld_timestamp = false, $fld_title = false, $fld_ids = 
false,
-                       $fld_sizes = false;
+                       $fld_sizes = false, $fld_tags = false;
        /**
         * Get an array mapping token names to their handler functions.
         * The prototype for a token function is func($pageid, $title, $rc)
@@ -174,6 +174,7 @@
                        $this->fld_redirect = isset($prop['redirect']);
                        $this->fld_patrolled = isset($prop['patrolled']);
                        $this->fld_loginfo = isset($prop['loginfo']);
+                       $this->fld_tags = isset($prop['tags']);
 
                        global $wgUser;
                        if($this->fld_patrolled && !$wgUser->useRCPatrol() && 
!$wgUser->useNPPatrol())
@@ -203,6 +204,17 @@
                                $this->addFields('page_is_redirect');
                        }
                }
+               
+               if($this->fld_tags || !is_null($params['tag'])) {
+                       $this->addTables('tag_summary');
+                       $this->addJoinConds(array('tag_summary' => array('LEFT 
JOIN', array('rc_id=ts_rc_id'))));
+                       $this->addFields('ts_tags');
+               }
+                       
+               if(!is_null($params['tag'])) {
+                       $this->addWhereFld('ts_tags' , $params['tag']);
+               }
+               
                $this->token = $params['token'];
                $this->addOption('LIMIT', $params['limit'] +1);
                $this->addOption('USE INDEX', array('recentchanges' => $index));
@@ -335,6 +347,10 @@
                                $row->rc_log_type, $row->rc_timestamp);
                }
                
+               if ($this->fld_tags && isset($row->ts_tags)) {
+                       $vals['tags'] = $row->ts_tags;
+               }
+               
                if(!is_null($this->token))
                {
                        $tokenFunctions = $this->getTokenFunctions();
@@ -408,6 +424,7 @@
                                        'redirect',
                                        'patrolled',
                                        'loginfo',
+                                       'tags',
                                )
                        ),
                        'token' => array(
@@ -443,7 +460,8 @@
                                        'new',
                                        'log'
                                )
-                       )
+                       ),
+                       'tag' => null,
                );
        }
 
@@ -462,6 +480,7 @@
                                'For example, to see only minor edits done by 
logged-in users, set show=minor|!anon'
                        ),
                        'type' => 'Which types of changes to show.',
+                       'tag' => 'Only list changes with this tag',
                        'limit' => 'How many total changes to return.'
                );
        }

Modified: trunk/phase3/includes/api/ApiQueryRevisions.php
===================================================================
--- trunk/phase3/includes/api/ApiQueryRevisions.php     2009-08-03 17:04:17 UTC 
(rev 54290)
+++ trunk/phase3/includes/api/ApiQueryRevisions.php     2009-08-03 17:48:01 UTC 
(rev 54291)
@@ -42,7 +42,7 @@
        }
 
        private $fld_ids = false, $fld_flags = false, $fld_timestamp = false, 
$fld_size = false,
-                       $fld_comment = false, $fld_user = false, $fld_content = 
false;
+                       $fld_comment = false, $fld_user = false, $fld_content = 
false, $fld_tags = false;
 
        protected function getTokenFunctions() {
                // tokenname => function
@@ -121,9 +121,8 @@
                }
 
                $db = $this->getDB();
-               $this->addTables('revision');
+               $this->addTables(array('page', 'revision'));
                $this->addFields(Revision::selectFields());
-               $this->addTables('page');
                $this->addWhere('page_id = rev_page');
 
                $prop = array_flip($params['prop']);
@@ -135,6 +134,7 @@
                $this->fld_timestamp = isset ($prop['timestamp']);
                $this->fld_comment = isset ($prop['comment']);
                $this->fld_size = isset ($prop['size']);
+               $this->fld_tags = isset ($prop['tags']);
                $this->fld_user = isset ($prop['user']);
                $this->token = $params['token'];
                $this->diffto = $params['diffto'];
@@ -143,6 +143,16 @@
                        $this->addFields( Revision::selectPageFields() );
                }
 
+               if ($this->fld_tags || !is_null($params['tag'])) {
+                       $this->addTables('tag_summary');
+                       $this->addJoinConds(array('tag_summary' => array('LEFT 
JOIN', array('rev_id=ts_rev_id'))));
+                       $this->addFields('ts_tags');
+               }
+               
+               if( !is_null($params['tag']) ) {
+                       $this->addWhereFld('ts_tags', $params['tag']);
+               }
+               
                if (isset ($prop['content'])) {
 
                        // For each page we will request, the user must have 
read rights for that page
@@ -293,9 +303,9 @@
                                $this->setContinueEnumParameter('startid', 
intval($row->rev_id));
                                break;
                        }
-                       $revision = new Revision( $row );
+                       
                        //
-                       $fit = $this->addPageSubItem($revision->getPage(), 
$this->extractRowInfo($revision), 'rev');
+                       $fit = $this->addPageSubItem($row->rev_page, 
$this->extractRowInfo($row), 'rev');
                        if(!$fit)
                        {
                                if($enumRevMode)
@@ -311,7 +321,8 @@
                $db->freeResult($res);
        }
 
-       private function extractRowInfo( $revision ) {
+       private function extractRowInfo( $row ) {
+               $revision = new Revision( $row );
                $title = $revision->getTitle();
                $vals = array ();
 
@@ -353,6 +364,9 @@
                        }
                }       
 
+               if ($this->fld_tags && $row->ts_tags)
+                       $vals['tags'] = $row->ts_tags;
+               
                if(!is_null($this->token))
                {
                        $tokenFunctions = $this->getTokenFunctions();
@@ -427,6 +441,7 @@
                                        'size',
                                        'comment',
                                        'content',
+                                       'tags'
                                )
                        ),
                        'limit' => array (
@@ -460,6 +475,7 @@
                        'excludeuser' => array(
                                ApiBase :: PARAM_TYPE => 'user'
                        ),
+                       'tag' => null,
                        'expandtemplates' => false,
                        'generatexml' => false,
                        'section' => null,
@@ -483,6 +499,7 @@
                        'dir' => 'direction of enumeration - towards "newer" or 
"older" revisions (enum)',
                        'user' => 'only include revisions made by user',
                        'excludeuser' => 'exclude revisions made by user',
+                       'tag' => 'only list revisions with this tag',
                        'expandtemplates' => 'expand templates in revision 
content',
                        'generatexml' => 'generate XML parse tree for revision 
content',
                        'section' => 'only retrieve the content of this 
section',

Added: trunk/phase3/includes/api/ApiQueryTags.php
===================================================================
--- trunk/phase3/includes/api/ApiQueryTags.php                          (rev 0)
+++ trunk/phase3/includes/api/ApiQueryTags.php  2009-08-03 17:48:01 UTC (rev 
54291)
@@ -0,0 +1,167 @@
+<?php
+
+/*
+ * Created on Jul 9, 2009
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2009 Matthew Britton <firstname>.<lastname>@btinternet.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+       // Eclipse helper - will be ignored in production
+       require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to enumerate change tags.
+ *
+ * @ingroup API
+ */
+class ApiQueryTags extends ApiQueryBase {
+       
+       private $limit, $result;
+       private $fld_displayname = false, $fld_description = false,
+                       $fld_hitcount = false;
+       
+       public function __construct($query, $moduleName) {
+               parent :: __construct($query, $moduleName, 'tg');
+       }
+
+       public function execute() {
+               $params = $this->extractRequestParams();
+               
+               $prop = array_flip($params['prop']);
+               
+               $this->fld_displayname = isset($prop['displayname']);
+               $this->fld_description = isset($prop['description']);
+               $this->fld_hitcount = isset($prop['hitcount']);
+               
+               $this->limit = $params['limit'];
+               $this->result = $this->getResult();
+               
+               $pageSet = $this->getPageSet();
+               $titles = $pageSet->getTitles();
+               $data = array();
+               $ok = true;
+               
+               if($this->fld_hitcount) {
+                       foreach( ChangeTags::getHitCounts() as $tag => $count ) 
{
+                               if(!$ok) break;
+                               $ok = $this->doTag( $tag, $count );
+                       }
+               } else {
+                       foreach( ChangeTags::listDefinedTags() as $tag ) {
+                               if(!$ok) break;
+                               $ok = $this->doTag( $tag, 0 );
+                       }
+               }
+               
+               $this->result->setIndexedTagName_internal(array('query', 
$this->getModuleName()), 'tag');
+       }
+       
+       private function doTag( $tagName, $hitcount ) {
+               static $count = 0;
+               static $doneTags = array();
+               
+               if ( in_array( $tagName, $doneTags ) ) {
+                       return true;
+               }
+               
+               if(++$count > $this->limit)
+               {
+                       $this->setContinueEnumParameter('continue', $tagName);
+                       return false;
+               }
+               
+               $tag = array();
+               $tag['name'] = $tagName;
+               
+               if($this->fld_displayname)
+                       $tag['displayname'] = ChangeTags::tagDescription( 
$tagName );
+               
+               if($this->fld_description)
+               {
+                       $msg = wfMsg( "tag-$tagName-description" );
+                       $msg = wfEmptyMsg( "tag-$tagName-description", $msg ) ? 
'' : $msg;
+                       $tag['description'] = $msg;
+               }
+                       
+               if($this->fld_hitcount)
+                       $tag['hitcount'] = $hitcount;
+               
+               $doneTags[] = $tagName;
+               
+               $fit = $this->result->addValue(array('query', 
$this->getModuleName()), null, $tag);
+               if(!$fit)
+               {
+                       $this->setContinueEnumParameter('continue', $tagName);
+                       return false;
+               }
+                       
+               return true;
+       }
+       
+       public function getAllowedParams() {
+               return array (
+                       'continue' => array(
+                       ),
+                       'end' => array(
+                       ),
+                       'limit' => array(
+                               ApiBase :: PARAM_DFLT => 10,
+                               ApiBase :: PARAM_TYPE => 'limit',
+                               ApiBase :: PARAM_MIN => 1,
+                               ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+                               ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+                       ),
+                       'prop' => array(
+                               ApiBase :: PARAM_DFLT => 'name',
+                               ApiBase :: PARAM_TYPE => array(
+                                               'name',
+                                               'displayname',
+                                               'description',
+                                               'hitcount'
+                                       ),
+                               ApiBase :: PARAM_ISMULTI => true
+                       )
+               );
+       }
+
+       public function getParamDescription() {
+               return array (
+                       'continue' => 'When more results are available, use 
this to continue',
+                       'limit' => 'The maximum number of tags to list',
+                       'prop' => 'Which properties to get',
+               );
+       }
+
+       public function getDescription() {
+               return 'List change tags.';
+       }
+
+       protected function getExamples() {
+               return array (
+                       
'api.php?action=query&list=tags&tgprop=displayname|description|hitcount'
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id: ApiQueryTags.php';
+       }
+}


Property changes on: trunk/phase3/includes/api/ApiQueryTags.php
___________________________________________________________________
Added: svn:keywords
   + id
Added: svn:eol-style
   + native

Modified: trunk/phase3/includes/api/ApiQueryUserContributions.php
===================================================================
--- trunk/phase3/includes/api/ApiQueryUserContributions.php     2009-08-03 
17:04:17 UTC (rev 54290)
+++ trunk/phase3/includes/api/ApiQueryUserContributions.php     2009-08-03 
17:48:01 UTC (rev 54291)
@@ -42,7 +42,7 @@
        private $params, $username;
        private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
                        $fld_comment = false, $fld_flags = false,
-                       $fld_patrolled = false;
+                       $fld_patrolled = false, $fld_tags = false;
 
        public function execute() {
 
@@ -57,6 +57,7 @@
                $this->fld_flags = isset($prop['flags']);
                $this->fld_timestamp = isset($prop['timestamp']);
                $this->fld_patrolled = isset($prop['patrolled']);
+               $this->fld_tags = isset($prop['tags']);
 
                // TODO: if the query is going only against the revision table, 
should this be done?
                $this->selectNamedDB('contributions', DB_SLAVE, 
'contributions');
@@ -141,7 +142,7 @@
        private function prepareQuery() {
                // We're after the revision table, and the corresponding page
                // row for anything we retrieve. We may also need the
-               // recentchanges row.
+               // recentchanges row and/or tag summary row.
                global $wgUser;
                $tables = array('page', 'revision'); // Order may change
                $this->addWhere('page_id=rev_page');
@@ -245,6 +246,16 @@
                $this->addFieldsIf('rev_minor_edit', $this->fld_flags);
                $this->addFieldsIf('rev_parent_id', $this->fld_flags);
                $this->addFieldsIf('rc_patrolled', $this->fld_patrolled);
+               
+               if($this->fld_tags || !is_null($this->params['tag'])) {
+                       $this->addTables('tag_summary');
+                       $this->addJoinConds(array('tag_summary' => array('LEFT 
JOIN', array('rev_id=ts_rev_id'))));
+                       $this->addFields('ts_tags');
+               }
+               
+               if( !is_null($this->params['tag']) ) {
+                       $this->addWhereFld('ts_tags', $this->params['tag']);
+               }
        }
 
        /**
@@ -292,6 +303,9 @@
                if ($this->fld_size && !is_null($row->rev_len))
                        $vals['size'] = intval($row->rev_len);
 
+               if ($this->fld_tags && $row->ts_tags)
+                       $vals['tags'] = $row->ts_tags;
+                       
                return $vals;
        }
        
@@ -343,6 +357,7 @@
                                        'size',
                                        'flags',
                                        'patrolled',
+                                       'tags',
                                )
                        ),
                        'show' => array (
@@ -354,6 +369,7 @@
                                        '!patrolled',
                                )
                        ),
+                       'tag' => null,
                );
        }
 
@@ -370,6 +386,7 @@
                        'prop' => 'Include additional pieces of information',
                        'show' => array('Show only items that meet this 
criteria, e.g. non minor edits only: show=!minor',
                                        'NOTE: if show=patrolled or 
show=!patrolled is set, revisions older than $wgRCMaxAge won\'t be shown',),
+                       'tag' => 'Only list contributions with this tag',
                );
        }
 

Modified: trunk/phase3/includes/specials/SpecialTags.php
===================================================================
--- trunk/phase3/includes/specials/SpecialTags.php      2009-08-03 17:04:17 UTC 
(rev 54290)
+++ trunk/phase3/includes/specials/SpecialTags.php      2009-08-03 17:48:01 UTC 
(rev 54291)
@@ -25,17 +25,11 @@
                                Xml::tags( 'th', null, wfMsgExt( 
'tags-description-header', 'parseinline' ) ) .
                                Xml::tags( 'th', null, wfMsgExt( 
'tags-hitcount-header', 'parseinline' ) )
                        );
-               $dbr = wfGetDB( DB_SLAVE );
-               $res = $dbr->select( 'change_tag', array( 'ct_tag', 'count(*) 
as hitcount' ), array(), __METHOD__, array( 'GROUP BY' => 'ct_tag', 'ORDER BY' 
=> 'hitcount DESC' ) );
 
-               while ( $row = $res->fetchObject() ) {
-                       $html .= $this->doTagRow( $row->ct_tag, $row->hitcount 
);
+               foreach( ChangeTags::getHitCounts() as $tag => $hitcount ) {
+                       $html .= $this->doTagRow( $tag, $hitcount );
                }
 
-               foreach( ChangeTags::listDefinedTags() as $tag ) {
-                       $html .= $this->doTagRow( $tag, 0 );
-               }
-
                $wgOut->addHTML( Xml::tags( 'table', array( 'class' => 
'wikitable mw-tags-table' ), $html ) );
        }
 



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to