r108187 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r108186‎ | r108187 | r108188 >
Date:00:05, 6 January 2012
Author:bsitu
Status:resolved (Comments)
Tags:
Comment:
Adding "Show unanswered" filter to feedback dashboard
Modified paths:
  • /trunk/extensions/MoodBar/ApiQueryMoodBarComments.php (modified) (history)
  • /trunk/extensions/MoodBar/MoodBar.i18n.php (modified) (history)
  • /trunk/extensions/MoodBar/SpecialFeedbackDashboard.php (modified) (history)
  • /trunk/extensions/MoodBar/modules/ext.moodBar.dashboard/ext.moodBar.dashboard.js (modified) (history)

Diff [purge]

Index: trunk/extensions/MoodBar/SpecialFeedbackDashboard.php
@@ -49,8 +49,13 @@
5050 if ( count( $filters ) ) {
5151 $filterType = 'filtered';
5252 }
53 -
54 - $filters['myresponse'] = $wgRequest->getVal( 'myresponse' );
 53+
 54+ // UI should allow users to select one or none
 55+ if ( $wgRequest->getVal( 'myresponse' ) == '1' ) {
 56+ $filters['responsefilter'] = 'myresponse';
 57+ } elseif ( $wgRequest->getVal( 'showunanswered' ) == '1' ) {
 58+ $filters['responsefilter'] = 'showunanswered';
 59+ }
5560 }
5661 // Do the query
5762 $backwards = $wgRequest->getVal( 'dir' ) === 'prev';
@@ -141,11 +146,19 @@
142147 if ( !$wgUser->isAnon() ) {
143148 $myResponseMsg = wfMessage( 'moodbar-feedback-filters-my-response' )->escaped();
144149 $myResponseCheckbox = Xml::check( 'myresponse', $wgRequest->getCheck( 'myresponse' ),
145 - array( 'id' => 'fbd-filters-my-response', 'value' => '1' ) );
 150+ array( 'id' => 'fbd-filters-my-response', 'value' => '1' ) );
146151
147152 $myResponseFilter = '<label for="fbd-filters-my-response" id="fbd-filters-type-my-response-label" class="fbd-filters-label">' .
148 - $myResponseCheckbox . $myResponseMsg . '</label>';
 153+ $myResponseCheckbox . $myResponseMsg . '</label>';
149154 }
 155+
 156+ // Show unanswered filter
 157+ $showUnansweredMsg = wfMessage( 'moodbar-feedback-filters-show-unanswered' )->escaped();
 158+ $showUnansweredCheckbox = Xml::check( 'showunanswered', $wgRequest->getCheck( 'showunanswered' ),
 159+ array( 'id' => 'fbd-filters-show-unanswered', 'value' => '1' ) );
 160+
 161+ $showUnansweredFilter = '<label for="fbd-filters-show-unanswered" id="fbd-filters-type-show-unanswered-label" class="fbd-filters-label">' .
 162+ $showUnansweredCheckbox . $showUnansweredMsg . '</label>';
150163
151164 return <<<HTML
152165 <div id="fbd-description">
@@ -179,6 +192,7 @@
180193 <label for="fbd-filters-username" class="fbd-filters-label">$usernameMsg</label>
181194 $usernameTextbox
182195 $myResponseFilter
 196+ $showUnansweredFilter
