Extension talk:UserMerge/LQT Archive 1

Instructions
For $wgUserMergeUnmergeable comment, don't you mean "Optional, prevents user_id 1 from being merged"?

Svanslyck 21:00, 9 February 2008 (UTC)
 * Well... Optional as in you don't have to set it for the extension to work. By default, user_id 1 can't be merged because $wgUserMergeUnmergable is initalized to array(1).  It's optional meaning you can change it's behavior if you want, but don't need to.  This was added as Simetrical pointed out that user_id 1 isn't always the admin/root user as MW has no concept of a 'root' user_id.  Tim Laqua talk 17:43, 10 February 2008 (UTC)

You cannot delete or merge from yourself!
What happened? I'm logged in as sysop and trying to merge two other users, deleting one of them. Svanslyck 21:05, 9 February 2008 (UTC)
 * Fixed in v1.4.2, r30803 Tim Laqua talk 17:39, 10 February 2008 (UTC)

No Logging?
Shouldn't there be log entries for merge&delete? --NoLuck 22:46, 13 November 2007 (UTC)
 * Dunno, should there be? I never really planned for it to be used frequently enough - but considering that one should be able to rebuild an entire system using Logs - if there's a User creation log, there should most definately be a user deletion log.  I'll take a look at how the User Creation logs are being done.
 * well, there doesn't seem to be a user creation log - maybe no real need for that as this is a pure constructive act done by the concerned person himself ... however, after a user merge/deletion it could be good to know when that happened and who enacted that function... Extension:Renameuser is using a "user rename" log for its own purposes - so I guess you're not restricted on the standard log entries. Thx for consideration btw :) --NoLuck 21:02, 19 November 2007 (UTC)
 * Yeah, similar f/ the User Creation log - there is one, but it's part of an extension. Still, I'll look in to it.  ;-)  Maybe even implement if it doesn't give me a headache.
 * Ok, v1.2 (r27730) now has a User Merge log. ;-)
 * cool, thx! :-) --NoLuck 16:23, 24 November 2007 (UTC)

User Pages
Would like to see this also deleting the User Page and User Discussion page for the deleted user.

Apart from that, works a treat - thanks for providing this.

BrillyuntWebby 18:20, 16 November 2007 (UTC)
 * What should it do in the case of a Merge? Append to the new user?  Or just flat out, always delete the old user's page?  Or maybe a checkbox?  But I agree, it should do *something* with the old user's page... but if you don't delete it... and you don't wanna append it... where should it go?
 * I'd go for having them deleted anyway with the option (checkbox) to append the content to the new users User and Discussion page. Wolverine 15:16, 9 January 2008 (UTC)

Statistics
When deleting the old user the statistics counter (ss_users in table site_stats) remains unchanged. So Special:Statistics shows more registered users than really exist/are listed by Special:Listusers. I think it should be possible to decrement the value in the database when deleting an user. I fixed this manually in our wiki and so far it didn't seem to have side-effects (i.e. when a new user registers). Wolverine 15:20, 9 January 2008 (UTC)
 * good point - i'll decrement that in the next release. Tim Laqua talk 16:17, 10 January 2008 (UTC)
 * great,thx! :-) The extension was already quite useful against "I forgot my account, ah ... I just create another one" users. ;-) With that, and the above optional merge of User and Discussion page it becomes complete (for me). So it's just one action and no further manual work neccessary. Nice! :-) Wolverine 08:57, 11 January 2008 (UTC)
 * Recalucation of ss_users and ss_admins added in 1.3.2, r30181. Tim Laqua talk 03:55, 27 January 2008 (UTC)

Database
When i used the stable version of this extension on my 1.11.0 fresh wiki, i noticed it leaves residues of the removed users in the database, in places like searchindex and recentchanges (and many others). Shouldn't this be fixed?
 * I'll take a look - The true intent of the extension is to allow removal of users while maintaining the referential ingegrity of the database. Where exactly did you notice fragments?  Tim Laqua talk 12:20, 18 January 2008 (UTC)

