r111472 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r111471‎ | r111472 | r111473 >
Date:19:14, 14 February 2012
Author:emsmith
Status:resolved (Comments)
Tags:schema 
Comment:
bug 34090 - Added an additional column in the main feedback table to keep a count of the number of activities which have happened for each piece of feedback - this should be equivalent to running a "count(*)" on the logging table for a specific piece of feedback. Made sure the counter is incremented when a new log entry concerning activity is added. Created a new api to get an html block of activity for use on the feedback page. Returns a json object with "activity" = html block of activities, more set to true IF there are more entries to fetch, can have the limit changed and uses continue to get the next entries if more is true, send it the feedbackid and optionally a limit and/or continue value
Modified paths:
  • /trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.i18n.php (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.php (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/api/ApiArticleFeedbackv5Utils.php (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/api/ApiViewActivityArticleFeedbackv5.php (added) (history)
  • /trunk/extensions/ArticleFeedbackv5/sql/ArticleFeedbackv5.sql (modified) (history)
  • /trunk/extensions/ArticleFeedbackv5/sql/alter.sql (modified) (history)

Diff [purge]

Index: trunk/extensions/ArticleFeedbackv5/sql/ArticleFeedbackv5.sql
@@ -44,7 +44,10 @@
4545 -- Flag a message as requiring oversight, being hidden ,or being deleted
4646 af_needs_oversight boolean NOT NULL DEFAULT FALSE,
4747 af_is_deleted boolean NOT NULL DEFAULT FALSE,
48 - af_is_hidden boolean NOT NULL DEFAULT FALSE
 48+ af_is_hidden boolean NOT NULL DEFAULT FALSE,
 49+ -- Keep track of number of activities (hide/show/flag/unflag)
 50+ -- should be equivalent to counting rows in logging table
 51+ af_activity_count integer unsigned NOT NULL DEFAULT 0
4952 ) /*$wgDBTableOptions*/;
5053 CREATE INDEX /*i*/af_page_user_token_id ON /*_*/aft_article_feedback (af_page_id, af_user_id, af_user_anon_token, af_id);
5154 CREATE INDEX /*i*/af_revision_id ON /*_*/aft_article_feedback (af_revision_id);
Index: trunk/extensions/ArticleFeedbackv5/sql/alter.sql
@@ -125,3 +125,6 @@
126126
127127 -- Added 2/1 (greg)
128128 CREATE INDEX /*_*/af_net_helpfulness_af_id ON /*_*/aft_article_feedback (af_id, af_net_helpfulness);
 129+
 130+-- Added 2/14 (emsmith)
 131+ALTER TABLE /*_*/aft_article_feedback ADD COLUMN af_activity_count integer unsigned NOT NULL DEFAULT 0;
Index: trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.i18n.php
@@ -321,7 +321,7 @@
322322 'right-aftv5-see-deleted-feedback' => 'View deleted feedback',
323323 'right-aftv5-see-hidden-feedback' => 'View hidden feedback',
324324
325 - // Log types
 325+ /* Log types */
326326 'articlefeedbackv5-log-name' => 'Article Feedback Activity Log',
327327 'articlefeedbackv5-log-header' => 'This is the log of activity taken on feedback items collected for articles using Article Feedback.',
328328 'articlefeedbackv5-log-oversight' => 'changed the feedback [[$1]] status to oversight',
@@ -334,6 +334,25 @@
335335 'articlefeedbackv5-log-flag' => 'flagged the feedback [[$1]] as abuse',
336336 'articlefeedbackv5-log-unflag' => 'unflagged the feedback [[$1]] as abuse',
337337
 338+ /* Activity Pane phrases */
 339+ 'articlefeedbackv5-activity-pane-header' => 'Activity Log',
 340+ 'articlefeedbackv5-activity-help-item' => '?',
 341+ 'articlefeedbackv5-activity-close-item' => 'X',
 342+ 'articlefeedbackv5-activity-feedback-info' => 'Feedback Post #$1 by',
 343+ 'articlefeedbackv5-activity-feedback-date' => 'Posted on $1',
 344+ 'articlefeedbackv5-activity-permalink' => 'permalink',
 345+ 'articlefeedbackv5-activity-request' => 'requested oversight on',
 346+ 'articlefeedbackv5-activity-unrequest' => 'unrequested oversight on',
 347+ 'articlefeedbackv5-activity-decline' => 'declined oversight on',
 348+ 'articlefeedbackv5-activity-hidden' => 'hid this post on',
 349+ 'articlefeedbackv5-activity-flag' => 'flagged this post on',
 350+ 'articlefeedbackv5-activity-unhidden' => 'unhid this post on',
 351+ 'articlefeedbackv5-activity-unflag' => 'unflagged this post on',
 352+ 'articlefeedbackv5-activity-oversight' => 'oversighted this post on',
 353+ 'articlefeedbackv5-activity-unoversight' => 'removed oversight on this post on',
 354+ 'articlefeedbackv5-activity-count' => '$1 actions on this post',
 355+ 'articlefeedbackv5-activity-more' => 'Show more Activity',
 356+
338357 /* EmailCapture */
339358 'articlefeedbackv5-emailcapture-response-body' => 'Hello!
340359
Index: trunk/extensions/ArticleFeedbackv5/ArticleFeedbackv5.php
@@ -244,6 +244,7 @@
245245 'Arthur Richards',
246246 'Timo Tijhof',
247247 'Ryan Kaldari',
 248+ 'Elizabeth M Smith',
248249 ),
249250 'version' => '0.0.1',
250251 'descriptionmsg' => 'articlefeedbackv5-desc',
@@ -257,6 +258,7 @@
258259 $wgAutoloadClasses['ApiViewRatingsArticleFeedbackv5'] = $dir . 'api/ApiViewRatingsArticleFeedbackv5.php';
259260 $wgAutoloadClasses['ApiViewFeedbackArticleFeedbackv5'] = $dir . 'api/ApiViewFeedbackArticleFeedbackv5.php';
260261 $wgAutoloadClasses['ApiFlagFeedbackArticleFeedbackv5'] = $dir . 'api/ApiFlagFeedbackArticleFeedbackv5.php';
 262+$wgAutoloadClasses['ApiViewActivityArticleFeedbackv5'] = $dir . 'api/ApiViewActivityArticleFeedbackv5.php';
261263 $wgAutoloadClasses['ArticleFeedbackv5Hooks'] = $dir . 'ArticleFeedbackv5.hooks.php';
262264 $wgAutoloadClasses['SpecialArticleFeedbackv5'] = $dir . 'SpecialArticleFeedbackv5.php';
263265 $wgExtensionMessagesFiles['ArticleFeedbackv5'] = $dir . 'ArticleFeedbackv5.i18n.php';
@@ -276,6 +278,7 @@
277279 // API Registration
278280 $wgAPIListModules['articlefeedbackv5-view-ratings'] = 'ApiViewRatingsArticleFeedbackv5';
279281 $wgAPIListModules['articlefeedbackv5-view-feedback'] = 'ApiViewFeedbackArticleFeedbackv5';
 282+$wgAPIListModules['articlefeedbackv5-view-activity'] = 'ApiViewActivityArticleFeedbackv5';
280283 $wgAPIModules['articlefeedbackv5-flag-feedback'] = 'ApiFlagFeedbackArticleFeedbackv5';
281284 $wgAPIModules['articlefeedbackv5'] = 'ApiArticleFeedbackv5';
282285
Index: trunk/extensions/ArticleFeedbackv5/api/ApiArticleFeedbackv5Utils.php
@@ -245,6 +245,21 @@
246246 $log = new LogPage( 'articlefeedbackv5' );
247247 // comments become the notes section from the feedback
248248 $log->addEntry( $type, $title, $notes );
 249+
 250+ // update our log count by 1
 251+ $dbw = wfGetDB( DB_MASTER );
 252+ $dbw->begin();
 253+
 254+ $dbw->update(
 255+ 'aft_article_feedback',
 256+ array( 'af_activity_count = af_activity_count + 1' ),
 257+ array(
 258+ 'af_id' => $itemId
 259+ ),
 260+ __METHOD__
 261+ );
 262+
 263+ $dbw->commit();
249264 }
250265 }
251266
Index: trunk/extensions/ArticleFeedbackv5/api/ApiViewActivityArticleFeedbackv5.php
@@ -0,0 +1,379 @@
 2+<?php
 3+/**
 4+ * ApiViewActivityArticleFeedbackv5 class
 5+ *
 6+ * @package ArticleFeedback
 7+ * @subpackage Api
 8+ * @author Elizabeth M Smith <elizabeth@omniti.com>
 9+ * @version $Id$
 10+ */
 11+
 12+/**
 13+ * This class pulls the aggregated ratings for display in Bucket #5
 14+ *
 15+ * @package ArticleFeedback
 16+ * @subpackage Api
 17+ */
 18+class ApiViewActivityArticleFeedbackv5 extends ApiQueryBase {
 19+
 20+ /**
 21+ * Constructor
 22+ */
 23+ public function __construct( $query, $moduleName ) {
 24+ parent::__construct( $query, $moduleName, 'af' );
 25+ }
 26+
 27+ /**
 28+ * Execute the API call: Pull max 25 activity log items for page
 29+ */
 30+ public function execute() {
 31+ global $wgUser; // we need to check permissions in here
 32+ global $wgLang; // timestamp formats
 33+
 34+ // If we can't hide, we can't see activity, return an empty string
 35+ // front-end should never let you get here, but just in case
 36+ if( !$wgUser->isAllowed( 'aftv5-hide-feedback' )) {
 37+ return;
 38+ }
 39+
 40+ // These are our valid activity log actions
 41+ $valid = array( 'oversight', 'unoversight', 'hidden', 'unhidden',
 42+ 'decline', 'request', 'unrequest','flag','unflag' );
 43+
 44+ // get our parameter information
 45+ $params = $this->extractRequestParams();
 46+ $feedbackId = $params['feedbackid'];
 47+ $limit = $params['limit'];
 48+ $continue = $params['continue'];
 49+
 50+ // fetch our activity database information
 51+ $feedback = $this->fetchFeedback( $feedbackId );
 52+
 53+ // get the string title for the page
 54+ $page = Title::newFromID( $feedback->af_page_id );
 55+ $title = $page->getPartialURL();
 56+
 57+ // get our activities
 58+ $activities = $this->fetchActivity( $title, $feedbackId, $limit, $continue);
 59+
 60+ // overwrite previous continue for new value
 61+ $continue = null;
 62+
 63+ // generate our html
 64+ $html = '';
 65+
 66+ // <div class="articleFeedbackv5-activity-pane">
 67+ $html .= Html::openElement( 'div', array(
 68+ 'class' => 'articleFeedbackv5-activity-pane'
 69+ ) );
 70+
 71+ // <div class="articleFeedbackv5-activity-header">
 72+ $html .= Html::openElement( 'div', array(
 73+ 'class' => 'articleFeedbackv5-activity-header'
 74+ ) );
 75+
 76+ // <h1>Activity Log</h1>
 77+ $html .= Html::element( 'h1', array(),
 78+ wfMessage( 'articlefeedbackv5-activity-pane-header' )->text() );
 79+
 80+ // <div id="articlefeedbackv5-activity-pane-help">?</div>
 81+ $html .= Html::element( 'div', array(
 82+ 'id' => 'articlefeedbackv5-activity-pane-help'),
 83+ wfMessage( 'articlefeedbackv5-activity-help-item' )->text() );
 84+
 85+ // <div id="articlefeedbackv5-activity-pane-close">X</div>
 86+ $html .= Html::element( 'div', array(
 87+ 'id' => 'articlefeedbackv5-activity-pane-close'),
 88+ wfMessage( 'articlefeedbackv5-activity-close-item' )->text() );
 89+
 90+ // </div> for class="articleFeedbackv5-activity-header"
 91+ $html .= Html::closeElement( 'div' );
 92+
 93+ // <div class="articleFeedbackv5-activity-feedback">
 94+ $html .= Html::openElement( 'div', array(
 95+ 'class' => 'articleFeedbackv5-activity-feedback'
 96+ ) );
 97+
 98+ // <div>Feedback Post #{$feedbackid} by {$user_link}</div>
 99+ $html .= Html::openElement( 'div', array() );
 100+ $html .= wfMessage( 'articlefeedbackv5-activity-feedback-info',
 101+ array($feedback->af_id))->text()
 102+ . $this->getUserLink($feedback->af_user_id, $feedback->af_user_ip);
 103+ $html .= Html::closeElement( 'div' );
 104+
 105+ //<div>Posted on {$date} (UTC)</div>
 106+ $html .= Html::element( 'div', array(),
 107+ wfMessage( 'articlefeedbackv5-activity-feedback-date',
 108+ array( $wgLang->timeanddate( $feedback->af_created ) ))->text() );
 109+
 110+ // <div class="articleFeedbackv5-activity-feedback-permalink">
 111+ $html .= Html::openElement( 'div', array(
 112+ 'class' => 'articleFeedbackv5-activity-feedback-permalink'
 113+ ) );
 114+
 115+ // <a href="{$permalink}">permalink</a>
 116+ $html .= Linker::link(
 117+ SpecialPage::getTitleFor( 'ArticleFeedbackv5', $title . '/'. $feedback->af_id ),
 118+ wfMessage( 'articlefeedbackv5-activity-permalink' )->text());
 119+
 120+ // </div> for class="articleFeedbackv5-activity-feedback-permalink"
 121+ $html .= Html::closeElement( 'div' );
 122+
 123+ // </div> for class="articleFeedbackv5-activity-feedback"
 124+ $html .= Html::closeElement( 'div' );
 125+
 126+ //<div class="articleFeedbackv5-activity-count">$n actions on this post</div>
 127+ $html .= Html::element( 'div', array('class' => 'articleFeedbackv5-activity-count'),
 128+ wfMessage( 'articlefeedbackv5-activity-count',
 129+ array( $feedback->af_activity_count ))->text() );
 130+
 131+ // divs of activity items
 132+ foreach($activities as $item) {
 133+
 134+ // if we do not have a valid action, skip this item
 135+ if ( !in_array( $item->log_action, $valid )) {
 136+ continue;
 137+ }
 138+
 139+ // <div class="articleFeedbackv5-activity-item">
 140+ $html .= Html::openElement( 'div', array(
 141+ 'class' => 'articleFeedbackv5-activity-item'
 142+ ) );
 143+
 144+ // $user $did_something_on $date
 145+ $html .= $this->getUserLink($item->log_user, $item->log_user_text)
 146+ . Html::element( 'div', array(),
 147+ wfMessage( 'articlefeedbackv5-activity-' . $item->log_action,
 148+ array())->text() )
 149+ . $wgLang->timeanddate( $item->log_timestamp );
 150+
 151+ // optional: <div class="articleFeedbackv5-activity-notes">$notes</div>
 152+ if (!empty($item->log_comment)) {
 153+ $html .= Html::element( 'div',
 154+ array('class' => 'articlefeedbackv5-activity-notes'),
 155+ $item->log_comment);
 156+ }
 157+
 158+ // </div> for class="articleFeedbackv5-activity-item"
 159+ $html .= Html::closeElement( 'div' );
 160+
 161+ // the last item's log_id should be the continue;
 162+ $continue = $item->log_id;
 163+ }
 164+
 165+ // figure out if we have more based on our new continue value
 166+ $more = $this->fetchHasMore($title, $feedbackId, $continue);
 167+
 168+ //optional <div class="articleFeedbackv5-activity-more">Show more Activity</div>
 169+ if ($more) {
 170+ $html .= Html::element( 'div', array('class' => 'articleFeedbackv5-activity-more'),
 171+ wfMessage( 'articlefeedbackv5-activity-more', array())->text() );
 172+ }
 173+
 174+ // </div> for class="articleFeedbackv5-activity-pane"
 175+ $html .= Html::closeElement( 'div' );
 176+
 177+ // finally add our generated html data
 178+ $result = $this->getResult();
 179+ $result->addValue( $this->getModuleName(), 'limit', $limit );
 180+ $result->addValue( $this->getModuleName(), 'activity', $html );
 181+
 182+ // continue only goes in if it's not empty
 183+ if ($continue > 0) {
 184+ $result->addValue( $this->getModuleName(), 'continue', $continue );
 185+ }
 186+
 187+ // more only goes in if there are more entries
 188+ if ($more) {
 189+ $result->addValue( $this->getModuleName(), 'more', $more );
 190+ }
 191+ }
 192+
 193+ /**
 194+ * Sees if there are additional activity rows to view
 195+ *
 196+ * @param string $title the title of the page
 197+ * @param int $feedbackId identifier for the feedback item we are fetching activity for
 198+ * @param mixed $continue used for offsets
 199+ * @return bool true if there are more rows, or false
 200+ */
 201+ protected function fetchHasMore( $title, $feedbackId, $continue = null ) {
 202+ $dbr = wfGetDB( DB_SLAVE );
 203+
 204+ $feedback = $dbr->selectField(
 205+ array( 'logging' ),
 206+ array( 'log_id'),
 207+ array(
 208+ 'log_type' => 'articlefeedbackv5',
 209+ 'log_title' => "ArticleFeedbackv5/$title/$feedbackId",
 210+ 'log_id < ' . intval($continue)
 211+ ),
 212+ __METHOD__,
 213+ array(
 214+ 'LIMIT' => 1
 215+ )
 216+ );
 217+
 218+ return ( (bool) $feedback );
 219+ }
 220+
 221+ /**
 222+ * Gets some base feedback information
 223+ *
 224+ * @param int $feedbackId identifier for the feedback item we are fetching activity for
 225+ * @return int total number of activity items for feedback item
 226+ */
 227+ protected function fetchFeedback( $feedbackId ) {
 228+ $dbr = wfGetDB( DB_SLAVE );
 229+
 230+ $feedback = $dbr->selectRow(
 231+ array( 'aft_article_feedback' ),
 232+ array( 'af_id',
 233+ 'af_page_id',
 234+ 'af_user_id',
 235+ 'af_user_ip',
 236+ 'af_created',
 237+ 'af_activity_count'),
 238+ array(
 239+ 'af_id' => $feedbackId,
 240+ ),
 241+ __METHOD__,
 242+ array(
 243+ 'LIMIT' => 1
 244+ )
 245+ );
 246+
 247+ return $feedback;
 248+ }
 249+
 250+ /**
 251+ * Gets the last 25 (or a requested continuance) of activity rows taken
 252+ * from the log table
 253+ *
 254+ * @param string $title the title of the page
 255+ * @param int $feedbackId identifier for the feedback item we are fetching activity for
 256+ * @param int $limit total limit number
 257+ * @param mixed $continue used for offsets
 258+ * @return array db record rows
 259+ */
 260+ protected function fetchActivity( $title, $feedbackId, $limit = 25, $continue = null) {
 261+
 262+ $where = array (
 263+ 'log_type' => 'articlefeedbackv5',
 264+ 'log_title' => "ArticleFeedbackv5/$title/$feedbackId"
 265+ );
 266+
 267+ if ( null !== $continue ) {
 268+ $where[] = 'log_id < ' . intval($continue);
 269+ }
 270+
 271+ $dbr = wfGetDB( DB_SLAVE );
 272+ $activity = $dbr->select(
 273+ array( 'logging' ),
 274+ array( 'log_id',
 275+ 'log_action',
 276+ 'log_timestamp',
 277+ 'log_user',
 278+ 'log_user_text',
 279+ 'log_title',
 280+ 'log_comment'),
 281+ $where,
 282+ __METHOD__,
 283+ array(
 284+ 'LIMIT' => ($limit + 1),
 285+ 'ORDER BY' => 'log_timestamp DESC'
 286+ )
 287+ );
 288+
 289+ return $activity;
 290+ }
 291+
 292+ /**
 293+ * Gets the allowed parameters
 294+ *
 295+ * @return array the params info, indexed by allowed key
 296+ */
 297+ public function getAllowedParams() {
 298+ return array(
 299+ 'feedbackid' => array(
 300+ ApiBase::PARAM_REQUIRED => true,
 301+ ApiBase::PARAM_TYPE => 'integer',
 302+ ),
 303+ 'limit' => array(
 304+ ApiBase::PARAM_DFLT => 25,
 305+ ApiBase::PARAM_TYPE => 'limit',
 306+ ApiBase::PARAM_MIN => 1,
 307+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 308+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 309+ ),
 310+ 'continue' => null,
 311+ );
 312+ }
 313+
 314+ /**
 315+ * Gets the parameter descriptions
 316+ *
 317+ * @return array the descriptions, indexed by allowed key
 318+ */
 319+ public function getParamDescription() {
 320+ return array(
 321+ 'feedbackid' => 'ID to get feedback activity for',
 322+ 'limit' => 'How many activity results to return',
 323+ 'continue' => 'When more results are available, use this to continue',
 324+ );
 325+ }
 326+
 327+ /**
 328+ * Gets the api descriptions
 329+ *
 330+ * @return array the description as the first element in an array
 331+ */
 332+ public function getDescription() {
 333+ return array(
 334+ 'List article feedback activity for a specified page'
 335+ );
 336+ }
 337+
 338+ /**
 339+ * Gets an example
 340+ *
 341+ * @return array the example as the first element in an array
 342+ */
 343+ protected function getExamples() {
 344+ return array(
 345+ 'api.php?action=query&list=articlefeedbackv5-view-activity&affeedbackid=1',
 346+ );
 347+ }
 348+
 349+ /**
 350+ * Gets the version info
 351+ *
 352+ * @return string the SVN version info
 353+ */
 354+ public function getVersion() {
 355+ return __CLASS__ . ': $Id$';
 356+ }
 357+
 358+ /**
 359+ * Creates a user link for a log row
 360+ *
 361+ * @param stdClass $item row from log table db
 362+ * @return string the SVN version info
 363+ */
 364+ protected function getUserLink($user_id, $user_ip) {
 365+ $userId = (int) $user_id;
 366+ if ( $userId !== 0 ) { // logged-in users
 367+ $user = User::newFromId( $userId );
 368+ } else { // IP users
 369+ $userText = $user_ip;
 370+ $user = User::newFromName( $userText, false );
 371+ }
 372+
 373+ $element = Linker::userLink(
 374+ $user->getId(),
 375+ $user->getName()
 376+ );
 377+ return $element;
 378+ }
 379+}
 380+