183197 <button type="submit" id="fbd-filters-set">$setFiltersMsg</button>
184198 </form>
185199 <a href="$whatIsURL" id="fbd-about">$whatIsMsg</a>
@@ -585,12 +599,25 @@
586600 $option = array( 'LIMIT' => $limit + 2, 'ORDER BY' => "mbf_timestamp$desc, mbf_id$desc" );
587601 $tableJoin = array( 'user' => array( 'LEFT JOIN', 'user_id=mbf_user_id' ) );
588602
589 - //View my response
590 - if ( isset( $filters['myresponse'] ) && $filters['myresponse'] == '1' && !$wgUser->isAnon() ) {
591 - $table[] = 'moodbar_feedback_response';
592 - $option['GROUP BY'] = 'mbf_id';
593 - $tableJoin['moodbar_feedback_response'] = array( 'INNER JOIN', 'mbf_id=mbfr_mbf_id' );
594 - $conds['mbfr_user_id'] = $wgUser->getId();
 603+
 604+ // View my response or unanswered feedback
 605+ if ( isset( $filters['responsefilter'] ) ) {
 606+ switch ( $filters['responsefilter'] ) {
 607+ case 'myresponse':
 608+ if ( !$wgUser->isAnon() ) {
 609+ $table[] = 'moodbar_feedback_response';
 610+ $option['GROUP BY'] = 'mbf_id';
 611+ $tableJoin['moodbar_feedback_response'] = array( 'INNER JOIN', 'mbf_id=mbfr_mbf_id' );
 612+ $conds['mbfr_user_id'] = $wgUser->getId();
 613+ }
 614+ break;
 615+
 616+ case 'showunanswered':
 617+ $table[] = 'moodbar_feedback_response';
 618+ $tableJoin['moodbar_feedback_response'] = array( 'LEFT JOIN', 'mbf_id=mbfr_mbf_id' );
 619+ $conds['mbfr_id'] = null;
 620+ break;
 621+ }
595622 }
596623
597624 $res = $dbr->select( $table, array(
Index: trunk/extensions/MoodBar/MoodBar.i18n.php
@@ -110,6 +110,7 @@
111111 'moodbar-feedback-filters-type-sad' => 'Sad',
112112 'moodbar-feedback-filters-username' => 'Username:',
113113 'moodbar-feedback-filters-my-response' => 'My responses only',
 114+ 'moodbar-feedback-filters-show-unanswered' => 'Show unanswered',
114115 'moodbar-feedback-filters-button' => 'Set filters',
115116 'moodbar-feedback-whatis' => 'What is this feature?',
116117 'moodbar-feedback-permalink' => 'link to here',
@@ -290,6 +291,7 @@
291292 'moodbar-feedback-filters-type-sad' => 'Used on Special:FeedbackDashboard to filter by "sad" feedback entries',
292293 'moodbar-feedback-filters-username' => '{{Identical|Username}}',
293294 'moodbar-feedback-filters-my-response' => 'Used on SpecialFeedbackDashboard to filter by "My responses only" feedback entries. A checkbox comes right before the text.',
 295+ 'moodbar-feedback-filters-show-unanswered' => 'Used on SpecialFeedbackDashboard to filter by "Show unanswered" feedback entries',
294296 'moodbar-feedback-more' => 'Text of the link that the user can click to see more results. Only visible if JavaScript is enabled.
295297 {{Identical|More}}',
296298 'moodbar-feedback-newer' => 'Text of the link that the user can click to go back to more recent results. Only visible if JavaScript is not enabled.',
Index: trunk/extensions/MoodBar/ApiQueryMoodBarComments.php
@@ -38,11 +38,18 @@
3939 $this->addWhereRange( 'mbf_id', $params['dir'], null, null );
4040 $this->addOption( 'LIMIT', $params['limit'] + 1 );
4141
42 - if ( $params['myresponse'] == '1' && !$wgUser->isAnon() ) {
 42+
 43+ if ( $params['myresponse'] == '1' ) {
 44+ if ( !$wgUser->isAnon() ) {
 45+ $this->addTables( array( 'moodbar_feedback_response' ) );
 46+ $this->addJoinConds( array( 'moodbar_feedback_response' => array( 'INNER JOIN', 'mbf_id=mbfr_mbf_id' ) ) );
 47+ $this->addWhereFld( 'mbfr_user_id', $wgUser->getId() );
 48+ $this->addOption( 'GROUP BY', 'mbf_id' );
 49+ }
 50+ } elseif ( $params['showunanswered'] == '1' ) {
4351 $this->addTables( array( 'moodbar_feedback_response' ) );
44 - $this->addJoinConds( array( 'moodbar_feedback_response' => array( 'INNER JOIN', 'mbf_id=mbfr_mbf_id' ) ) );
45 - $this->addWhereFld( 'mbfr_user_id', $wgUser->getId() );
46 - $this->addOption( 'GROUP BY', 'mbf_id' );
 52+ $this->addJoinConds( array( 'moodbar_feedback_response' => array( 'LEFT JOIN', 'mbf_id=mbfr_mbf_id' ) ) );
 53+ $this->addWhere( array( 'mbfr_id' => null ) );
4754 }
4855
4956 if ( ! $wgUser->isAllowed( 'moodbar-admin' ) ) {
@@ -164,8 +171,11 @@
165172 ApiBase::PARAM_TYPE => 'user',
166173 ),
167174 'myresponse' => array(
168 - ApiBase::PARAM_TYPE => array( '1' , '0' ),
 175+ ApiBase::PARAM_TYPE => array( '1', '0' ),
169176 ),
 177+ 'showunanswered' => array(
 178+ ApiBase::PARAM_TYPE => array( '1', '0' ),
 179+ ),
170180 'prop' => array(
171181 ApiBase::PARAM_TYPE => array( 'metadata', 'formatted', 'hidden' ),
172182 ApiBase::PARAM_DFLT => 'metadata',
@@ -185,6 +195,7 @@
186196 'type' => 'Only return comments of the given type(s). If not set or empty, return all comments',
187197 'user' => 'Only return comments submitted by the given user',
188198 'myresponse' => 'Only return comments to which the current user has responded',
 199+ 'showunanswered' => 'Only return comments to which no one has responded',
189200 'prop' => array( 'Which properties to get:',
190201 ' metadata - Comment ID, type, timestamp, user',
191202 ' formatted - HTML that would be displayed for this comment on Special:MoodBarFeedback',
Index: trunk/extensions/MoodBar/modules/ext.moodBar.dashboard/ext.moodBar.dashboard.js
@@ -5,7 +5,7 @@
66 /**
77 * Saved form state
88 */
9 - var formState = { types: [], username: '', myresponse: '0' };
 9+ var formState = { types: [], username: '', myresponse: '0', showunanswered: '0' };
1010
1111 /**
1212 * Save the current form state to formState
@@ -14,6 +14,7 @@
1515 formState.types = getSelectedTypes();
1616 formState.username = $( '#fbd-filters-username' ).val();
1717 formState.myresponse = $( '#fbd-filters-my-response' ).prop( 'checked' ) ? $( '#fbd-filters-my-response' ).val() : '0';
 18+ formState.showunanswered = $( '#fbd-filters-show-unanswered' ).prop( 'checked' ) ? $( '#fbd-filters-show-unanswered' ).val() : '0';
1819 }
1920
2021 /**
@@ -135,6 +136,9 @@
136137 if ( formState.myresponse != '0' ) {
137138 reqData.mbcmyresponse = formState.myresponse;
138139 }
 140+ if ( formState.showunanswered != '0' ) {
 141+ reqData.mbcshowunanswered = formState.showunanswered;
 142+ }
139143
140144 $.ajax( {
141145 'url': mw.util.wikiScript( 'api' ),

Sign-offs

UserFlagDate
Johnduhartinspected19:41, 7 January 2012

Follow-up revisions

RevisionCommit summaryAuthorDate
r108454followup to -r108187 - Checking isset instead of 1/0 for checkbox, adding myr...bsitu18:45, 9 January 2012
r108535followup to -r108187 - move checkbox outside of label, remove INNER JOIN and ...bsitu19:33, 10 January 2012
r108539followup to -r108187 - Add mbfr_user_id as index for my response filterbsitu19:59, 10 January 2012
r108556followup to -r108187 - Introducing new field mbf_latest_response for latest f...bsitu22:42, 10 January 2012

Comments

#Comment by Johnduhart (talk | contribs)   19:43, 7 January 2012

API code looks fine however,

+				ApiBase::PARAM_TYPE => array( '1', '0' ),

Instead of having a 0/1 parameter, make it so that it works based on if the parameter is set (This is how it's usually done)

#Comment by Catrope (talk | contribs)   16:02, 10 January 2012
+		$showUnansweredFilter = '<label for="fbd-filters-show-unanswered" id="fbd-filters-type-show-unanswered-label" class="fbd-filters-label">' . 
+								$showUnansweredCheckbox . $showUnansweredMsg . '</label>';

Why is the checkbox inside the label tag like that, shouldn't it be before it?

+						$conds['mbfr_user_id'] = $wgUser->getId();

There is no index on this field at all, please make sure the query is properly indexed.

+					$tableJoin['moodbar_feedback_response'] = array( 'LEFT JOIN', 'mbf_id=mbfr_mbf_id' );
+					$conds['mbfr_id'] = null; 

This isn't a very nice query, it does a full table scan on moodbar_feedback. It would be nicer to have a boolean mbf_answered field.

Pro tip: you don't need to specify join conds for INNER JOINs, you can specify those implicitly by just adding 'mbf_id=mbfr_mbf_id' as a WHERE condition.

John's right, the API offers boolean parameters (based on presence/absence). You can specify these with 'showunanswered' => false, .

#Comment by Bsitu (talk | contribs)   17:41, 10 January 2012

Forget to add the index, :(

Status & tagging log