Index: trunk/extensions/ArticleFeedbackv5/sql/alter.sql |
— | — | @@ -122,3 +122,6 @@ |
123 | 123 | ALTER TABLE /*_*/aft_article_feedback ADD COLUMN af_net_helpfulness integer NOT NULL DEFAULT 0; |
124 | 124 | CREATE INDEX /*i*/af_net_helpfulness ON /*_*/aft_article_feedback (af_net_helpfulness); |
125 | 125 | UPDATE aft_article_feedback SET af_net_helpfulness = CONVERT(af_helpful_count, SIGNED) - CONVERT(af_unhelpful_count, SIGNED); |
| 126 | + |
| 127 | +-- Added 2/1 (greg) |
| 128 | +CREATE INDEX /*_*/af_net_helpfulness_af_id ON /*_*/aft_article_feedback (af_id, af_net_helpfulness); |
Index: trunk/extensions/ArticleFeedbackv5/modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.special.js |
— | — | @@ -51,7 +51,8 @@ |
52 | 52 | sort: 'age', |
53 | 53 | sortDirection: 'desc', |
54 | 54 | limit: 25, |
55 | | - continue: null |
| 55 | + continue: null, |
| 56 | + continueId: null // Sort of a tie-breaker for continue values. |
56 | 57 | }; |
57 | 58 | |
58 | 59 | /** |
— | — | @@ -110,8 +111,9 @@ |
111 | 112 | */ |
112 | 113 | $.articleFeedbackv5special.setBinds = function() { |
113 | 114 | $( '#articleFeedbackv5-filter-select' ).bind( 'change', function( e ) { |
114 | | - $.articleFeedbackv5special.listControls.filter = $(this).val(); |
115 | | - $.articleFeedbackv5special.listControls.continue = null; |
| 115 | + $.articleFeedbackv5special.listControls.filter = $(this).val(); |
| 116 | + $.articleFeedbackv5special.listControls.continue = null; |
| 117 | + $.articleFeedbackv5special.listControls.continueId = null; |
116 | 118 | $.articleFeedbackv5special.loadFeedback( true ); |
117 | 119 | return false; |
118 | 120 | } ); |
— | — | @@ -121,8 +123,9 @@ |
122 | 124 | oldId = $.articleFeedbackv5special.listControls.sort; |
123 | 125 | |
124 | 126 | // set direction = desc... |
125 | | - $.articleFeedbackv5special.listControls.sort = id; |
126 | | - $.articleFeedbackv5special.listControls.continue = null; |
| 127 | + $.articleFeedbackv5special.listControls.sort = id; |
| 128 | + $.articleFeedbackv5special.listControls.continue = null; |
| 129 | + $.articleFeedbackv5special.listControls.continueId = null; |
127 | 130 | |
128 | 131 | // unless we're flipping the direction on the current sort. |
129 | 132 | if( id == oldId && $.articleFeedbackv5special.listControls.sortDirection == 'desc' ) { |
— | — | @@ -148,6 +151,7 @@ |
149 | 152 | $.articleFeedbackv5special.listControls.filter = 'id'; |
150 | 153 | $.articleFeedbackv5special.listControls.filterValue = id; |
151 | 154 | $.articleFeedbackv5special.listControls.continue = null; |
| 155 | + $.articleFeedbackv5special.listControls.continueId = null; |
152 | 156 | $.articleFeedbackv5special.loadFeedback( true ); |
153 | 157 | } ); |
154 | 158 | |
— | — | @@ -579,6 +583,7 @@ |
580 | 584 | 'afvfsortdirection' : $.articleFeedbackv5special.listControls.sortDirection, |
581 | 585 | 'afvflimit' : $.articleFeedbackv5special.listControls.limit, |
582 | 586 | 'afvfcontinue' : $.articleFeedbackv5special.listControls.continue, |
| 587 | + 'afvfcontinueid' : $.articleFeedbackv5special.listControls.continueId, |
583 | 588 | 'action' : 'query', |
584 | 589 | 'format' : 'json', |
585 | 590 | 'list' : 'articlefeedbackv5-view-feedback', |
— | — | @@ -617,7 +622,8 @@ |
618 | 623 | } |
619 | 624 | } ); |
620 | 625 | $( '#articleFeedbackv5-feedback-count-total' ).text( data['articlefeedbackv5-view-feedback'].count ); |
621 | | - $.articleFeedbackv5special.listControls.continue = data['articlefeedbackv5-view-feedback'].continue; |
| 626 | + $.articleFeedbackv5special.listControls.continue = data['articlefeedbackv5-view-feedback'].continue; |
| 627 | + $.articleFeedbackv5special.listControls.continueId = data['articlefeedbackv5-view-feedback'].continueid; |
622 | 628 | } else { |
623 | 629 | $( '#articleFeedbackv5-show-feedback' ).text( mw.msg( 'articlefeedbackv5-error-loading-feedback' ) ); |
624 | 630 | } |
Index: trunk/extensions/ArticleFeedbackv5/api/ApiViewFeedbackArticleFeedbackv5.php |
— | — | @@ -14,7 +14,8 @@ |
15 | 15 | * @subpackage Api |
16 | 16 | */ |
17 | 17 | class ApiViewFeedbackArticleFeedbackv5 extends ApiQueryBase { |
18 | | - private $continue; |
| 18 | + private $continue = null; |
| 19 | + private $continueId = null; |
19 | 20 | |
20 | 21 | /** |
21 | 22 | * Constructor |
— | — | @@ -40,21 +41,23 @@ |
41 | 42 | $params['sort'], |
42 | 43 | $params['sortdirection'], |
43 | 44 | $params['limit'], |
44 | | - ( $params['continue'] !== 'null' ? $params['continue'] : null ) |
| 45 | + ( $params['continue'] !== 'null' ? $params['continue'] : null ), |
| 46 | + ( $params['continueid'] !== 'null' ? $params['continueid'] : null ) |
45 | 47 | ); |
46 | 48 | foreach ( $feedback as $record ) { |
47 | 49 | $html .= $this->renderFeedback( $record ); |
48 | 50 | $length++; |
49 | 51 | } |
50 | 52 | |
51 | | - $continue = $this->continue; |
52 | | - |
53 | 53 | $result->addValue( $this->getModuleName(), 'length', $length ); |
54 | 54 | $result->addValue( $this->getModuleName(), 'count', $count ); |
| 55 | + if ( $this->continue !== null ) { |
| 56 | + $result->addValue( $this->getModuleName(), 'continue', $this->continue ); |
| 57 | + } |
| 58 | + if ( $this->continueId ) { |
| 59 | + $result->addValue( $this->getModuleName(), 'continueid', $this->continueId ); |
| 60 | + } |
55 | 61 | $result->addValue( $this->getModuleName(), 'feedback', $html ); |
56 | | - if ( $continue ) { |
57 | | - $result->addValue( $this->getModuleName(), 'continue', $continue ); |
58 | | - } |
59 | 62 | } |
60 | 63 | |
61 | 64 | public function fetchFeedbackCount( $pageId ) { |
— | — | @@ -74,7 +77,7 @@ |
75 | 78 | |
76 | 79 | public function fetchFeedback( $pageId, $filter = 'visible', |
77 | 80 | $filterValue = null, $sort = 'age', $sortOrder = 'desc', |
78 | | - $limit = 25, $continue = null ) { |
| 81 | + $limit = 25, $continue = null, $continueId ) { |
79 | 82 | $dbr = wfGetDB( DB_SLAVE ); |
80 | 83 | $ids = array(); |
81 | 84 | $rows = array(); |
— | — | @@ -103,28 +106,37 @@ |
104 | 107 | // Build ORDER BY clause. |
105 | 108 | switch( $sort ) { |
106 | 109 | case 'helpful': |
107 | | - $sortField = 'af_net_helpfulness'; |
| 110 | + $sortField = 'af_net_helpfulness'; |
| 111 | + $order = "af_net_helpfulness $direction, af_id $direction"; |
| 112 | + $continueSql = "(af_net_helpfulness $continueDirection ".intVal( $continue ) |
| 113 | + ." OR (af_net_helpfulness = ".intVal( $continue ) |
| 114 | + ." AND af_id $continueDirection ".intval( $continueId ).") )"; |
108 | 115 | break; |
109 | 116 | case 'rating': |
110 | | - $sortField = 'rating'; |
| 117 | + # TODO: null ratings don't seem to show up at all. Need to sort that one out. |
| 118 | + $sortField = 'rating'; |
| 119 | + $order = "rating $direction, af_id $direction"; |
| 120 | + $continueSql = "(rating.aa_response_boolean $continueDirection ".intVal( $continue ) |
| 121 | + ." OR (rating.aa_response_boolean = ".intVal( $continue ) |
| 122 | + ." AND af_id $continueDirection ".intval( $continueId ).") )"; |
111 | 123 | break; |
112 | 124 | case 'age': |
113 | 125 | # Default field, fall through |
114 | 126 | default: |
115 | | - $sortField = 'af_id'; |
| 127 | + $sortField = 'af_id'; |
| 128 | + $order = "af_id $direction"; |
| 129 | + $continueSql = "af_id < ".intVal( $continue ); |
116 | 130 | break; |
117 | 131 | } |
118 | | - $order = "$sortField $direction"; |
119 | | - $continueSql = "$sortField $continueDirection"; |
120 | 132 | |
121 | 133 | // Build WHERE clause. |
122 | 134 | // Filter applied , if any: |
123 | 135 | $where = $this->getFilterCriteria( $filter, $filterValue ); |
124 | 136 | // PageID: |
125 | 137 | $where['af_page_id'] = $pageId; |
126 | | - // Continue value, if any: |
| 138 | + // Continue SQL, if any: |
127 | 139 | if ( $continue !== null ) { |
128 | | - $where[] = $continueSql.' '.intVal( $continue ); |
| 140 | + $where[] = $continueSql; |
129 | 141 | } |
130 | 142 | // Only show bucket 1 (per Fabrice on 1/25) |
131 | 143 | $where['af_bucket_id'] = 1; |
— | — | @@ -163,10 +175,13 @@ |
164 | 176 | ) |
165 | 177 | ) |
166 | 178 | ); |
| 179 | + |
167 | 180 | foreach ( $id_query as $id ) { |
168 | 181 | $ids[] = $id->af_id; |
169 | | - $this->continue = $id->$sortField; |
| 182 | + $this->continue = $id->$sortField; |
| 183 | + $this->continueId = $id->af_id; |
170 | 184 | } |
| 185 | + |
171 | 186 | |
172 | 187 | if ( !count( $ids ) ) { |
173 | 188 | return array(); |
— | — | @@ -683,6 +698,11 @@ |
684 | 699 | ApiBase::PARAM_ISMULTI => false, |
685 | 700 | ApiBase::PARAM_TYPE => 'integer' |
686 | 701 | ), |
| 702 | + 'continueid' => array( |
| 703 | + ApiBase::PARAM_REQUIRED => false, |
| 704 | + ApiBase::PARAM_ISMULTI => false, |
| 705 | + ApiBase::PARAM_TYPE => 'string' |
| 706 | + ), |
687 | 707 | 'continue' => array( |
688 | 708 | ApiBase::PARAM_REQUIRED => false, |
689 | 709 | ApiBase::PARAM_ISMULTI => false, |
— | — | @@ -703,7 +723,8 @@ |
704 | 724 | 'filter' => 'What filtering to apply to list', |
705 | 725 | 'filtervalue' => 'Optional param to pass to filter', |
706 | 726 | 'limit' => 'Number of records to show', |
707 | | - 'continue' => 'Offset from which to continue', |
| 727 | + 'continue' => 'sort value at which to continue', |
| 728 | + 'continueid' => 'Last af_id with that sort value that was shown (IE, where to continue if the page break has the same sort value)', |
708 | 729 | ); |
709 | 730 | } |
710 | 731 | |