Last modified: 2013-09-04 11:47:14 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T32925, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 30925 - Enhanced Recent Changes hooks
Enhanced Recent Changes hooks
Status: RESOLVED WORKSFORME
Product: MediaWiki
Classification: Unclassified
Recent changes (Other open bugs)
1.17.x
All All
: Unprioritized enhancement (vote)
: ---
Assigned To: Nobody - You can work on this!
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-09-16 02:37 UTC by Olivier Finlay Beaton
Modified: 2013-09-04 11:47 UTC (History)
0 users

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Olivier Finlay Beaton 2011-09-16 02:37:09 UTC
Finlay (irc) / quadir (mediawiki) here.

There seems to be a severe lack of hooks in the EnhancedChangesList class.

Talking about it on irc, hashar made a quick patch
http://www.mediawiki.org/wiki/Special:Code/MediaWiki/97203
however it has problems as discussed there (output at the EnhancedChangesList::recentChangesLine and endRecentChangesList level is really inconvenient).

I would love for some kind of generic hook in ChangesList that allowed me to modify each change (row) and give me the query data/obj for that row.  Looking at the code, that's unlikely to come from ChangeList. Once you look at includes/specials/SpecialRecentchanges.php, SpecialRecentchangeslinked.php and SpecialWatchlist.php things start looking a bit better, since it assumes there is a 'recentChangesLine ' for every ChangesList class (why isn't this enforced by ChangesList???).  This would be great as you could then support any ChangesList class, however since ECL makes such a mess of these functions it wouldn't provide the functionality for the one that counts.

I have two ideas about how we could go about this. Both involve just hooking EnhancedChangesList, and relying on the old hook for OldChangesList. Any 3rd party ChangesList would have to provide 3rd party hooks for cross-support of any extensions.

Method 1: oh neat! a one-liner.

Simply make a hook in EnhancedChangesList::recentChangesBlock between these two:
  foreach( $this->rc_cache as $block ) {
    if( count( $block ) < 2 ) {
where you pass in $block.  Each block is a collection of change objects which contain all the information recentChangesBlockGroup() and recentChangesBlockLine() will eventually use to build the output. If you change the fields here, you change the output later. While not as powerful a replacement as the hooks in Method 2, it is MUCH more elegant, especially for things like changing how Usernames are displayed (my use case).

It should be noted it is already possible to do this, you hook FetchChangesList, then copy+paste the code from ChangesList.php to make sure you only replace the list when the user wants the enhanced changes. Extend the EnhancedChangesList and override the recentChangesBlock() function to cycle through $this->rc_cache and make the changes you want before passing to parent::. If you go this route, Method 1 is not going to break your code down the road. 

However with the workaround your code may break if the function name  EnhancedChangesList::recentChangesBlock change on you, or it's parameters change. It's definitely not as slick as a hook (even if a dumb one parameter wise).

Method 2: (ugly)

To get the full change line you have to look at EnhancedChangesList::recentChangesBlockGroup $r variable, however you quickly realize that it will contain each "main summary line" (with usernames listed with x2 x3 x4 edits), and then a series of actual edits (which get hidden by default but can be expanded).

So if we were to create hooks, I would suggest creating a hook for each. 

collect the summary line from $r (change it to something else, then add it $r after hook) 
746~:  $r = Html::openElement( 'table', array( 'class' => $classes ) ) .
                        Html::openElement( 'tr' );
to 
911~:   $r .= "</td></tr></table>\n";
and ensure the hook receives $block, as the user will likely want to rewrite it based on query data, but since this is a summary row of multiple users, you need the data for all the users. passing in only the user rcObj listed would be cool, just ensure the whole objects are passed in.

then a hook for each change line from $r (change it to something else, then add it $r after hook) before
924~:   #$r .= '<tr><td valign="top">'.$this->spacerArrow();
to
984~:   $r .= "</td></tr>\n";

where you ensure to pass in $rcObj.

then you need a 3rd hook (unless you can reuse the line one above) for recentChangesBlockLine() which is used when there isn't more than one change on a page on a day.

This will allow extension writters to actually do something with the data.
Comment 1 Olivier Finlay Beaton 2011-09-19 13:50:58 UTC
The consensus seems to be that subclassing off EnhancedChangesList and then swapping it in using the existing hook (FetchChangesList) should be enough to provide most hook functionality. OldChanges then is there for compatibility reasons (I assume).

Closing request as WORKSFORME.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links