MediaWiki 1.9.0
I'm running MediaWiki 1.9.0 and I'd like to install the User Merge extension. Is it definitely incompatible with 1.9 or has it simply never been tested? If I tried it, could it mess up my database?--Lorikeet 07:05, 24 January 2008 (UTC)
 * It was originally developed on 1.9.3 - however the curennt Special Page implementation may not be backwards compatible w/ the 1.9.3 core. If you can install it and view the special page, you shouldn't encounter any problems - but as usual, use at your own risk - I haven't tested the current revison on 1.9.3.  Tim Laqua talk 03:22, 27 January 2008 (UTC)

MediaWiki 1.10.2
On the Extension page it says 1.10+ however on 1.10.2 is spits out "Call to undefined function wfLoadExtensionMessages". Is this function 1.11+ only? If no, provide a solution, if yes correct the extension page to say 1.11+
 * Changed, thanks. Tim Laqua talk 23:51, 22 February 2008 (UTC)

Praise
Oh, thank you for this extention! I'm new to MediaWiki and I made some user accounts that I really didn't want (and made page edits with them, thus permeating the database!) ... and I was pulling my hair out trying to clean up behind myself. It's important that my user list be correct. This ext. did the trick! THANK YOU! -- toff@paleravens.com

"Undefined variable" error
I'm trying to get this extension working with MW 1.11.0. When I open Special:UserMerge page I'm getting this errors on the top of page:

Notice: Undefined variable: olduser_text in [strip]/extensions/UserMerge/UserMerge_body.php on line 89 Notice: Undefined variable: newuser_text in [strip]/extensions/UserMerge/UserMerge_body.php on line 93 Notice: Undefined variable: deleteUserCheck in [strip]/extensions/UserMerge/UserMerge_body.php on line 97 Notice: Undefined variable: validNewUser in [strip]/extensions/UserMerge/UserMerge_body.php on line 107


 * Fixed in r30180. Tim Laqua talk 03:32, 27 January 2008 (UTC)

Select the user instead of writing it?
Hi, Great work with this extension. I just wonder how can it be done so that when you use this extension you select the old username from a list instead of writting it in the box? And for using multiple selection of old users? The user list i'll manage won't exceed the 50 or 60 users, that's why i ask. Also... can you delete your own username being an admin using this extension? or has to be someone else the one who does it? Thanks -Juanan 10:53, 6 February 2008 (UTC)
 * Oh yes, you can delete yourself - however, I believe the next time you try to view a MW page - your session should expire as the user no longer exists. As far as selecting multiple users - It's certainly possible to make a multiple user selection dialog for the "old username" and make it support multiple entries - though I could almost see that being a separate Special page rather than an addition to the current one, indended for mass user deletion.  Maybe a feature for the next version - do you forsee needing to delete large numbers of users?  I noticed you mentioned integration of a CAS - what are you using and what are you trying to get User Merge and Delete to do?  I personally use LDAP Authentication against AD for a few Wikis at a university and I use the extension to clean up auto-created accounts for users that don't have read or write access (the simple act of logging in for most CAS implementations causes a MediaWiki account to be created).  Tim Laqua talk 14:46, 6 February 2008 (UTC)


 * Well it shouldn't let a user to delete itself, should it? Or at least it should issue a warning so that you accidentally don't delete yourself... also do you think it would be hard to implement a button that loads a list of users from the database and lets you select he ones that will be losing their contributuions (and probably ending deleted) and then merge them against one single user? About CAS, yes, I use it to autocreate/login users according to certain user type privileges and they won't be able to login when those privileges don't exist. (For example they don't study the subject this wiki is for). -Juanan 19:59, 6 February 2008 (UTC)


 * Not deleting yourself should be simple enough to check for (and it's debatable - I don't see any real harm in stopping it from deleting you). As far as the selection list - it wouldn't be hard so much as tedious - modal dialogs aren't very standardized between browsers (which is why scripts like ThickBox and Submodal exist) - I'm also not a fan of postbacks for trivial information.  I'll put some thought in to it - my main concern is that dropdowns and multiple selection options are not realistic in large wikis - really once the userlist gets larger than 50 users, the lists are out of control.  Tim Laqua talk 20:56, 6 February 2008 (UTC)
 * Blocking of self deletion implemented in v1.4, r30677. Tim Laqua talk 18:40, 7 February 2008 (UTC)

Minor problem with international languages pack
I followed all the steps installing this extension. However I found that when changed the user's language at prefercences, the Name for the extension that appears on The special restricted pages changes but not the buttons and messages of this extension, even though it works, it doesn't seem to show the correct language. I downloaded the last version up to date. -Juanan 11:40, 7 February 2008 (UTC)
 * Fixed in v1.4, r30677. Tim Laqua talk 18:40, 7 February 2008 (UTC)

Call to undefined function wfLoadExtensionMessage
I get the following error when trying to use this extension: Fatal error: Call to undefined function wfLoadExtensionMessage in extensions\UserMerge\UserMerge.php on line 32 Using mediawiki 1.11.1 -Z
 * Line 32 is "wfLoadExtensionMessages('UserMerge');" - mw 1.11+ should support that function. Make sure you have the latest revision of this extension and verify that you are running MW 1.11+  Tim Laqua talk 17:36, 12 February 2008 (UTC)
 * Is there any way to get your extension working with MediaWiki version 1.10?
 * Yes, download an old revision like: http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/UserMerge/?pathrev=27730
 * I have MediaWiki 1.6.10 and the SVN checkout of UserMerge, and I get this wfLoadExtensionMessages error too. 144.171.146.113 22:58, 20 February 2008 (UTC)
 * It doesn't work on 1.6.10 - I don't think it ever did or ever will. Tim Laqua talk 21:07, 21 February 2008 (UTC)

A simple question about the default used when "nonewuser"
Hi there, dear Tim. You are doing a wonderful work with this extension - wich I'm using to create a mod to delete all the users from the "student" type at user_groups table - In this last change you seem to have changed the behaviour of the newuser used when it's void. The version from before used the username with the id 1 (WikiSysop) and this newer version uses the username with id 0 (Anonymous). Why this change? -Juanan 23:05, 15 February 2008 (UTC)
 * Excellent question! Because a few other developers disagreed pretty adamently with merging users to "ID 1" as id 1 doesn't actually mean anything to MediaWiki.  In actuality user_id 1 could be a normal user!  The only time that user_id 1 is indeed the "admin" user is following a 100% default install, with no goofy merging or migrating going on.  Well, we don't like to assume around here.  So the merge to Anonymous is now allowed and enabled by default.  ;-) Tim Laqua talk 21:03, 21 February 2008 (UTC)