Property changes on: trunk/extensions/ArticleFeedbackv5/api/ApiViewActivityArticleFeedbackv5.php
___________________________________________________________________
Added: svn:keywords
1381 + Id

Follow-up revisions

RevisionCommit summaryAuthorDate
r111474bug 34090 - remove a todo - take the note from the flag submission and save i...emsmith19:57, 14 February 2012
r111493r111471/r111472: Update ignore messagesraymond21:25, 14 February 2012
r111552bug 34090 - split activity notes into their own config for maximum length (th...emsmith16:07, 15 February 2012
r111557bug 34090 - changed structure of the link classes and ids per the following f...emsmith16:47, 15 February 2012
r111570bug 34090 - request oversight is now a counter - so you can request/unrequest...emsmith19:53, 15 February 2012
r111573bug 34090 - removed the "header" portion of the html generation from the acti...emsmith20:18, 15 February 2012
r111645bug 34090 - updated the filter count update script to get requested oversight...emsmith15:45, 16 February 2012
r112038bug 34090 - added additional counts for filters including unhidden, undeleted...emsmith20:28, 21 February 2012
r112039bug 34090 - fixed issue noted : if $feedback is false return nothing - not th...emsmith20:50, 21 February 2012
r112041bug 34090 - kill the -1 issue by never letting it get below 0emsmith21:08, 21 February 2012
r112115bug 34090 - no code changes, just fixing/adding keyword svn propertiesemsmith16:31, 22 February 2012
r112119bug 34090 - cast the naughty column so it can be signed, the greatest still k...emsmith16:57, 22 February 2012
r112142bug 34090 - toggle for atomic un/helpful changing (and elimination of an extr...emsmith20:37, 22 February 2012
r112147bug 34090 - note to self, watch the copy and paste errors...emsmith21:01, 22 February 2012
r112149bug 34090 - no upper limit, only lower limit - we can't get any worse then 0emsmith21:21, 22 February 2012
r112154bug 34090 - quick and dirty helper script to get missing documentation keysemsmith21:57, 22 February 2012
r112156bug 34090 - only send the activity header if continue < 1, make the more div ...emsmith22:14, 22 February 2012
r112161bug 34090 - fix limit and use old continue to determine if we do the headeremsmith23:15, 22 February 2012
r112218bug 34090 - make sure the name are right for hidden/unhidden logging (argh)emsmith16:44, 23 February 2012
r112225bug 34090 - unhidden and unoversight logic adjustmentsemsmith18:06, 23 February 2012
r112228bug 34090 - fix filter - needsoversight are always autohiddenemsmith19:16, 23 February 2012
r112230bug 34090 - let's try this again - needsoversight and declined will have hidd...emsmith19:38, 23 February 2012
r112232bug 34090 - hide and show shouldn't fiddle with oversight counts or declined ...emsmith19:48, 23 February 2012
r112599bug 34090 - follow up to r111211 - rename things to make them "less confusin...emsmith14:43, 28 February 2012
r112603bug 34090 - Add the logging of automated hide/show errors by the "Article Fee...emsmith15:21, 28 February 2012
r112604bug 34090 - can't believe there were no permissions checks in this - only del...emsmith15:38, 28 February 2012
r112610bug 34090 - change all sql updates to use escaping except for explicitly comm...emsmith16:22, 28 February 2012
r112611bug 34090 - take out implicit show and add returning user that hid/oversighte...emsmith17:02, 28 February 2012
r112627bug 34090 - follow up to r112599 - change to use getText since it's going int...emsmith18:53, 28 February 2012
r112825bug 34090 - insert custom attributes (sigh) for the user and formatted timest...emsmith18:14, 1 March 2012
r112830bug 34090 - follow up to r111474 - use truncate for choppingemsmith19:42, 1 March 2012
r113052bug 34090 - remaining backend feature in requirements, oversight email genera...emsmith18:04, 5 March 2012
r113062bug 34090 - follow up to r110520 1. change index 2. default of null for conti...emsmith18:54, 5 March 2012
r113073bug 34090 - follow up to r111472 part 1 - change to use getDbKey, check for b...emsmith19:48, 5 March 2012
r113082bug 34090 - follow up to r111471 - changed to use text()emsmith20:42, 5 March 2012
r113083bug 34090 - follow up to rr111472 part 2 - only use log_id for orderingemsmith20:48, 5 March 2012
r113104bug 34090 - follow up to rr111472 part 3 - totally redo the continue function...emsmith23:10, 5 March 2012
r113159bug 34090 - follow up to rr111472 part 4 and follow up to r111596 (same issue...emsmith17:37, 6 March 2012
r113160bug 34090 - follow up to rr111472 part 5 plural and number format action countemsmith17:48, 6 March 2012
r113161bug 34090 - follow up to rr111472 part 6 last of lego messagesemsmith17:53, 6 March 2012
r113163bug 34090 - two additional configuration settings (help url and admin user ur...emsmith18:02, 6 March 2012
r113193bug 34090 - followup to r113104 - only sort by timestamp (sorting by log id w...emsmith22:56, 6 March 2012
r113228bug 34090 - followup to r113160emsmith14:05, 7 March 2012
r113247bug 34090 - db issue, remove one of the sorts from the query, use the ids arr...emsmith16:52, 7 March 2012
r113269bug 34090 - followup to r113247emsmith19:01, 7 March 2012
r113273bug 34090 - add javascript level hiding on request oversight IF autohidden is...emsmith19:22, 7 March 2012
r113287bug 34090 - usernames and formatted timestamps into red lines for hidden/over...emsmith20:22, 7 March 2012
r113311bug 34090 - fixing the username bugs - apparently using the data- stuff with ...emsmith22:34, 7 March 2012
r113317bug 34090 - js and css voodoo to make the element with the red lines appear a...emsmith23:01, 7 March 2012
r113370bug 34090 - make different titles for masking appear if it's been hidden or o...emsmith16:43, 8 March 2012
r113371bug 34090 - fixes for oversighter view for hide/oversight panelsemsmith17:51, 8 March 2012
r113383bug 34090 - not entirely necessary, but keeps $2 from showing up in hiders pa...emsmith19:25, 8 March 2012
r113384bug 34090 - fix for double red line issues when hiding an oversighted post ha...emsmith19:28, 8 March 2012
r113390bug 34090 - adding translation for "automatic hider" useremsmith19:44, 8 March 2012
r113392bug 34090 - followup to r113287 - adjusted localization documentationemsmith20:03, 8 March 2012
r113393bug 34090 - followup to r113370 - adjusted localization documentationemsmith20:05, 8 March 2012

Comments

#Comment by Bsitu (talk | contribs)   22:54, 17 February 2012
// fetch our activity database information
$feedback = $this->fetchFeedback( $feedbackId );

// get the string title for the page
$page = Title::newFromID( $feedback->af_page_id );

$feedback may be a ResultWrapper or boolean false, that should be checked

#Comment by Catrope (talk | contribs)   19:07, 1 March 2012
+ af_activity_count integer unsigned NOT NULL DEFAULT 0
+ if( !$wgUser->isAllowed( 'aftv5-hide-feedback' )) {
+ return;
+ }

You should return an error message rather than just returning nothing. Use $this->dieUsage( "You don't have permission to hide feedback", 'permissiondenied' ); or something.

+ $page = Title::newFromID( $feedback->af_page_id );
+ $title = $page->getPartialURL();

This will throw a fatal error if someone supplies a bad page ID, because Title::newFromID() can return null. This is in addition to what Benny said about $feedback possibly being false. And this also needs ->getText() rather than ->getPartialURL(), just like the other instance we talked about earlier. Note that ->getText() will return a string with spaces rather than underscores, so for use in DB queries against log_title you will need to use ->getDBKey() instead. You can also use ->getDBKey() throughout if you want, the Title constructors accept both text form and dbkey form (but not URL form).

+ // <div>Feedback Post #{$feedbackid} by {$user_link}</div>
+ $html .= Html::openElement( 'div', array() );
+ $html .= wfMessage( 'articlefeedbackv5-activity-feedback-info',
+ array($feedback->af_id))->text()
+ . $this->getUserLink($feedback->af_user_id, $feedback->af_user_ip);
+ $html .= Html::closeElement( 'div' );

This is what we call lego messages, and should be avoided. String concatenation is not a valid replacement for $1 parameters. Instead, you should add a $2 parameter to the message that takes the user link. Because it's HTML, you'll need to use ->rawParams() rather than ->params() to set it.

+ array( $feedback->af_activity_count ))->text() );

This needs number formatting, i.e. array( $wgLang->formatNum( $feedback->af_activity_count ) ) . Also,

+ 'articlefeedbackv5-activity-count' => '$1 actions on this post',

needs pluralization, i.e. $1 actions on this post . This doesn't seem terribly important in English, but other language (either Polish or Russian, I forget) have plural cases that resemble numbering in English (-st, -nd, -rd and -th) so it definitely matters for those.

+ $html .= $this->getUserLink($item->log_user, $item->log_user_text)
+ . Html::element( 'div', array(),
+ wfMessage( 'articlefeedbackv5-activity-' . $item->log_action,
+ array())->text() )
+ . $wgLang->timeanddate( $item->log_timestamp );

This is also lego.

+ if (!empty($item->log_comment)) {

Don't use empty(), it suppresses all errors, so if someone misspelled log_comment here no one would ever find out. Perhaps you meant !$item->log_comment or $item->log_comment == or something else.

+ // figure out if we have more based on our new continue value
+ $more = $this->fetchHasMore($title, $feedbackId, $continue);

The preferred way to do paging in MediaWiki is to fetch one row more than you need (i.e. 'LIMIT' => $limit + 1) and then have a counter that ensures that excess row is never output, but its ID is used as the continue value. This is different from what you're doing, you're outputting the ID of the last row as the continue value and then checking separately if there are more results. With my suggested approach, you would have to use foo >= $continue rather than foo > $continue , but you wouldn't have to check separately if there are more results (presence or absence of the excess row indicates this) and you wouldn't have to output this fact separately either (presence or absence of the continue parameter indicates this).

Reading the actual query, it looks like you are requesting $limit+1 rows, but the code that processes these rows is not aware of it? I don't quite get it.

+ $result->addValue( $this->getModuleName(), 'continue', $continue );

The standard way of doing this is $this->setContinueEnumParameter( 'continue', $continue ); . That will put it in the query-continue element.

+ $where[] = 'log_id < ' . intval($continue);
[...]
+ 'ORDER BY' => 'log_timestamp DESC'

These don't mix well together (read: the database really will not like this query). You'll need to do your ordering and your continuation using the same field or set of fields. I think you can probably get away with ordering by log_id instead of log_timestamp, because out-of-order entries should be very rare and will probably only be off by one or two seconds if at all (and presumably your timestamp display in the UI shows timestamps to the minute, not to the second).

+ parent::__construct( $query, $moduleName, 'af' );

Module prefixes should be unique, and I'm pretty sure 'af' is already in use by another AFTv5 module.

#Comment by Elizabeth M Smith (talk | contribs)   17:53, 6 March 2012

These should now all be fixed - took at least 6 different commits for the different issues

#Comment by Catrope (talk | contribs)   22:36, 6 March 2012

Looks like this has all been taken care of.

Status & tagging log