Index: trunk/extensions/ArticleFeedbackv5/sql/ArticleFeedbackv5.sql |
— | — | @@ -32,7 +32,10 @@ |
33 | 33 | -- Which link the user clicked on to get to the widget. Default of 0 is "none". |
34 | 34 | af_link_id integer unsigned NOT NULL DEFAULT 0, |
35 | 35 | -- Creation timetamp |
36 | | - af_created binary(14) NOT NULL DEFAULT '' |
| 36 | + af_created binary(14) NOT NULL DEFAULT '', |
| 37 | + -- Number of times the feedback was hidden or marked as abusive. |
| 38 | + af_abuse_count integer unsigned NOT NULL DEFAULT 0, |
| 39 | + af_hide_count integer unsigned NOT NULL DEFAULT 0 |
37 | 40 | ) /*$wgDBTableOptions*/; |
38 | 41 | CREATE INDEX /*i*/af_page_user_token_id ON /*_*/aft_article_feedback (af_page_id, af_user_id, af_user_anon_token, af_id); |
39 | 42 | CREATE INDEX /*i*/af_revision_id ON /*_*/aft_article_feedback (af_revision_id); |
Index: trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.i18n.php |
— | — | @@ -39,6 +39,8 @@ |
40 | 40 | 'articlefeedbackv5-error-flagging' => 'Error flagging feedback.', |
41 | 41 | |
42 | 42 | // Article Feedback special page. |
| 43 | + 'articlefeedbackv5-form-helpful-label' => 'Is this feedback helpful?', |
| 44 | + 'articlefeedbackv5-special-add-feedback' => 'Add Your feedback', |
43 | 45 | 'articlefeedbackv5-special-filter-visible' => 'Visible', |
44 | 46 | 'articlefeedbackv5-special-filter-invisible' => 'Invisible', |
45 | 47 | 'articlefeedbackv5-special-filter-all' => 'All', |
— | — | @@ -48,13 +50,14 @@ |
49 | 51 | 'articlefeedbackv5-special-sort-label-after' => '', |
50 | 52 | 'articlefeedbackv5-special-filter-label-before' => 'Show only:', |
51 | 53 | 'articlefeedbackv5-special-filter-label-after' => '', |
52 | | - 'articlefeedbackv5-special-showing' => 'Showing $1 posts (of $2)', // FIXME: Needs plural support on $1. |
| 54 | + 'articlefeedbackv5-special-showing' => '$1 feedback posts on this page', // FIXME: Needs plural support on $1. |
53 | 55 | 'articlefeedbackv5-special-more' => 'More', |
54 | | - 'articlefeedbackv5-special-pagetitle' => 'Feedback for $1', |
| 56 | + 'articlefeedbackv5-special-pagetitle' => 'Feedback: $1', |
55 | 57 | |
56 | 58 | 'articlefeedbackv5-form-optionid' => 'Option $1', |
57 | | - 'articlefeedbackv5-form-hide' => 'Hide this ($1)', |
| 59 | + 'articlefeedbackv5-form-hide' => 'Hide this post ($1)', |
58 | 60 | 'articlefeedbackv5-form-abuse' => 'Flag as abuse ($1)', |
| 61 | + 'articlefeedbackv5-form-delete' => 'Delete', |
59 | 62 | 'articlefeedbackv5-form-header' => 'Feedback #$1, at $2', |
60 | 63 | 'articlefeedbackv5-form1-header-found' => '{{GENDER:$1|$1}} found what they were looking for:', |
61 | 64 | 'articlefeedbackv5-form1-header-not-found' => '{{GENDER:$1|$1}} did not find what they were looking for:', |
— | — | @@ -72,9 +75,9 @@ |
73 | 76 | 'articlefeedbackv5-error-loading-feedback' => 'Error loading feedback', |
74 | 77 | 'articlefeedbackv5-invalid-feedback-id' => 'Invalid feedback ID', |
75 | 78 | 'articlefeedbackv5-invalid-feedback-flag' => 'Invalid feedback flag', |
76 | | - 'articlefeedbackv5-go-to-article' => 'Go to page', |
77 | | - 'articlefeedbackv5-discussion-page' => 'Discussion Page', |
78 | | - 'articlefeedbackv5-whats-this' => 'What\'s this?', |
| 79 | + 'articlefeedbackv5-go-to-article' => 'View article', |
| 80 | + 'articlefeedbackv5-discussion-page' => 'Discussion', |
| 81 | + 'articlefeedbackv5-whats-this' => 'Help', |
79 | 82 | 'articlefeedbackv5-invalid-page-id' => 'Invalid page ID', |
80 | 83 | 'articlefeedbackv5-percent-found' => '$1% of users found what they were looking for.', |
81 | 84 | 'articlefeedbackv5-overall-rating' => 'Rating: $1/5', |
Index: trunk/extensions/ArticleFeedbackv5/modules/jquery.articleFeedbackv5/jquery.articleFeedbackv5.special.js |
— | — | @@ -26,6 +26,8 @@ |
27 | 27 | |
28 | 28 | // {{{ articleFeedbackv5 definition |
29 | 29 | |
| 30 | + // TODO: jam sort/filter options into URL anchors, and use them as defaults if present. |
| 31 | + |
30 | 32 | $.articleFeedbackv5special = {}; |
31 | 33 | |
32 | 34 | // {{{ Properties |
— | — | @@ -56,11 +58,6 @@ |
57 | 59 | $.articleFeedbackv5special.offset = 0; |
58 | 60 | |
59 | 61 | /** |
60 | | - * ??? |
61 | | - */ |
62 | | - $.articleFeedbackv5special.showing = 0; |
63 | | - |
64 | | - /** |
65 | 62 | * The url to which to send the request |
66 | 63 | */ |
67 | 64 | $.articleFeedbackv5special.apiUrl = undefined; |
— | — | @@ -72,34 +69,36 @@ |
73 | 70 | * Binds events for each of the controls |
74 | 71 | */ |
75 | 72 | $.articleFeedbackv5special.setBinds = function() { |
76 | | - $( '#aft5-filter' ).bind( 'change', function(e) { |
| 73 | + $( '#aft5-filter' ).bind( 'change', function( e ) { |
77 | 74 | $.articleFeedbackv5special.filter = $(this).val(); |
78 | 75 | $.articleFeedbackv5special.loadFeedback( true ); |
79 | 76 | return false; |
80 | 77 | } ); |
81 | | - $( '#aft5-sort' ).bind( 'change', function(e) { |
82 | | - $.articleFeedbackv5special.sort = $(this).val(); |
| 78 | + $( '.aft5-sort-link' ).bind( 'click', function( e ) { |
| 79 | + $.articleFeedbackv5special.sort = $.articleFeedbackv5special.stripID( this, 'articlefeedbackv5-special-sort-' ); |
83 | 80 | $.articleFeedbackv5special.loadFeedback( true ); |
84 | 81 | return false; |
85 | 82 | } ); |
86 | | - $( '#aft5-show-more' ).bind( 'click', function(e) { |
87 | | - $.articleFeedbackv5special.offset += |
88 | | - $.articleFeedbackv5special.limit; |
89 | | - $.articleFeedbackv5special.loadFeedback( false); |
| 83 | + $( '#aft5-show-more' ).bind( 'click', function( e ) { |
| 84 | + $.articleFeedbackv5special.offset += $.articleFeedbackv5special.limit; |
| 85 | + $.articleFeedbackv5special.loadFeedback( false ); |
90 | 86 | return false; |
91 | 87 | } ); |
92 | | - $( '.aft5-abuse-link' ).live( 'click', function(e) { |
93 | | - var id = $( this ).attr( 'id' ).replace( 'aft5-abuse-link-', '' ); |
94 | | - $.articleFeedbackv5special.abuseFeedback( id ); |
| 88 | + $( '.aft5-abuse-link' ).live( 'click', function( e ) { |
| 89 | + $.articleFeedbackv5special.abuseFeedback( $.articleFeedbackv5special.stripID( this, 'aft5-abuse-link-' ) ); |
95 | 90 | return false; |
96 | 91 | } ); |
97 | | - $( '.aft5-hide-link' ).live( 'click', function(e) { |
98 | | - var id = $( this ).attr( 'id' ).replace( 'aft5-hide-link-', '' ); |
99 | | - $.articleFeedbackv5special.hideFeedback( id ); |
| 92 | + $( '.aft5-hide-link' ).live( 'click', function( e ) { |
| 93 | + $.articleFeedbackv5special.hideFeedback( $.articleFeedbackv5special.stripID( this, 'aft5-hide-link-' ) ); |
100 | 94 | return false; |
101 | 95 | } ); |
102 | 96 | } |
103 | 97 | |
| 98 | + // Utility method for stripping long IDs down to the specific bits we care about. |
| 99 | + $.articleFeedbackv5special.stripID = function ( object, toRemove ) { |
| 100 | + return $( object ).attr( 'id' ).replace( toRemove, '' ); |
| 101 | + } |
| 102 | + |
104 | 103 | // }}} |
105 | 104 | // {{{ Moderation methods |
106 | 105 | |
— | — | @@ -202,17 +201,10 @@ |
203 | 202 | if ( 'articlefeedbackv5-view-feedback' in data ) { |
204 | 203 | if ( resetContents ) { |
205 | 204 | $( '#aft5-show-feedback' ).html( data['articlefeedbackv5-view-feedback'].feedback); |
206 | | - $.articleFeedbackv5special.showing = data['articlefeedbackv5-view-feedback'].length; |
207 | 205 | } else { |
208 | 206 | $( '#aft5-show-feedback' ).append( data['articlefeedbackv5-view-feedback'].feedback); |
209 | | - $.articleFeedbackv5special.showing += data['articlefeedbackv5-view-feedback'].length; |
210 | 207 | } |
211 | | - $( '#aft5-feedback-count-shown' ).text( $.articleFeedbackv5special.showing ); |
212 | 208 | $( '#aft5-feedback-count-total' ).text( data['articlefeedbackv5-view-feedback'].count ); |
213 | | - if ( $.articleFeedbackv5special.showing >= data['articlefeedbackv5-view-feedback'].count ) { |
214 | | - $( '#aft5-show-more' ).hide(); |
215 | | - } |
216 | | - |
217 | 209 | } else { |
218 | 210 | $( '#aft5-show-feedback' ).text( mw.msg( 'articlefeedbackv5-error-loading-feedback' ) ); |
219 | 211 | } |
— | — | @@ -237,12 +229,9 @@ |
238 | 230 | |
239 | 231 | // {{{ Kick off when ready |
240 | 232 | |
241 | | - // This was failing sometimes when it was in the function above. |
242 | | - // I think it maky have been a race condition. |
| 233 | + // Set up config vars, event binds, and do initial fetch. |
243 | 234 | $.articleFeedbackv5special.apiUrl = mw.util.wikiScript('api'); |
244 | 235 | $.articleFeedbackv5special.page = mw.config.get( 'afPageId' ); |
245 | | - |
246 | | - // Set up event binds and do initial data fetch. |
247 | 236 | $.articleFeedbackv5special.setBinds(); |
248 | 237 | $.articleFeedbackv5special.loadFeedback( true ); |
249 | 238 | |
Index: trunk/extensions/ArticleFeedbackv5/api/ApiArticleFeedbackv5.php |
— | — | @@ -65,7 +65,7 @@ |
66 | 66 | if ( $value === '' ) { |
67 | 67 | continue; |
68 | 68 | } |
69 | | - if ( $this->validateParam( $value, $type, $field['afi_id'] ) ) { |
| 69 | + if ( $this->validateParam( $value, $type, $field['afi_id'], $pageId ) ) { |
70 | 70 | $data = array( |
71 | 71 | 'aa_field_id' => $field['afi_id'], |
72 | 72 | ); |
— | — | @@ -143,9 +143,10 @@ |
144 | 144 | * text for the id) |
145 | 145 | * @param $type string the field type |
146 | 146 | * @param $field_id int the field id |
| 147 | + * @param $pageId int the page id (needed by abuse filter) |
147 | 148 | * @return bool whether this is okay |
148 | 149 | */ |
149 | | - protected function validateParam( &$value, $type, $field_id ) { |
| 150 | + protected function validateParam( &$value, $type, $field_id, $pageId ) { |
150 | 151 | # rating: int between 1 and 5 (inclusive) |
151 | 152 | # boolean: 1 or 0 |
152 | 153 | # option_id: option exists |
— | — | @@ -173,7 +174,7 @@ |
174 | 175 | } |
175 | 176 | break; |
176 | 177 | case 'text': |
177 | | - return true; |
| 178 | + return $this->validateText( $value, $pageId ); |
178 | 179 | default: |
179 | 180 | return false; |
180 | 181 | } |
— | — | @@ -181,6 +182,39 @@ |
182 | 183 | } |
183 | 184 | |
184 | 185 | /** |
| 186 | + * Run the text through the AbuseFilter and SpamBlacklist extensions. |
| 187 | + * Should we check length as well? What's a reasonable max length? |
| 188 | + * |
| 189 | + */ |
| 190 | + private function validateText( &$value, $pageId ) { |
| 191 | + global $wgArticleFeedbackv5MaxCommentLength; |
| 192 | + $title = Title::newFromID( $pageId ); |
| 193 | + |
| 194 | + # Apparently this returns either true or an error message? |
| 195 | + # http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/AbuseFilter/AbuseFilter.class.php?view=markup |
| 196 | + # (line 715-721). So normalize this. |
| 197 | + $vars = array( |
| 198 | + ); |
| 199 | +# $filter_error = AbuseFilter::filterAction( $vars, $title ); |
| 200 | +# $filter_error = ( $filter_error === true ? 1 : 0 ); |
| 201 | + |
| 202 | + $filter_error = 0; # TODO |
| 203 | + $spam_error = 0; # TODO |
| 204 | + |
| 205 | + # Not actually a requirement, but I can see this being a thing, |
| 206 | + # not letting people post the entire text of 1984 in a comment |
| 207 | + # or something like that. |
| 208 | + $length_error = 0; |
| 209 | + if( isset( $wgArticleFeedbackv5MaxCommentLength ) ) { |
| 210 | + $length_error = strlen( $value ) > $wgArticleFeedbackv5MaxCommentLength ? 1 : 0; |
| 211 | + } |
| 212 | + |
| 213 | + $has_error = $filter_error + $spam_error + $length_error; |
| 214 | + |
| 215 | + return $has_error ? false : true; |
| 216 | + } |
| 217 | + |
| 218 | + /** |
185 | 219 | * Update the rollup tables |
186 | 220 | * |
187 | 221 | * @param $page int the page id |
Index: trunk/extensions/ArticleFeedbackv5/api/ApiViewFeedbackArticleFeedbackv5.php |
— | — | @@ -46,9 +46,9 @@ |
47 | 47 | $length++; |
48 | 48 | } |
49 | 49 | |
50 | | - $result->addValue( $this->getModuleName(), 'length', $length ); |
51 | | - $result->addValue( $this->getModuleName(), 'count', $count ); |
52 | | - $result->addValue( $this->getModuleName(), 'feedback', $html ); |
| 50 | + $result->addValue( $this->getModuleName(), 'length', $length ); |
| 51 | + $result->addValue( $this->getModuleName(), 'count', $count ); |
| 52 | + $result->addValue( $this->getModuleName(), 'feedback', $html ); |
53 | 53 | } |
54 | 54 | |
55 | 55 | public function fetchFeedbackCount( $pageId, $filter ) { |
— | — | @@ -171,29 +171,49 @@ |
172 | 172 | } |
173 | 173 | |
174 | 174 | protected function renderFeedback( $record ) { |
175 | | - $id = $record[0]->af_id; |
176 | | - $rv = "<div class='aft5-feedback'><p>" |
177 | | - .wfMessage( 'articlefeedbackv5-form-header', $id, $record[0]->af_created )->escaped() |
178 | | - .'</p>'; |
179 | 175 | switch( $record[0]->af_bucket_id ) { |
180 | | - case 1: $rv .= $this->renderBucket1( $record ); break; |
181 | | - case 2: $rv .= $this->renderBucket2( $record ); break; |
182 | | - case 3: $rv .= $this->renderBucket3( $record ); break; |
183 | | - case 4: $rv .= $this->renderBucket4( $record ); break; |
184 | | - case 5: $rv .= $this->renderBucket5( $record ); break; |
185 | | - case 6: $rv .= $this->renderBucket6( $record ); break; |
186 | | - default: $rv .= $this->renderNoBucket( $record ); break; |
| 176 | + case 1: $content .= $this->renderBucket1( $record ); break; |
| 177 | + case 2: $content .= $this->renderBucket2( $record ); break; |
| 178 | + case 3: $content .= $this->renderBucket3( $record ); break; |
| 179 | + case 4: $content .= $this->renderBucket4( $record ); break; |
| 180 | + case 5: $content .= $this->renderBucket5( $record ); break; |
| 181 | + case 6: $content .= $this->renderBucket6( $record ); break; |
| 182 | + default: $content .= $this->renderNoBucket( $record ); break; |
187 | 183 | } |
188 | | - $rv .= "<p>" |
| 184 | + # TODO: check roles to determine what to show here (and cache somewhere so we don't keep looking them up). |
| 185 | + $can_flag = 1; |
| 186 | + $can_hide = 1; |
| 187 | + $can_delete = 1; |
| 188 | + $id = $record[0]->af_id; |
| 189 | + |
| 190 | + # TODO: permalinks |
| 191 | + return Html::openElement( 'div', array( 'id' => 'aft5-feedback' ) ) |
| 192 | + .Html::openElement( 'p' ) |
| 193 | + .Html::element( 'a', array( 'class' => 'aft5-comment-name', 'href' => 'profilepage or whatever' ), $id ) |
| 194 | + .Html::element( 'span', array( 'class' => 'aft5-comment-timestamp' ), $record[0]->af_created ) |
| 195 | + .Html::closeElement( 'p' ) |
189 | 196 | .wfMessage( 'articlefeedbackv5-form-optionid', $record[0]->af_bucket_id )->escaped() |
190 | | - .'</a> '.wfMessage( 'pipe-separator' )->escaped() |
191 | | - ."<a href='#' class='aft5-hide-link' id='aft5-hide-link-$id'>" |
192 | | - .wfMessage( 'articlefeedbackv5-form-hide', $record[0]->af_hide_count )->escaped() |
193 | | - .'</a>'.wfMessage( 'pipe-separator' )->escaped() |
194 | | - ."<a href='#' class='aft5-abuse-link' id='aft5-abuse-link-$id'>" |
195 | | - .wfMessage( 'articlefeedbackv5-form-abuse', $record[0]->af_abuse_count )->escaped() |
196 | | - ."</a></p></div><hr>"; |
197 | | - return $rv; |
| 197 | + .$content |
| 198 | + .wfMessage( 'articlefeedbackv5-form-helpful-label' )->escaped() |
| 199 | + .Html::openElement( 'div', array( 'id' => 'aft5-feedback-tools' ) ) |
| 200 | + .Html::element( 'h3', array(), 'Tools' ) |
| 201 | + .Html::openElement( 'ul' ) |
| 202 | + .($can_flag ? Html::rawElement( 'li', array(), Html::element( 'a', array( |
| 203 | + 'id' => "aft5-hide-link-$id", |
| 204 | + 'class' => 'aft5-hide-link' |
| 205 | + ), wfMessage( 'articlefeedbackv5-form-hide', $record[0]->af_hide_count )->escaped() ) ) : '' ) |
| 206 | + .($can_hide ? Html::rawElement( 'li', array(), Html::element( 'a', array( |
| 207 | + 'id' => "aft5-abuse-link-$id", |
| 208 | + 'class' => 'aft5-abuse-link' |
| 209 | + ), wfMessage( 'articlefeedbackv5-form-abuse', $record[0]->af_abuse_count )->escaped() ) ) : '' ) |
| 210 | + .($can_delete ? Html::rawElement( 'li', array(), Html::element( 'a', array( |
| 211 | + 'id' => "aft5-delete-link-$id", |
| 212 | + 'class' => 'aft5-delete-link' |
| 213 | + ), wfMessage( 'articlefeedbackv5-form-delete' )->escaped() ) ) : '' ) |
| 214 | + .Html::closeElement( 'ul' ) |
| 215 | + .Html::closeElement( 'div' ) |
| 216 | + .Html::closeElement( 'div' ) |
| 217 | + .Html::element( 'hr' ); |
198 | 218 | } |
199 | 219 | |
200 | 220 | private function renderBucket1( $record ) { |
Index: trunk/extensions/ArticleFeedbackv5/SpecialArticleFeedbackv5.php |
— | — | @@ -43,84 +43,130 @@ |
44 | 44 | $rating = isset( $ratings['rating'] ) ? $ratings['rating'] : null; |
45 | 45 | |
46 | 46 | $out->setPagetitle( |
47 | | - $this->msg( 'articlefeedbackv5-special-pagetitle', $title ) |
48 | | - ->escaped() |
| 47 | + $this->msg( 'articlefeedbackv5-special-pagetitle', $title )->escaped() |
49 | 48 | ); |
50 | 49 | |
51 | 50 | if ( !$pageId ) { |
52 | 51 | $out->addWikiMsg( 'articlefeedbackv5-invalid-page-id' ); |
53 | 52 | } else { |
| 53 | + # TODO: Fix links. |
54 | 54 | $out->addHTML( |
55 | | - Linker::link( |
| 55 | + Html::openElement( |
| 56 | + 'div', |
| 57 | + array( 'id' => 'aft5-header-links' ) |
| 58 | + ) |
| 59 | + .Linker::link( |
56 | 60 | Title::newFromText( $param ), |
57 | 61 | $this->msg( 'articlefeedbackv5-go-to-article' )->escaped() |
58 | 62 | ) |
59 | | - . ' | ' . |
60 | | - Linker::link( |
61 | | - Title::newFromText( $param ), |
62 | | - $this->msg( 'articlefeedbackv5-discussion-page' )->escaped() |
63 | | - ) |
64 | | - . ' | ' . |
65 | | - Linker::link( |
66 | | - Title::newFromText( $param ), |
67 | | - $this->msg( 'articlefeedbackv5-whats-this' )->escaped() |
68 | | - ) |
| 63 | + . ' | ' . |
| 64 | + Linker::link( |
| 65 | + Title::newFromText( $param ), |
| 66 | + $this->msg( 'articlefeedbackv5-discussion-page' )->escaped() |
| 67 | + ) |
| 68 | + . ' | ' . |
| 69 | + Linker::link( |
| 70 | + Title::newFromText( $param ), |
| 71 | + $this->msg( 'articlefeedbackv5-whats-this' )->escaped() |
| 72 | + ) |
| 73 | + .Html::closeElement( 'div' ) |
69 | 74 | ); |
70 | 75 | } |
71 | 76 | |
| 77 | + $out->addHTML( |
| 78 | + Html::openElement( |
| 79 | + 'div', |
| 80 | + array( 'id' => 'aft5-showing-count-wrap' ) |
| 81 | + ) |
| 82 | + .$this->msg( |
| 83 | + 'articlefeedbackv5-special-showing', |
| 84 | + Html::element( 'span', array( 'id' => 'aft-feedback-count-total' ), '0' ) |
| 85 | + ) |
| 86 | + .Html::closeElement( 'div' ) |
| 87 | + ); |
| 88 | + |
72 | 89 | if ( $found ) { |
73 | | - $out->addWikiMsg( 'articlefeedbackv5-percent-found', $found ); |
| 90 | + $out->addHtml( |
| 91 | + Html::openElement( |
| 92 | + 'div', |
| 93 | + array( 'id' => 'aft5-percent-found-wrap' ) |
| 94 | + ) |
| 95 | + .$this->msg( 'articlefeedbackv5-percent-found', $found )->escaped() |
| 96 | + .Html::closeElement( 'div' ) |
| 97 | + ); |
74 | 98 | } |
75 | 99 | |
76 | | - if ( $rating ) { |
77 | | - $out->addWikiMsg( 'articlefeedbackv5-overall-rating', $rating ); |
78 | | - } |
| 100 | +# if ( $rating ) { |
| 101 | +# $out->addWikiMsg( 'articlefeedbackv5-overall-rating', $rating ); |
| 102 | +# } |
79 | 103 | |
80 | 104 | $out->addWikiMsg( 'articlefeedbackv5-special-title' ); |
81 | 105 | |
82 | | - $showing = $this->msg( |
83 | | - 'articlefeedbackv5-special-showing', |
84 | | - Html::element( 'span', array( 'id' => 'aft-feedback-count-shown' ), '0' ), |
85 | | - Html::element( 'span', array( 'id' => 'aft-feedback-count-total' ), '0' ) |
86 | | - ); |
87 | | - |
88 | 106 | $out->addJsConfigVars( 'afPageId', $pageId ); |
89 | 107 | $out->addModules( 'jquery.articleFeedbackv5.special' ); |
90 | 108 | |
| 109 | + |
| 110 | + $sortLabels = array(); |
| 111 | + $sortOpts = array( 'newest', 'oldest' ); |
| 112 | + foreach( $sortOpts as $sort ) { |
| 113 | + $sortLabels[] = Html::element( |
| 114 | + 'a', |
| 115 | + array( |
| 116 | + 'href' => '#', |
| 117 | + 'id' => 'articlefeedbackv5-special-sort-'.$sort, |
| 118 | + 'class' => 'aft5-sort-link' |
| 119 | + ), |
| 120 | + $this->msg( 'articlefeedbackv5-special-sort-'.$sort ) |
| 121 | + ); |
| 122 | + } |
| 123 | + |
91 | 124 | $filterSelect = new XmlSelect( false, 'aft5-filter' ); |
92 | 125 | $filterSelect->addOptions( $this->selectMsg( array( |
93 | | - 'articlefeedbackv5-special-filter-visible' => 'visible', |
94 | | - 'articlefeedbackv5-special-filter-invisible' => 'invisible', |
95 | | - 'articlefeedbackv5-special-filter-all' => 'all', |
96 | | - ) |
| 126 | + 'articlefeedbackv5-special-filter-visible' => 'visible', |
| 127 | + 'articlefeedbackv5-special-filter-invisible' => 'invisible', |
| 128 | + 'articlefeedbackv5-special-filter-all' => 'all', |
| 129 | + ))); |
| 130 | + |
| 131 | + $out->addHTML( |
| 132 | + Html::openElement( |
| 133 | + 'div', |
| 134 | + array( 'id' => 'aft5-sort-filter-controls' ) |
97 | 135 | ) |
| 136 | + .$this->msg( 'articlefeedbackv5-special-sort-label-before' ) |
| 137 | + .implode( wfMessage( 'pipe-separator' )->escaped(), $sortLabels ) |
| 138 | + .$this->msg( 'articlefeedbackv5-special-sort-label-after' ) |
| 139 | + |
| 140 | + .$this->msg( 'articlefeedbackv5-special-filter-label-before' ) |
| 141 | + .$filterSelect->getHTML() |
| 142 | + .$this->msg( 'articlefeedbackv5-special-filter-label-after' ) |
| 143 | + .Html::element( |
| 144 | + 'a', |
| 145 | + array( |
| 146 | + 'href' => '#', |
| 147 | + 'id' => 'articlefeedbackv5-special-add-feedback', |
| 148 | + ), |
| 149 | + $this->msg( 'articlefeedbackv5-special-add-feedback' ) |
| 150 | + ) |
| 151 | + .Html::closeElement( 'div' ) |
98 | 152 | ); |
99 | 153 | |
100 | | - $sortSelect = new XmlSelect( false, 'aft5-sort' ); |
101 | | - $sortSelect->addOptions( $this->selectMsg( array( |
102 | | - 'articlefeedbackv5-special-sort-newest' => 'newest', |
103 | | - 'articlefeedbackv5-special-sort-oldest' => 'oldest', |
104 | | - ) |
| 154 | + $out->addHTML( |
| 155 | + Html::element( |
| 156 | + 'div', |
| 157 | + array( |
| 158 | + 'id' => 'aft5-show-feedback', |
| 159 | + 'style' => 'border:1px solid red;' |
| 160 | + ), '' |
105 | 161 | ) |
| 162 | + .Html::element( |
| 163 | + 'a', |
| 164 | + array( |
| 165 | + 'href' => '#', |
| 166 | + 'id' => 'aft5-show-more' |
| 167 | + ), |
| 168 | + $this->msg( 'articlefeedbackv5-special-more' )->escaped() |
| 169 | + ) |
106 | 170 | ); |
107 | | - |
108 | | - $out->addHTML( $this->msg( 'articlefeedbackv5-special-filter-label-before' )->escaped() |
109 | | - . $filterSelect->getHTML() |
110 | | - . $this->msg( 'articlefeedbackv5-special-filter-label-after' )->escaped() |
111 | | - . ' | ' |
112 | | - . $this->msg( 'articlefeedbackv5-special-sort-label-before' )->escaped() |
113 | | - . $sortSelect->getHTML() |
114 | | - . $this->msg( 'articlefeedbackv5-special-sort-label-after' )->escaped() |
115 | | - . Html::element( 'span', array( 'id' => 'aft-showing' ), $showing ) |
116 | | - . Html::element( 'div', array( |
117 | | - 'id' => 'aft5-show-feedback', |
118 | | - 'style' => 'border:1px solid red;' |
119 | | - ), '' |
120 | | - ) |
121 | | - . Html::element( 'a', array( 'href' => '#', 'id' => 'aft5-show-more' ), |
122 | | - $this->msg( 'articlefeedbackv5-special-more' )->escaped() |
123 | | - ) |
124 | | - ); |
125 | 171 | } |
126 | 172 | |
127 | 173 | /** |