Newbie hack
I gotta echo Juanan's call above: "Select the user instead of writing it?" -- that would be handy!

In the absence of such a drop-down list, I added the following clumsy code to my installation of this awesome extention.

I did this because and The hack (obviously?) starts not far below the recognizable line "//NO POST data found" and stops at the line "<form id='usermergeform' ..."
 * First hack: I believe I will always want to merge-and-delete no-longer-wanted accounts into a user that I set up for the purpose, named (DeletedUser), so I prefilled the NewUserMergeTo with that named, and pre-CHECKED the DeleteUserbox ... note you have to have the user account (DeletedUser) already created! or you'd get an error(duh).
 * Second hack: having a lazy brain, I find it difficult to remember the username for the 2.5 seconds it takes me to click over to the UserMergeAndDelete page, so I stuck an iFrame into the page, sourced as my Special:Listusers URL, so I will always have a list of users handy on the page.

It's not pretty, but it helps. Thought I'd share, anyway. And I renew my "Praise" comment (from above). Cheers! --Töff 01:03, 16 February 2008 (UTC) //NO POST data found }               $action = $wgTitle->escapeLocalUrl; $token = $wgUser->editToken;

// ====================================== PaleRavens hack $newuser_text = "(DeletedUser)"; $deleteUserCheck = "CHECKED "; // ====================================== /hack

