r88699 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r88698‎ | r88699 | r88700 >
Date:22:45, 23 May 2011
Author:janpaul123
Status:ok (Comments)
Tags:
Comment:
Modified paths:
  • /trunk/extensions/WikiLove/WikiLove.api.php (modified) (history)
  • /trunk/extensions/WikiLove/WikiLove.i18n.php (modified) (history)
  • /trunk/extensions/WikiLove/WikiLove.php (modified) (history)
  • /trunk/extensions/WikiLove/defaultTypes.js (modified) (history)
  • /trunk/extensions/WikiLove/patches/WikiLoveLog.sql (modified) (history)
  • /trunk/extensions/WikiLove/wikiLove.js (modified) (history)

Diff [purge]

Index: trunk/extensions/WikiLove/WikiLove.php
@@ -45,6 +45,11 @@
4646 'descriptionmsg' => 'wikilove-desc',
4747 );
4848
 49+// default user options
 50+$wgWikiLoveGlobal = false; // enable the extension for all users, removing the user preference
 51+$wgWikiLoveTabIcon = true; // use an icon for skins that support them (i.e. Vector)
 52+$wgWikiLoveLogging = false; // enable logging of giving of WikiLove
 53+
4954 // current directory including trailing slash
5055 $dir = dirname( __FILE__ ) . '/';
5156
@@ -60,17 +65,11 @@
6166 $wgHooks['SkinTemplateNavigation'][] = 'WikiLoveHooks::skinTemplateNavigation';
6267 $wgHooks['SkinTemplateTabs'][] = 'WikiLoveHooks::skinTemplateTabs';
6368 $wgHooks['BeforePageDisplay'][] = 'WikiLoveHooks::beforePageDisplay';
64 -//$wgHooks['LoadExtensionSchemaUpdates'][] = 'WikiLoveHooks::loadExtensionSchemaUpdates';
65 -// Not a final schema, please apply patches/WikiLoveLog.sql manually for now!
 69+$wgHooks['LoadExtensionSchemaUpdates'][] = 'WikiLoveHooks::loadExtensionSchemaUpdates';
6670
6771 // api modules
68 -$wgAPIModules['wikiLove'] = 'WikiLoveApi';
 72+$wgAPIModules['wikilove'] = 'WikiLoveApi';