$wgOut->addHTML( "




 * Update: the hack actually generates a couple of harmless errors. They only show up if error reporting is turned on. The functionality seems to be still 100%.--Töff 04:56, 18 February 2008 (UTC)
 * Interesting... I'll see if I can get to this the first week of March.  Tim Laqua talk 20:59, 21 February 2008 (UTC)
 * Cool, an official version would be awesome. --Töff 01:51, 14 March 2008 (UTC)

Complete merge between user accounts
I was hoping that this extension could actually change all 'User:' references in the database to the new user. I really don't want any traces of the old user hanging around the database. Could this be added as an extra option? --AlissaHarrison 10:29, 17 February 2008 (UTC)
 * I thought that's what it does now. --Töff 04:54, 18 February 2008 (UTC)
 * Me too. Tim Laqua talk 20:57, 21 February 2008 (UTC)
 * Oh, are you talking about namespaces? Like the old User:Username articles exist in the database?  Tim Laqua talk 00:02, 23 February 2008 (UTC)

Partial Logging
Hello again Tim. I have completely succeeded into creating the mass "students" deletion using your merge & delete (will post soon), but I noticed there's something that isn't working at this version yet. The logging! Since there appear only two lines in the all logs option, and none under the "User merge and delete" bar.

At the usermerge.php the two lines of code are
 * $wgLogActions['usermerge/mergeuser'] 	= 'usermerge-success-log';
 * $wgLogActions['usermerge/deleteuser']	= 'usermerge-userdeleted-log';

Assuming they refer to the internationalisation code.
 * 'usermerge-success-log' 	=> 'User $2 ($3) merged to $4 ($5)',
 * 'usermerge-userdeleted-log' 	=> 'Deleted user: $2 ($3)',

At the usermerge_body.php the two calls to the logging are:
 * In the merge function
 * $log = new LogPage( 'usermerge' );
 * $log->addEntry( 'mergeuser', $wgUser->getUserPage,'',array($olduser_text,$olduserID,$newuser_text,$newuserID) );
 * In the delete function
 * $log = new LogPage( 'usermerge' );
 * $log->addEntry( 'deleteuser', $wgUser->getUserPage,'',array($olduser_text,$olduserID) );

The thing is that I believe either the two lines on the UserMerge.php or the call to the log->adEntry... is not done correctly. Could it be also that the parsing at the internationalisation array is not done correctly? Since there only appear the two lines of the $log->addEntry in the Special:logs like this  => 16:02, 22 February 2008 Pau Fonseca (Talk | contribs | block) deleteuser ‎ and also 16:02, 22 February 2008 Pau Fonseca (Talk | contribs | block) mergeuser ‎(and they only appear under the (all logs) option.

Man, I really seem to be pointing the errors all the time but it's not my intention to be annoying, besides you understand the insides of the mediawiki far better than I will ever know. --Juanan 16:49, 22 February 2008 (UTC)
 * Can't confirm. I checked on a current 1.12alpha wiki and a 1.11.1 wiki and am unable to reproduce.  It's most likely something that you changed in your implementation.

14:11, 6 February 2008 [snip] (Talk | contribs | block) User [snip] (130) merged to [snip] (1) ‎ 14:10, 6 February 2008 [snip] (Talk | contribs | block) Deleted user: [snip] (149) ‎ 14:10, 6 February 2008 [snip] (Talk | contribs | block) User [snip] (149) merged to [snip] (42) ‎
 * All of my logs look fine (both the user merge log and listings under all logs). Tim Laqua talk 23:49, 22 February 2008 (UTC)
 * I see where the error was. i had the logType like this -> $wgLogTypes[]                 		= 'studentdelete';   and it seems that the database type for the variable log_type is a varbinary(10) so it saved only "studentdel" and never showed at logs. Problem solved thanks!

But now i have another question (i havent checked this exhaustively though). I noticed that when you create usernames a lot and delete them also, it gives the new users ids that were given before. For example an user has UID 10, i create 2 more users, so they use UID 11 and 12. But when I delete some of the middle.. for example the UID 10. is there any chance that when creating new users it tries to give the username a UID of 10 ? since its an incremental variable won't this mean that sometime later it will try to give the next UID the value 11, even though it's ocupied? (there goes my brick)--Juanan 20:10, 25 February 2008 (UTC)
 * No, that's not how it works:

mysql> desc user; +--+-+--+-+-++ +--+-+--+-+-++ +--+-+--+-+-++ 15 rows in set (0.01 sec)
 * Field                   | Type            | Null | Key | Default | Extra          |
 * user_id                 | int(5) unsigned | NO   | PRI | NULL    | auto_increment |
 * user_name               | varchar(255)    | NO   | UNI |         |                |
 * user_real_name          | varchar(255)    | NO   |     |         |                |
 * user_password           | tinyblob        | NO   |     |         |                |
 * user_newpassword        | tinyblob        | NO   |     |         |                |
 * user_email              | tinytext        | NO   |     |         |                |
 * user_options            | blob            | NO   |     |         |                |
 * user_touched            | char(14)        | NO   |     |         |                |
 * user_token              | char(32)        | NO   |     |         |                |
 * user_email_authenticated | char(14)       | YES  |     | NULL    |                |
 * user_email_token        | char(32)        | YES  | MUL | NULL    |                |
 * user_email_token_expires | char(14)       | YES  |     | NULL    |                |
 * user_registration       | char(14)        | YES  |     | NULL    |                |
 * user_newpass_time       | char(14)        | YES  |     | NULL    |                |
 * user_editcount          | int(11)         | YES  |     | NULL    |                |
 * auto_increment variables don't crash in to themselves - as a matter of fact, they don't re-use IDs once they have been issued - ever. You can technically reset the auto_increment counter, but there is virtually no reason to do so.  It'll just keep counting up and up until it runs out of space.  Then i'm honestly not sure what happens...  I would imagine it'd throw some sort of error - but it won't ever loop around.  If you were running out of space for IDs (i.e. you exceeded the size of field as defined) - you would most likely just alter the field to be larger.


 * Also, regarding your solution - please don't post it on the pages for this extension - post a fork extension or post it in a subpage of your user account. The reason for this is because I will not support the fork - so if you post it, you need to either stipulate that you are posting as is or you need to support it. Tim Laqua talk 22:29, 25 February 2008 (UTC)
 * http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html further info - and a particular condition where an ID will be reused (if the highest value in a group is deleted) Tim Laqua talk 12:39, 26 February 2008 (UTC)

After deleting an user some logs remain
Hi there Tim, I noticed today that when you delete an username using your extension it doesn't delete some logs, so far ive just detected this on the permission changes logs for the user. This can be shown when you create an user with the same username, it shows the previous user permission changes logs. By the way, have you tried the extension with the last version 1.12? It seems that the parser has suffered dramatic changes. We'll see how this affects the other extensions. -Juanan 15:27, 26 March 2008 (UTC)
 * Interesting, I never really considered that people would re-create deleted users - I'll look in to clearing out the log entries next time I get a chance. I haven't tried specifically with the released 1.12 branch, but I do actively test on the SVN trunk (1.13alpha now).  Have you noticed any oddities?  The parser did indeed dramatically change, but I don't think it will effect this extension in particular.  Tim Laqua talk 17:09, 26 March 2008 (UTC)
 * I looked in to the logs more - logging.log_user is the user_id of the user who performed the logged action. I already merge that field - so what exactly are you referring to?  The text in the log comment? Tim Laqua talk 17:25, 26 March 2008 (UTC)
 * When i create the user Test3 (for example) and then go to User Rights Management I can see previous user changes that have relation to this user: For example: 10:49, 19 March 2008 Pau Fonseca (Talk | contribs | block) changed group membership for Usuari:Test3 from student to student, banned ‎. I don't think it has to do with the user group they belong to (since it's a custom group) and it does not make sense that there is actual information (in a log ) about a user who has been deleted (well it's debatable too to keep the information on a log or not about this when the user has already been deleted :) ) . Also a bit of offtopic but do you know where to find a mediawiki databse schema updated (ver. 1.11 or 1.12)--Juanan 19:06, 26 March 2008 (UTC)
 * Eh, it's a matter of parsing out the comment text to weed out those references. I do have qualms about the fact that the link to the user page is embeded in those messages - but technically, it doesn't break referrential integrity, so I don't see any problems with it.  Not to mention that those logged actions did indeed occur - there's just more to the story... which is in a different log.  ;-)  Leaving it in lets the logs tell the story of the wiki - which is the goal.  As far as the schema, look at maintenance/tables.sql in whatever wiki version you need.  You won't always see hard FK constraints, but it's pretty self explanitory.  Also see Database, which hasn't been updated for 1.12 yet.  Tim Laqua talk 22:21, 26 March 2008 (UTC)

Another question
Hello Tim, I've noticed some interesting fact. When you do delete a user it doesn't completely delete the user_talk references. In mergeuser function you do this -> $dbw->delete( 'user_newtalk', array( 'user_ip' => $olduserID ));. But shouldn't you do this also in the delete function $dbw->delete( 'user_newtalk', array( 'user_id' => $olduserID ));. What do you think?--Juanan 17:32, 17 April 2008 (UTC)
 * Whoops, good catch. Not in addition, but instead of - looks like a typo, it always should have been deleting on user_id matches.  Fixed in v1.9.1, r33499. Tim Laqua talk 18:10, 17 April 2008 (UTC)

How to merge and delete a large list of users
Here's some code I used to merge and delete about 400 users. This was done under Windows because it's the OS I happened to be on at the time. This would be simpler directly under bash. This syntax is DOS/Batch not bash.

First I went to the "User List" page and copy and pasted the list of users into a text file called "users.txt". I removed the users I wanted to keep.

Next I created a user to merge all other users into, I called it "Merge-delete". I did this through the normal mediawiki web UI.

Next I logged in to the wiki from the command line, generating the authentication cookies and determining the edit token


 * ADMIN is your user account that can use the Merge and Delete extension
 * ADMINPASSWORD is the password for that user

d:\tools\curl\curl --location --cookie-jar cookie_jar.txt --cookie cookie_jar.txt -d wpName=ADMIN -d wpPassword=ADMINPASSWORD -d wpRemember=1 -d wpLoginattempt="Log in" http://www.example.com/wiki/index.php?title=Special:Userlogin^&action=submitlogin^&type=login

Next go to the UserMerge page to get the edit token

d:\tools\curl\curl --cookie-jar cookie_jar.txt --cookie cookie_jar.txt http://www.example.com/wiki/index.php?title=Special:Userlogin | find "token"

Next take this edit token and urlencode it (you can use a urlencoder out on the web if you need). This results in an edit token looking like "b817be56d8d14b680e01f114d198996a%2B%5C"

Finally put it all together into a loop that calls the UserMerge page and merges and deletes each user

for /f "tokens=*" %A IN (users.txt) DO d:\tools\curl\curl --cookie-jar cookie_jar.txt --cookie cookie_jar.txt -d olduser=%A -d newuser=Merge-delete -d deleteuser=on -d submit=Merge+user -d token=b817be56d8d14b680e01f114d198996a%2B%5C http://www.example.com/wiki/index.php/Special:UserMerge | find "to Merge-delete"

Careful not to Merge the "Merege-delete" user into the "Merge-delete" user like I did. =)