6973
70 -// default user options
71 -$wgWikiLoveGlobal = false;
72 -$wgWikiLoveTabIcon = true;
73 -$wgWikiLoveLogging = false;
74 -
7574 // resources
7675 $wikiLoveTpl = array(
7776 'localBasePath' => dirname( __FILE__ ),
@@ -100,6 +99,7 @@
101100 'wikilove-omit-sig',
102101 'wikilove-button-preview',
103102 'wikilove-preview',
 103+ 'wikilove-notify',
104104 'wikilove-button-send',
105105 'wikilove-type-makeyourown',
106106 'wikilove-err-header',
@@ -113,6 +113,7 @@
114114 'jquery.ui.dialog',
115115 'jquery.ui.button',
116116 'jquery.elastic',
 117+ 'jquery.localize',
117118 ),
118119 ),
119120 'jquery.elastic' => $wikiLoveTpl + array(
Index: trunk/extensions/WikiLove/defaultTypes.js
@@ -2,44 +2,45 @@
33 // example type, could be removed later (also no i18n)
44 'barnstar': {
55 name: 'Barnstar', // name of the type (appears in the types menu)
6 - fields: [ 'header', 'title', 'image' ], // fields to ask for in form if not specified in config
76 select: 'Select a barnstar:', // subtype select label
87 subtypes: { // some different subtypes
98 // note that when not using subtypes you should use these subtype options
109 // for the top-level type
1110 'original': {
 11+ fields: [ 'notify' ], // fields to ask for in form
1212 option: 'Original barnstar', // option listed in the select list
1313 descr: 'This barnstar is given to recognize particularly fine contributions to Wikipedia, to let people know that their hard work is seen and appreciated.', // description
14 - header: mw.msg( 'wikilove-barnstar-header' ), // header that appears at the top of the talk page post (optional)
 14+ header: 'A barnstar for you!', // header that appears at the top of the talk page post (optional)
1515 title: 'The Original Barnstar', // title that appears inside the award box (optional)
1616 image: 'Original Barnstar Hires.png', // image for the award
1717 mail: 'Hello $7!\n\nI just awarded you a barnstar.' // message to use in email notification; $7 is replaced by the recipient's username
1818 },
1919 'editors': {
 20+ fields: [ 'notify' ],
2021 option: 'Editor\'s barnstar',
2122 descr: 'The Editor\'s Barnstar is awarded to individuals who display particularly fine decisions in general editing.',
22 - header: mw.msg( 'wikilove-barnstar-header' ),
 23+ header: 'A barnstar for you!',
2324 title: 'The Editor\'s Barnstar',
2425 image: 'Editors Barnstar Hires.png',
2526 mail: 'Hello $7!\n\nI just awarded you a barnstar.'
2627 },
2728 'tireless': {
 29+ fields: [ 'title', 'notify' ],
2830 option: 'Tireless contributor barnstar',
2931 descr: 'The Tireless Contributor Barnstar is awarded to especially tireless Wikipedians who contribute an especially large body of work without sacrificing quality.',
30 - header: mw.msg( 'wikilove-barnstar-header' ),
31 - title: 'The Editor\'s Barnstar',
 32+ header: 'A barnstar for you!',
 33+ title: 'Tireless contributor barnstar',
3234 image: 'Tireless Contributor Barnstar Hires.gif',
3335 mail: 'Hello $7!\n\nI just awarded you a barnstar.'
3436 }
3537 },
36 - showNotify: true, // add email notices as an option for each award of this type
3738 icon: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/extensions/WikiLove/images/icons/wikilove-icon-barnstar.png' // icon for left-side menu
3839 },
3940 'cats': {
4041 name: 'Cat',
4142 fields: [ 'header' ],
4243 header: 'A kitten for you!',
43 - text: '[[$3|left|150px]]\n$1\n\n~~~~\n<br style="clear: both"/>', // $3 is the image filename
 44+ text: '[[$3|left|150px]]\n$1\n\n~~~~\n<br style="clear: both"/>', // custom text
4445 gallery: {
4546 // right now we can only query the local wiki (not e.g. commons)
4647 category: 'Category:Cats',
@@ -51,7 +52,7 @@
5253 // default type, nice to leave this one in place when adding other types
5354 'makeyourown': {
5455 name: mw.msg( 'wikilove-type-makeyourown' ),
55 - fields: [ 'header', 'title', 'image' ],
 56+ fields: [ 'header', 'title', 'image', 'notify' ],
5657 imageSize: '150px'
5758 }
5859 }
\ No newline at end of file
Index: trunk/extensions/WikiLove/wikiLove.js
@@ -1,3 +1,4 @@
 2+var mw;
23 ( function( $ ) { $.wikiLove = {
34
45 $dialog: null, // dialog jQuery object
@@ -24,112 +25,116 @@
2526 if ( $.wikiLove.$dialog === null ) {
2627 // Load local configuration
2728 var wikiLoveConfigUrl = wgServer + wgScript + '?' + $.param( { 'title': 'MediaWiki:WikiLove.js', 'action': 'raw', 'ctype': 'text/javascript' } );
28 - mw.loader.load( wikiLoveConfigUrl );
29 -
30 - // Find out if we can email the user
31 - $.wikiLove.getEmailable();
32 -
33 - // Reusable spinner string
34 - var spinner = '<img class="wlSpinner" src="' + mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' )
35 - + '/extensions/WikiLove/images/spinner.gif"/>';
36 -
37 - // Build a type list like this:
38 - var $typeList = $( '<ul id="wlTypes"></ul>' );
39 - for( var typeId in $.wikiLove.types ) {
40 - $button = $( '<a href="#"></a>' );
41 - $buttonInside = $( '<div class="wlInside"></div>' );
 29+ $.getScript( wikiLoveConfigUrl, function() {
 30+ // Test to see if the 'E-mail this user' link exists
 31+ $.wikiLove.emailable = $( '#t-emailuser' ).length ? true : false;
4232
43 - if( typeof $.wikiLove.types[typeId].icon == 'string' ) {
44 - $buttonInside.append( '<div class="wlIconBox"><img src="'
45 - + $.wikiLove.types[typeId].icon + '"/></div>' );
 33+ // Reusable spinner string
 34+ var spinner = '<img class="wlSpinner" src="' + mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/extensions/WikiLove/images/spinner.gif' + '"/>';
 35+
 36+ // Build a type list like this:
 37+ var $typeList = $( '<ul id="wlTypes"></ul>' );
 38+ for( var typeId in $.wikiLove.types ) {
 39+ var $button = $( '<a href="#"></a>' );
 40+ var $buttonInside = $( '<div class="wlInside"></div>' );
 41+
 42+ if( typeof $.wikiLove.types[typeId].icon == 'string' ) {
 43+ $buttonInside.append( '<div class="wlIconBox"><img src="'
 44+ + mw.html.escape( $.wikiLove.types[typeId].icon ) + '"/></div>' );
 45+ }
 46+ else {
 47+ $buttonInside.addClass( 'wlNoIcon' );
 48+ }
 49+
 50+ $buttonInside.append( '<div class="wlLinkText">' + $.wikiLove.types[typeId].name + '</div>' );
 51+
 52+ $button.append( '<div class="wlLeftCap"></div>');
 53+ $button.append( $buttonInside );
 54+ $button.append( '<div class="wlRightCap"></div>');
 55+ $button.data( 'typeId', typeId );
 56+ $typeList.append( $( '<li tabindex="0"></li>' ).append( $button ) );
4657 }
47 - else {
48 - $buttonInside.addClass( 'wlNoIcon' );
49 - }
5058
51 - $buttonInside.append( '<div class="wlLinkText">' + $.wikiLove.types[typeId].name + '</div>' );
 59+ $.wikiLove.$dialog = $( '\
 60+<div id="wikiLoveDialog">\
 61+ <div id="wlSelectType">\
 62+ <span class="wlNumber">1</span>\
 63+ <h3><html:msg key="wikilove-select-type"/></h3>\
 64+ <ul id="wlTypes"></ul>\
 65+ </div>\
 66+ <div id="wlGetStarted">\
 67+ <h2><html:msg key="wikilove-get-started-header"/></h2>\
 68+ <ol>\
 69+ <li><html:msg key="wikilove-get-started-list-1"/></li>\
 70+ <li><html:msg key="wikilove-get-started-list-2"/></li>\
 71+ <li><html:msg key="wikilove-get-started-list-3"/></li>\
 72+ </ol>\
 73+ </div>\
 74+ <div id="wlAddDetails">\
 75+ <span class="wlNumber">2</span>\
 76+ <h3><html:msg key="wikilove-add-details"/></h3>\
 77+ <form id="wlPreviewForm">\
 78+ <label for="wlSubtype" id="wlSubtypeLabel"></label>\
 79+ <select id="wlSubtype"></select>\
 80+ <div id="wlSubtypeDescription"></div>\
 81+ <label id="wlGalleryLabel"><html:msg key="wikilove-image"/></label>\
 82+ <div id="wlGallerySpinner">' + spinner + '</div>\
 83+ <div id="wlGallery"></div>\
 84+ <label for="wlHeader" id="wlHeaderLabel"><html:msg key="wikilove-header"/></label>\
 85+ <input type="text" class="text" id="wlHeader"/>\
 86+ <label for="wlTitle" id="wlTitleLabel"><html:msg key="wikilove-title"/></label>\
 87+ <input type="text" class="text" id="wlTitle"/>\
 88+ <label for="wlImage" id="wlImageLabel"><html:msg key="wikilove-image"/></label>\
 89+ <input type="text" class="text" id="wlImage"/>\
 90+ <label for="wlMessage" id="wlMessageLabel"><html:msg key="wikilove-enter-message"/></label>\
 91+ <span class="wlNote"><html:msg key="wikilove-omit-sig"/></span>\
 92+ <textarea id="wlMessage"></textarea>\
 93+ <div id="wlNotify">\
 94+ <input type="checkbox" id="wlNotifyCheckbox" name="notify"/>\
 95+ <label for="wlNotifyCheckbox"><html:msg key="wikilove-notify"/></label>\
 96+ </div>\
 97+ <button class="submit" id="wlButtonPreview" type="submit"></button>\
 98+ ' + spinner + '\
 99+ </form>\
 100+ </div>\
 101+ <div id="wlPreview">\
 102+ <span class="wlNumber">3</span>\
 103+ <h3><html:msg key="wikilove-preview"/></h3>\
 104+ <div id="wlPreviewArea"></div>\
 105+ <form id="wlSendForm">\
 106+ <button class="submit" id="wlButtonSend" type="submit"></button>\
 107+ ' + spinner + '\
 108+ </form>\
 109+ </div>\
 110+</div>' );
 111+ $.wikiLove.$dialog.localize();
52112
53 - $button.append( '<div class="wlLeftCap"></div>');
54 - $button.append( $buttonInside );
55 - $button.append( '<div class="wlRightCap"></div>');
56 - $button.data( 'typeId', typeId );
57 - $typeList.append( $( '<li tabindex="0"></li>' ).append( $button ) );
58 - }
59 -
60 - // Build the left menu for selecting a type:
61 - var $selectType = $( '<div id="wlSelectType"></div>' )
62 - .append( '<span class="wlNumber">1</span>' )
63 - .append( '<h3>' + mw.msg( 'wikilove-select-type' ) + '</h3>' )
64 - .append( $typeList );
 113+ $.wikiLove.$dialog.dialog({
 114+ width: 800,
 115+ position: ['center', 80],
 116+ autoOpen: false,
 117+ title: mw.msg( 'wikilove-dialog-title' ),
 118+ modal: true,
 119+ resizable: false
 120+ });
65121
66 - var $getStarted = $( '<div id="wlGetStarted"></div>' )
67 - .append( '<h2>' + mw.msg( 'wikilove-get-started-header' ) + '</h2>' )
68 - .append( $( '<ol></ol>' )
69 - .append( '<li>' + mw.msg( 'wikilove-get-started-list-1' ) + '</li>' )
70 - .append( '<li>' + mw.msg( 'wikilove-get-started-list-2' ) + '</li>' )
71 - .append( '<li>' + mw.msg( 'wikilove-get-started-list-3' ) + '</li>' )
72 - );
73 -
74 - // Build the right top section for selecting a subtype and entering a title (optional) and message
75 - var $addDetails = $( '<div id="wlAddDetails"></div>' )
76 - .append( '<span class="wlNumber">2</span>' )
77 - .append( '<h3>' + mw.msg( 'wikilove-add-details' ) + '</h3>' )
78 - .append( $( '<form id="wlPreviewForm"></form>' )
79 - .append( '<label for="wlSubtype" id="wlSubtypeLabel"></label>' )
80 - .append( '<select id="wlSubtype"></select>' )
81 - .append( '<div id="wlSubtypeDescription"/>' )
82 - .append( '<label id="wlGalleryLabel">' + mw.msg( 'wikilove-image' ) + '</label>' )
83 - .append( '<div id="wlGallerySpinner">' + spinner + '</div>' )
84 - .append( '<div id="wlGallery"/>' )
85 - .append( '<label for="wlHeader" id="wlHeaderLabel">' + mw.msg( 'wikilove-header' ) + '</label>' )
86 - .append( '<input type="text" class="text" id="wlHeader"/>' )
87 - .append( '<label for="wlTitle" id="wlTitleLabel">' + mw.msg( 'wikilove-title' ) + '</label>' )
88 - .append( '<input type="text" class="text" id="wlTitle"/>' )
89 - .append( '<label for="wlImage" id="wlImageLabel">' + mw.msg( 'wikilove-image' ) + '</label>' )
90 - .append( '<input type="text" class="text" id="wlImage"/>' )
91 - .append( '<label for="wlMessage" id="wlMessageLabel">' + mw.msg( 'wikilove-enter-message' ) + '</label>' )
92 - .append( '<span class="wlNote">' + mw.msg( 'wikilove-omit-sig' ) + '</span>' )
93 - .append( '<textarea id="wlMessage"></textarea>' )
94 - .append( $('<div id="wlNotify"></div>').html('<input type="checkbox" id="wlNotifyCheckbox" name="notify"/> <label for="wlNotifyCheckbox">Notify user by email</label>') )
95 - .append( $('<button class="submit" id="wlButtonPreview" type="submit"></button>').button({ label: mw.msg( 'wikilove-button-preview' ), icons: { primary:'ui-icon-search' } }) )
96 - .append( spinner )
97 - )
98 - .hide();
99 -
100 - // Build the right bottom preview section
101 - var $preview = $( '<div id="wlPreview"></div>' )
102 - .append( '<span class="wlNumber">3</span>' )
103 - .append( '<h3>' + mw.msg( 'wikilove-preview' ) + '</h3>' )
104 - .append( '<div id="wlPreviewArea"></div>' )
105 - .append( $( '<form id="wlSendForm"></form>' )
106 - .append( $('<button class="submit" id="wlButtonSend" type="submit"></button>').button({ label: mw.msg( 'wikilove-button-send' ) }) )
107 - .append( spinner )
108 - )
109 - .hide();
110 -
111 - // Build a modal, hidden dialog with the 3 different sections
112 - $.wikiLove.$dialog = $( '<div id="wikiLoveDialog"></div>' )
113 - .append( $selectType )
114 - .append( $getStarted )
115 - .append( $addDetails )
116 - .append( $preview )
117 - .dialog({
118 - width: 800,
119 - position: ['center', 80],
120 - autoOpen: false,
121 - title: mw.msg( 'wikilove-dialog-title' ),
122 - modal: true,
123 - resizable: false
124 - });
125 -
126 - $( '#wlTypes a' ).click( $.wikiLove.clickType );
127 - $( '#wlSubtype' ).change( $.wikiLove.changeSubtype );
128 - $( '#wlPreviewForm' ).submit( $.wikiLove.submitPreview );
129 - $( '#wlSendForm' ).click( $.wikiLove.submitSend );
130 - $( '#wlMessage' ).elastic(); // have the message textarea grow automatically
 122+ $( '#wlButtonPreview' ).button( { label: mw.msg( 'wikilove-button-preview' ), icons: { primary:'ui-icon-search' } } );
 123+ $( '#wlButtonSend' ).button( { label: mw.msg( 'wikilove-button-send' ) } );
 124+ $( '#wlAddDetails' ).hide();
 125+ $( '#wlPreview' ).hide();
 126+ $( '#wlTypes' ).replaceWith( $typeList );
 127+
 128+ $( '#wlTypes a' ).click( $.wikiLove.clickType );
 129+ $( '#wlSubtype' ).change( $.wikiLove.changeSubtype );
 130+ $( '#wlPreviewForm' ).submit( $.wikiLove.submitPreview );
 131+ $( '#wlSendForm' ).click( $.wikiLove.submitSend );
 132+ $( '#wlMessage' ).elastic(); // have the message textarea grow automatically
 133+
 134+ $.wikiLove.$dialog.dialog( 'open' );
 135+ });
 136+ } else {
 137+ $.wikiLove.$dialog.dialog( 'open' );
131138 }
132 -
133 - $.wikiLove.$dialog.dialog( 'open' );
134139 },
135140
136141 /*
@@ -157,13 +162,13 @@
158163 // add all the subtypes to the menu while setting their subtype ids in jQuery data
159164 var subtype = $.wikiLove.types[$.wikiLove.currentTypeId].subtypes[subtypeId];
160165 $( '#wlSubtype' ).append(
161 - $( '<option>' + subtype.option + '</option>' ).data( 'subtypeId', subtypeId )
 166+ $( '<option></option>' ).text( subtype.option ).data( 'subtypeId', subtypeId )
162167 );
163168 }
164169 $( '#wlSubtype' ).show();
165170
166171 // change and show the subtype label depending on the type
167 - $( '#wlSubtypeLabel' ).text( $.wikiLove.types[$.wikiLove.currentTypeId].select );
 172+ $( '#wlSubtypeLabel' ).text( $.wikiLove.types[$.wikiLove.currentTypeId].select || mw.msg( 'wikilove-select-type' ) );
168173 $( '#wlSubtypeLabel' ).show();
169174 $.wikiLove.changeSubtype(); // update controls depending on the currently selected (i.e. first) subtype
170175 }
@@ -200,33 +205,6 @@
201206 },
202207
203208 /*
204 - * Find out whether we can e-mail this user. Probably needs to be moved to the API.
205 - */
206 - getEmailable: function() {
207 - // Test to see if the 'E-mail this user' link exists
208 - $.wikiLove.emailable = $('#t-emailuser').length ? true : false;
209 - },
210 -
211 - /*
212 - * Actually send the notification e-mail. Probably needs to be moved to the API.
213 - */
214 - sendEmail: function( subject, text ) {
215 - $.ajax({
216 - url: mw.util.wikiScript( 'api' ),
217 - data: {
218 - 'action': 'emailuser',
219 - 'target': wgTitle,
220 - 'subject': subject,
221 - 'text': text,
222 - 'format': 'json',
223 - 'token': mw.user.tokens.get( 'editToken' )
224 - },
225 - dataType: 'json',
226 - type: 'POST'
227 - });
228 - },
229 -
230 - /*
231209 * Called when type or subtype changes, updates controls.
232210 */
233211 updateAllDetails: function() {
@@ -240,40 +218,34 @@
241219 }
242220
243221 // show or hide header label and textbox depending on whether a predefined header exists
244 - var needsHeader = $.inArray( 'header', $.wikiLove.types[$.wikiLove.currentTypeId].fields );
245 - if( typeof $.wikiLove.currentTypeOrSubtype.header == 'string' || needsHeader == -1 ) {
246 - $( '#wlHeaderLabel').hide();
247 - $( '#wlHeader' ).hide();
248 - $( '#wlHeader' ).val( $.wikiLove.currentTypeOrSubtype.header );
249 - } else if ( needsHeader != -1 ) {
 222+ if( $.inArray( 'header', $.wikiLove.currentTypeOrSubtype.fields ) >= 0 ) {
250223 $( '#wlHeaderLabel').show();
251224 $( '#wlHeader' ).show();
252 - $( '#wlHeader' ).val( '' );
 225+ } else {
 226+ $( '#wlHeaderLabel').hide();
 227+ $( '#wlHeader' ).hide();
253228 }
 229+ $( '#wlHeader' ).val( $.wikiLove.currentTypeOrSubtype.header || '' );
254230
255231 // show or hide title label and textbox depending on whether a predefined title exists
256 - var needsTitle = $.inArray( 'title', $.wikiLove.types[$.wikiLove.currentTypeId].fields );
257 - if( typeof $.wikiLove.currentTypeOrSubtype.title == 'string' || needsTitle == -1 ) {
258 - $( '#wlTitleLabel').hide();
259 - $( '#wlTitle' ).hide();
260 - $( '#wlTitle' ).val( $.wikiLove.currentTypeOrSubtype.title );
261 - } else if ( needsTitle != -1 ) {
 232+ if( $.inArray( 'title', $.wikiLove.currentTypeOrSubtype.fields ) >= 0 ) {
262233 $( '#wlTitleLabel').show();
263234 $( '#wlTitle' ).show();
264 - $( '#wlTitle' ).val( '' );
 235+ } else {
 236+ $( '#wlTitleLabel').hide();
 237+ $( '#wlTitle' ).hide();
265238 }
 239+ $( '#wlTitle' ).val( $.wikiLove.currentTypeOrSubtype.title || '' );
266240
267241 // show or hide image label and textbox depending on whether a predefined image exists
268 - var needsTitle = $.inArray( 'image', $.wikiLove.types[$.wikiLove.currentTypeId].fields );
269 - if( typeof $.wikiLove.currentTypeOrSubtype.image == 'string' || needsTitle == -1 ) {
270 - $( '#wlImageLabel').hide();
271 - $( '#wlImage' ).hide();
272 - $( '#wlImage' ).val( $.wikiLove.currentTypeOrSubtype.image );
273 - } else if ( needsTitle != -1 ) {
 242+ if( $.inArray( 'image', $.wikiLove.currentTypeOrSubtype.fields ) >= 0 ) {
274243 $( '#wlImageLabel').show();
275244 $( '#wlImage' ).show();
276 - $( '#wlImage' ).val( '' );
 245+ } else {
 246+ $( '#wlImageLabel').hide();
 247+ $( '#wlImage' ).hide();
277248 }
 249+ $( '#wlImage' ).val( $.wikiLove.currentTypeOrSubtype.image || '' );
278250
279251 if( typeof $.wikiLove.currentTypeOrSubtype.gallery == 'object' ) {
280252 $( '#wlGalleryLabel' ).show();
@@ -287,7 +259,7 @@
288260 $( '#wlGallerySpinner' ).hide();
289261 }
290262
291 - if( $.wikiLove.types[$.wikiLove.currentTypeId].showNotify ) {
 263+ if( $.inArray( 'notify', $.wikiLove.currentTypeOrSubtype.fields ) >= 0 && $.wikiLove.emailable ) {
292264 $( '#wlNotify' ).show();
293265 } else {
294266 $( '#wlNotify' ).hide();
@@ -320,13 +292,8 @@
321293 $.wikiLove.showError( 'wikilove-err-sig' ); return false;
322294 }
323295
324 - if ( $.wikiLove.currentTypeOrSubtype.text ) {
325 - var text = $.wikiLove.currentTypeOrSubtype.text;
326 - } else {
327 - var text = $.wikiLove.defaultText;
328 - }
329296 var msg = $.wikiLove.prepareMsg(
330 - text,
 297+ $.wikiLove.currentTypeOrSubtype.text || $.wikiLove.defaultText,
331298 $.wikiLove.currentTypeOrSubtype.imageSize,
332299 $.wikiLove.currentTypeOrSubtype.backgroundColor,
333300 $.wikiLove.currentTypeOrSubtype.borderColor
@@ -337,14 +304,17 @@
338305 'header': $( '#wlHeader' ).val(),
339306 'msg': msg,
340307 'type': $.wikiLove.currentTypeId
341 - + ($.wikiLove.currentSubtypeId != null ? '-' + $.wikiLove.currentSubtypeId : ''),
342 - 'notify': $( '#wlNotifyCheckbox:checked' ).val()
 308+ + ($.wikiLove.currentSubtypeId !== null ? '-' + $.wikiLove.currentSubtypeId : ''),
343309 };
 310+
 311+ if ( $( '#wlNotifyCheckbox:checked' ).val() && $.wikiLove.emailable ) {
 312+ $.wikiLove.previewData.mail = $.wikiLove.prepareMsg( $.wikiLove.currentTypeOrSubtype.mail );
 313+ }
344314 return false;
345315 },
346316
347317 showError: function( errmsg ) {
348 - $( '#wlAddDetails' ).append( $( '<div class="wlError"></div>' ).html( mw.msg( errmsg ) ) );
 318+ $( '#wlAddDetails' ).append( $( '<div class="wlError"></div>' ).text( mw.msg( errmsg ) ) );
349319 },
350320
351321 /*
@@ -363,21 +333,10 @@
364334 msg = msg.replace( '$2', $( '#wlTitle' ).val() ); // replace the title
365335 msg = msg.replace( '$3', $( '#wlImage' ).val() ); // replace the image
366336
367 - if ( imageSize ) {
368 - var myImageSize = imageSize;
369 - } else {
370 - var myImageSize = $.wikiLove.defaultImageSize;
371 - }
372 - if ( backgroundColor ) {
373 - var myBackgroundColor = backgroundColor;
374 - } else {
375 - var myBackgroundColor = $.wikiLove.defaultBackgroundColor;
376 - }
377 - if ( borderColor ) {
378 - var myBorderColor = borderColor;
379 - } else {
380 - var myBorderColor = $.wikiLove.defaultBorderColor;
381 - }
 337+ var myImageSize = imageSize || $.wikiLove.defaultImageSize;
 338+ var myBackgroundColor = backgroundColor || $.wikiLove.defaultBackgroundColor;
 339+ var myBorderColor = borderColor || $.wikiLove.defaultBorderColor;
 340+
382341 msg = msg.replace( '$4', myImageSize ); // replace the image size
383342 msg = msg.replace( '$5', myBackgroundColor ); // replace the background color
384343 msg = msg.replace( '$6', myBorderColor ); // replace the border color
@@ -433,33 +392,33 @@
434393 /*
435394 * Fires the final AJAX request and then redirects to the talk page where the content is added.
436395 */
437 - doSend: function( subject, wikitext, type, notify ) {
 396+ doSend: function( subject, wikitext, type, mail ) {
438397 $( '#wlPreview .wlSpinner' ).fadeIn( 200 );
 398+
 399+ var sendData = {
 400+ 'action': 'wikilove',
 401+ 'format': 'json',
 402+ 'title': mw.config.get( 'wgPageName' ),
 403+ 'type': type,
 404+ 'text': wikitext,
 405+ 'subject': subject,
 406+ 'token': mw.user.tokens.get( 'editToken' )
 407+ };
 408+
 409+ if ( mail ) {
 410+ sendData.email = mail;
 411+ }
 412+
439413 $.ajax({
440414 url: mw.config.get( 'wgServer' ) + mw.config.get( 'wgScriptPath' ) + '/api.php?',
441 - data: {
442 - 'action': 'wikiLove',
443 - 'format': 'json',
444 - 'title': mw.config.get( 'wgPageName' ),
445 - 'type': type,
446 - 'text': wikitext,
447 - 'subject': subject,
448 - 'token': mw.user.tokens.get( 'editToken' )
449 - },
 415+ data: sendData,
450416 dataType: 'json',
451417 type: 'POST',
452418 success: function( data ) {
453 - if ( notify && $.wikiLove.emailable && typeof $.wikiLove.currentTypeOrSubtype.mail != 'undefined' ) {
454 - $.wikiLove.sendEmail(
455 - $.wikiLove.currentTypeOrSubtype.title,
456 - $.wikiLove.prepareMsg( $.wikiLove.currentTypeOrSubtype.mail )
457 - );
458 - }
459 -
460419 $( '#wlPreview .wlSpinner' ).fadeOut( 200 );
461420
462421 if ( typeof data.error !== 'undefined' ) {
463 - $( '#wlPreview' ).append( '<div class="wlError">' + data.error.info + '<div>' );
 422+ $( '#wlPreview' ).append( '<div class="wlError">' + mw.html.escape( data.error.info ) + '<div>' );
464423 return;
465424 }
466425
@@ -471,8 +430,8 @@
472431 window.location.reload();
473432 }
474433 else {
475 - window.location = mw.config.get( 'wgArticlePath' ).replace('$1', data.redirect.pageName)
476 - + data.redirect.fragment;
 434+ window.location = mw.config.get( 'wgArticlePath' ).replace( '$1', data.redirect.pageName )
 435+ + '#' + data.redirect.fragment;
477436 }
478437 }
479438 });
@@ -530,7 +489,7 @@
531490 // only add the image if it's actually an image
532491 if( page.imageinfo[0].mime.substr(0,5) == 'image' ) {
533492 // build an image tag with the correct url and width
534 - $img = $( '<img/>' )
 493+ var $img = $( '<img/>' )
535494 .attr( 'src', page.imageinfo[0].url )
536495 .attr( 'width', $.wikiLove.currentTypeOrSubtype.gallery.width )
537496 .hide()
@@ -578,5 +537,6 @@
579538 });
580539 }
581540 };
582 -$.wikiLove.init();
 541+
 542+$( document ).ready( $.wikiLove.init );
583543 } ) ( jQuery );
Index: trunk/extensions/WikiLove/WikiLove.api.php
@@ -7,16 +7,16 @@
88
99 $title = Title::newFromText( $params['title'] );
1010 if ( is_null( $title ) ) {
11 - $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
 11+ $this->dieUsageMsg( array( 'invaliduser', $params['title'] ) );
1212 }
1313
1414 $talk = WikiLoveHooks::getUserTalkPage( $title );
1515 if ( is_null( $talk ) ) {
16 - $this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
 16+ $this->dieUsageMsg( array( 'invaliduser', $params['title'] ) );
1717 }
1818
1919 if ( $wgWikiLoveLogging ) {
20 - $this->saveInDb( $talk, $params['subject'], $params['text'], $params['type'], $params['template'] );
 20+ $this->saveInDb( $talk, $params['subject'], $params['text'], $params['type'], isset( $params['email'] ) ? 1 : 0 );
2121 }
2222
2323 $api = new ApiMain( new FauxRequest( array(
@@ -28,15 +28,19 @@
2929 'summary' => $params['subject'],
3030 'notminor' => true,
3131 ), false, array( 'wsEditToken' => $wgRequest->getSessionData( 'wsEditToken' ) ) ), true );
 32+
 33+ if ( isset( $params['email'] ) ) {
 34+ $this->emailUser( $talk, $params['subject'], $params['email'] );
 35+ }
3236
3337 $api->execute();
3438
3539 $result = $api->getResult();
3640 $data = $result->getData();
3741
38 - $talk->setFragment( '#' . $params['subject'] );
3942 $this->getResult()->addValue( 'redirect', 'pageName', $talk->getPrefixedDBkey() );
40 - $this->getResult()->addValue( 'redirect', 'fragment', $talk->getFragmentForURL() );
 43+ $this->getResult()->addValue( 'redirect', 'fragment', Title::escapeFragmentForURL( $params['subject'] ) );
 44+ // note that we cannot use Title::makeTitle here as it doesn't sanitize the fragment
4145 }
4246
4347 /**
@@ -46,25 +50,38 @@
4751 * @param $type
4852 * @return void
4953 */
50 - private function saveInDb( $talk, $subject, $text, $type, $template ) {
 54+ private function saveInDb( $talk, $subject, $text, $type, $email ) {
5155 global $wgUser;
5256 $dbw = wfGetDB( DB_MASTER );
5357 $values = array(
54 - 'wl_timestamp' => $dbw->timestamp(),
55 - 'wl_sender_id' => $wgUser->getId(),
56 - 'wl_receiver_id' => User::newFromName( $talk->getSubjectPage()->getBaseText() )->getId(),
57 - 'wl_type' => $type,
58 - 'wl_subject' => $subject,
59 - 'wl_message' => $text,
60 - 'wl_email' => 0,
 58+ 'wll_timestamp' => $dbw->timestamp(),
 59+ 'wll_sender' => $wgUser->getId(),
 60+ 'wll_receiver' => User::newFromName( $talk->getSubjectPage()->getBaseText() )->getId(),
 61+ 'wll_type' => $type,
 62+ 'wll_subject' => $subject,
 63+ 'wll_message' => $text,
 64+ 'wll_email' => $email,
6165 );
6266 try{
6367 $dbw->insert( 'wikilove_log', $values, __METHOD__ );
6468 } catch( DBQueryError $dbqe ) {
65 - $this->dieUsage( 'Warning: action was not logged!', 'nologging' );
66 - return false;
 69+ $this->setWarning( 'Action was not logged' );
6770 }
6871 }
 72+
 73+ private function emailUser( $talk, $subject, $text ) {
 74+ $api = new ApiMain( new FauxRequest( array(
 75+ 'action' => 'emailuser',
 76+ 'target' => User::newFromName( $talk->getSubjectPage()->getBaseText() )->getName(),
 77+ 'subject' => $subject,
 78+ 'text' => $text,
 79+ ), false, array( 'wsEditToken' => $wgRequest->getSessionData( 'wsEditToken' ) ) ), true );
 80+ try{
 81+ $api->execute();
 82+ } catch( DBQueryError $dbqe ) {
 83+ $this->setWarning( 'E-mail was not sent' );
 84+ }
 85+ }
6986
7087 public function getAllowedParams() {
7188 return array(
@@ -87,6 +104,9 @@
88105 'type' => array(
89106 ApiBase::PARAM_TYPE => 'string',
90107 ),
 108+ 'email' => array(
 109+ ApiBase::PARAM_TYPE => 'string',
 110+ ),
91111 );
92112 }
93113
@@ -125,7 +145,7 @@
126146
127147 public function getExamples() {
128148 return array(
129 - 'api.php?action=wikiLove&title=User:Dummy&text=Love&subject=Hi&token=%2B\\',
 149+ 'api.php?action=wikilove&title=User:Dummy&text=Love&subject=Hi&token=%2B\\',
130150 );
131151 }
132152
Index: trunk/extensions/WikiLove/patches/WikiLoveLog.sql
@@ -1,15 +1,24 @@
22 --
33 -- WikiLove logging schema
 4+-- Logs all actions of giving WikiLove.
45 -- Not final, please apply this patch manually for now!
56 --
67
78 CREATE TABLE IF NOT EXISTS /*_*/wikilove_log (
8 - `wl_id` int NOT NULL PRIMARY KEY auto_increment,
9 - `wl_timestamp` binary(14) NOT NULL,
10 - `wl_sender_id` int(11) NOT NULL,
11 - `wl_receiver_id` int(11) NOT NULL,
12 - `wl_type` varchar(64) NOT NULL,
13 - `wl_subject` varchar(255) NOT NULL,
14 - `wl_message` blob NOT NULL,
15 - `wl_email` bool NOT NULL default '0'
 9+ wll_id int NOT NULL PRIMARY KEY auto_increment, -- unique id
 10+ wll_timestamp binary(14) NOT NULL, -- timestamp
 11+ wll_sender int(11) NOT NULL, -- user id of the sender
 12+ wll_receiver int(11) NOT NULL, -- user id of the receiver
 13+ wll_type varchar(64) NOT NULL, -- type (and subtype) of message
 14+ wll_subject varchar(255) NOT NULL, -- subject line
 15+ wll_message blob NOT NULL, -- actual message
 16+ wll_email bool NOT NULL default '0' -- whether or not a notification mail has been sent
1617 ) /*$wgDBTableOptions*/;
 18+
 19+CREATE INDEX /*i*/wll_timestamp ON /*_*/wikilove_log (wll_timestamp);
 20+CREATE INDEX /*i*/wll_type_time ON /*_*/wikilove_log (wll_type, wll_timestamp);
 21+CREATE INDEX /*i*/wll_sender_time ON /*_*/wikilove_log (wll_sender, wll_timestamp);
 22+CREATE INDEX /*i*/wll_receiver_time ON /*_*/wikilove_log (wll_receiver, wll_timestamp);
 23+-- ASSUMPTION: once narrowed down to a single user (sender/receiver), we can afford a filesort
 24+-- as a single users will have only limited WikiLove messages from or to him/her. It's not worth
 25+-- the memory of extra indexes to cover all the combinations (sender/receiver/type => 8 indexes)
Index: trunk/extensions/WikiLove/WikiLove.i18n.php
@@ -31,6 +31,7 @@
3232 'wikilove-omit-sig' => '(without a signature)',
3333 'wikilove-button-preview' => 'Preview',
3434 'wikilove-preview' => 'Preview',
 35+ 'wikilove-notify' => 'Notify the user by e-mail',
3536 'wikilove-button-send' => 'Send WikiLove',
3637 'wikilove-type-makeyourown' => 'Make your own',
3738 'wikilove-err-header' => 'Please enter a header.',
@@ -38,9 +39,6 @@
3940 'wikilove-err-msg' => 'Please enter a message.',
4041 'wikilove-err-image' => 'Please select an image.',
4142 'wikilove-err-sig' => 'Please do not include a signature in the message.',
42 -
43 - // messages for default types
44 - 'wikilove-barnstar-header' => 'A barnstar for you!',
4543 );
4644
4745 /** Message documentation (Message documentation)

Follow-up revisions

RevisionCommit summaryAuthorDate
r88701Quick followup to r88699, forgot to remove var mw; at the top which I added f...janpaul12322:50, 23 May 2011
r88703Followup to r88699, fix by Krinklejanpaul12323:08, 23 May 2011

Comments

#Comment by Jorm (WMF) (talk | contribs)   22:48, 23 May 2011

I'm getting "Uncaught TypeError: Cannot read property 'config' of undefined" when trying to fire the dialog.

#Comment by JanPaul123 (talk | contribs)   22:51, 23 May 2011

Tnx, fixed in r88701.

#Comment by Krinkle (talk | contribs)   23:02, 23 May 2011
 			'msg': msg,
 			'type': $.wikiLove.currentTypeId
-				+ ($.wikiLove.currentSubtypeId != null ? '-' + $.wikiLove.currentSubtypeId : ''),
-			'notify': $( '#wlNotifyCheckbox:checked' ).val()
+				+ ($.wikiLove.currentSubtypeId !== null ? '-' + $.wikiLove.currentSubtypeId : ''),
 		};

This leaves:

		$.wikiLove.previewData = {
			'header': $( '#wlHeader' ).val(),
			'msg': msg,
			'type': $.wikiLove.currentTypeId
				+ ($.wikiLove.currentSubtypeId !== null ? '-' + $.wikiLove.currentSubtypeId : ''),
		};

Trailing comma's are ignored in WebKit browsers and (like in PHP), but strictly speaking (as seen in IE), this breaks and causes an exception or syntax error.

#Comment by JanPaul123 (talk | contribs)   23:09, 23 May 2011

Thanks! I must've overlooked that one, in all other places there's no trailing comma. Fixed in r88703.

#Comment by Krinkle (talk | contribs)   00:11, 1 June 2011
+					window.location = mw.config.get( 'wgArticlePath' ).replace( '$1', data.redirect.pageName ) 

May wanna use mw.util.wikiGetlink( data.redirect.pageName ); for convenience.

Marking OK.

Status & tagging log