Cleanup of Additonal Tables (Extensions)
Great extension. A couple of things: watchlist/wl_user page_restrictions/pr_user (not sure what pr_id is)? protected_titles/pt_user $wgUserMergeIdUpdates = array; $wgUserMergeTextUpdates = array; If the Extension:DocumentApproval is added to the Wiki the administrator could then override these tokens rather than changing the code. $wgUserMergeIdUpdates = array(array('approval','user_id'),array('approval_request','user_id')); $wgUserMergeTextUpdates = array; Then the code UserMerge.php can be changed to initialize the variables if (!isset($wgUserMergeTextUpdates)) $wgUserMergeTextUpdates = array; if (!isset($wgUserMergeIdUpdates)) $wgUserMergeIdUpdates = array; Then the code UserMerge_body.php can be changed to merge the predefined array $textUpdateFields and $idUpdateFields. private function mergeUser ($newuser_text, $newuserID, $olduser_text, $olduserID) { global $wgOut, $wgUser, $wgUserMergeIdUpdates, $wgUserMergeTextUpdates;
 * The front page shows the code is at 1.5, but the discussion pages says "Fixed in v1.9.1, r33499".
 * To cleanup warnings line 53 and 82 need to test if it is an object before asking for the idForName.
 * Should the following tables/columns be added:
 * Because other extensions can add tables to the Wiki that contain a user_id and/or user_name two additional tokens should be allowed in the LocalSettings.php file

$textUpdateFields = array_merge(array(array('archive','ar_user_text'), array('revision','rev_user_text'), array('filearchive','fa_user_text'), array('image','img_user_text'), array('oldimage','oi_user_text'), array('recentchanges','rc_user_text'), array('ipblocks','ipb_address')), $wgUserMergeTextUpdates);

$idUpdateFields = array_merge(array(array('archive','ar_user'), array('revision','rev_user'), array('filearchive','fa_user'), array('image','img_user'), array('oldimage','oi_user'), array('recentchanges','rc_user'), array('logging','log_user')), $wgUserMergeIdUpdates);

... Chris Wolcott 14:32, 10 June 2008 (UTC)