Revision: 51638
Author:   werdna
Date:     2009-06-09 12:27:15 +0000 (Tue, 09 Jun 2009)

Log Message:
-----------
Reimplemented writeMessageStateForUpdated thread:
* Improve cross-database compatibility (and code readability) by using proper 
generation methods.
* Basic implementation of LQT email notification.
* TODO : Implement email notification for discussions on a user's talk page.

Modified Paths:
--------------
    trunk/extensions/LiquidThreads/LiquidThreads.php
    trunk/extensions/LiquidThreads/Lqt.i18n.php
    trunk/extensions/LiquidThreads/LqtFunctions.php
    trunk/extensions/LiquidThreads/classes/LqtNewMessages.php
    trunk/extensions/LiquidThreads/classes/LqtThread.php
    trunk/extensions/LiquidThreads/classes/LqtThreads.php
    trunk/extensions/LiquidThreads/classes/LqtView.php

Modified: trunk/extensions/LiquidThreads/LiquidThreads.php
===================================================================
--- trunk/extensions/LiquidThreads/LiquidThreads.php    2009-06-09 11:05:46 UTC 
(rev 51637)
+++ trunk/extensions/LiquidThreads/LiquidThreads.php    2009-06-09 12:27:15 UTC 
(rev 51638)
@@ -49,6 +49,7 @@
 $wgHooks['OldChangesListRecentChangesLine'][] = 
'LqtDispatch::customizeOldChangesList';
 $wgHooks['SkinTemplateOutputPageBeforeExec'][] = 'LqtDispatch::setNewtalkHTML';
 $wgHooks['TitleGetRestrictions'][] = 'Thread::getRestrictionsForTitle';
+$wgHooks['GetPreferences'][] = 'lqtGetPreferences';
 
 // Special pages
 $wgSpecialPages['DeleteThread'] = 'SpecialDeleteThread';
@@ -91,6 +92,9 @@
 $wgLogHeaders['liquidthreads']        = 'lqt-log-header';
 $wgLogActionsHandlers['liquidthreads/move'] = 'lqtFormatMoveLogEntry';
 
+// Preferences
+$wgDefaultUserOptions['lqtnotifytalk'] = true;
+
 /** CONFIGURATION SECTION */
 
 /* Number of days a thread needs to have existed to be considered for 
summarizing and archival */
@@ -105,3 +109,6 @@
 /* Allows switching LiquidThreads off for regular talk pages
        (intended for testing and transition) */
 $wgLqtTalkPages = true;
+
+/* Whether or not to activate LiquidThreads email notifications */
+$wgLqtEnotif = true;

Modified: trunk/extensions/LiquidThreads/Lqt.i18n.php
===================================================================
--- trunk/extensions/LiquidThreads/Lqt.i18n.php 2009-06-09 11:05:46 UTC (rev 
51637)
+++ trunk/extensions/LiquidThreads/Lqt.i18n.php 2009-06-09 12:27:15 UTC (rev 
51638)
@@ -151,6 +151,23 @@
        'lqt-log-name' => 'Threaded discussion log',
        'lqt-log-header' => 'This log details actions taken on discussion 
threads.',
        'lqt-log-action-move' => 'moved [[$1]] from [[$2]] to [[$3]].',
+       
+       // Preferences
+       'lqt-preference-notify-talk' => 'Email me when somebody replies to a 
thread I am watching',
+       
+       // Email notification
+       'lqt-enotif-subject-reply' => '{{SITENAME}} discussion - Reply: $1',
+       'lqt-enotif-subject-newthread' => '{{SITENAME}} discussion - New 
thread: $1',
+       'lqt-enotif-newthread' => "Hi $1,
+This is a notification from {{SITENAME}} that a new thread on $5, '$2',
+was created on $3 at $4.
+
+You can see it at <$6>",
+       'lqt-enotif-reply' => "Hi $1,
+This is a notification from {{SITENAME}} that a new reply to '$2' on $5,
+was created on $3 at $4.
+
+You can see it at <$6>",
 );
 
 /** Message documentation (Message documentation)

Modified: trunk/extensions/LiquidThreads/LqtFunctions.php
===================================================================
--- trunk/extensions/LiquidThreads/LqtFunctions.php     2009-06-09 11:05:46 UTC 
(rev 51637)
+++ trunk/extensions/LiquidThreads/LqtFunctions.php     2009-06-09 12:27:15 UTC 
(rev 51638)
@@ -102,3 +102,15 @@
        return wfMsgExt( 'lqt-log-action-move', 'parseinline',
                                        array( $title->getPrefixedText(), 
$parameters[0], $parameters[1] ) );
 }
+
+function lqtGetPreferences( $user, &$preferences ) {
+       wfLoadExtensionMessages( 'LiquidThreads' );
+       $preferences['lqtnotifytalk'] =
+               array(
+                       'type' => 'toggle',
+                       'label-message' => 'lqt-preference-notify-talk',
+                       'section' => 'personal/email'
+               );
+       
+       return true;
+}

Modified: trunk/extensions/LiquidThreads/classes/LqtNewMessages.php
===================================================================
--- trunk/extensions/LiquidThreads/classes/LqtNewMessages.php   2009-06-09 
11:05:46 UTC (rev 51637)
+++ trunk/extensions/LiquidThreads/classes/LqtNewMessages.php   2009-06-09 
12:27:15 UTC (rev 51638)
@@ -40,40 +40,167 @@
         * Write a user_message_state for each user who is watching the thread.
         * If the thread is on a user's talkpage, set that user's newtalk.
        */
-       static function writeMessageStateForUpdatedThread( $t ) {
+       static function writeMessageStateForUpdatedThread( $t, $type, 
$changeUser ) {
                global $wgDBprefix, $wgUser;
+               
+               wfDebugLog( 'LiquidThreads', 'Doing notifications' );
 
                if ( $t->article()->getTitle()->getNamespace() == NS_USER ) {
                        $name = $t->article()->getTitle()->getDBkey();
                        list( $name ) = split( '/', $name ); // subpages
                        $user = User::newFromName( $name );
-                       if ( $user && $user->getID() != $wgUser->getID() ) {
+                       if ( $user && $user->getID() != $changeUser->getID() ) {
                                $user->setNewtalk( true );
                        }
                }
 
                $dbw =& wfGetDB( DB_MASTER );
 
-               $talkpage_t = $t->article()->getTitle();
+               $talkpage_t = $t->article()->getTitle()->getSubjectPage();
                $root_t = $t->root()->getTitle();
 
                $q_talkpage_t = $dbw->addQuotes( $talkpage_t->getDBkey() );
                $q_root_t = $dbw->addQuotes( $root_t->getDBkey() );
 
                // Select any applicable watchlist entries for the thread.
-               $where_clause = <<<SQL
-(
-       (wl_namespace = {$talkpage_t->getNamespace()} and wl_title = 
$q_talkpage_t )
-or     (wl_namespace = {$root_t->getNamespace()} and wl_title = $q_root_t )
-)
-SQL;
+               $talkpageWhere = array( 'wl_namespace' => 
$talkpage_t->getNamespace(),
+                                                               'wl_title' => 
$talkpage_t->getDBkey() );
+               $rootWhere = array( 'wl_namespace' => $root_t->getNamespace(),
+                                                               'wl_title' => 
$root_t->getDBkey() );
+                                                               
+               $talkpageWhere = $dbw->makeList( $talkpageWhere, LIST_AND );
+               $rootWhere = $dbw->makeList( $rootWhere, LIST_AND );
+               
+               $where_clause = $dbw->makeList( array( $talkpageWhere, 
$rootWhere ), LIST_OR );
 
                // it sucks to not have 'on duplicate key update'. first update 
users who already have a ums for this thread
                // and who have already read it, by setting their state to 
unread.
-               $dbw->query( "update {$wgDBprefix}user_message_state, 
{$wgDBprefix}watchlist set ums_read_timestamp = null where ums_user = wl_user 
and ums_thread = {$t->id()} and $where_clause" );
-
-               $dbw->query( "insert ignore into 
{$wgDBprefix}user_message_state (ums_user, ums_thread) select user_id, 
{$t->id()} from {$wgDBprefix}user, {$wgDBprefix}watchlist where user_id = 
wl_user and $where_clause;" );
+               
+               // Pull users to update the message state for, including 
whether or not a
+               //  user_message_state row exists for them, and whether or not 
to send an email
+               //  notification.
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select(  array( 'watchlist', 'user_message_state', 
'user_properties' ),
+                                                               array( 
'wl_user', 'ums_user', 'ums_read_timestamp', 'up_value' ),
+                                                               $where_clause, 
__METHOD__, array(),
+                                                               array( 
'user_message_state' =>
+                                                                       array( 
'left join',  array( 'ums_user=wl_user',
+                                                                               
'ums_thread' => $t->id() ) ),
+                                                                       
'user_properties' => array(
+                                                                               
'left join',
+                                                                               
array( 'up_user=wl_user',
+                                                                               
        'up_property' => 'lqtnotifytalk',
+                                                                               
)
+                                                                       ),
+                                                               )
+                                                       );
+               
+               $insert_rows = array();
+               $update_tuples = array();
+               $notify_users = array();
+               while( $row = $dbr->fetchObject( $res ) ) {
+                       // Don't notify yourself
+                       if ( $changeUser->getId() == $row->wl_user )
+                               continue;
+                               
+                       if ( $row->ums_read_timestamp ) {
+                               $conds = array( 'ums_user' => $row->ums_user,
+                                                               'ums_thread' => 
$t->id() );
+                               $update_tuples[$row->ums_user.$t->id()] = 
$dbw->makeList( $conds, LIST_AND );   
+                       } elseif ( $row->ums_user ) {
+                               // It's already positive.
+                       } else {
+                               $insert_rows[] =
+                                       array(
+                                               'ums_user' => $row->wl_user,
+                                               'ums_thread' => $t->id(),
+                                       );
+                       }
+                       
+                       if ( ( is_null($row->up_value) && 
User::getDefaultOption( 'lqtnotifytalk' ) )
+                                       || $row->up_value ) {
+                               $notify_users[] = $row->wl_user;
+                       }
+               }
+               
+               // Avoids duplicates
+               $update_tuples = array_values( $update_tuples );
+               
+               // Do the actual updates
+               if ( count($insert_rows) ) {
+                       $dbw->insert( 'user_message_state', $insert_rows, 
__METHOD__, array( 'IGNORE' ) );
+               }
+               if ( count($update_tuples) ) {
+                       $where = $dbw->makeList( $update_tuples, LIST_OR );
+                       
+                       $dbw->update( 'user_message_state', array( 
'ums_read_timestamp' => null ),
+                                                       array($where), 
__METHOD__ );
+               }
+               
+               if ( count($notify_users) ) {
+                       self::notifyUsersByMail( $t, $notify_users, 
wfTimestampNow(), $type );
+               }
        }
+       
+       static function notifyUsersByMail( $t, $watching_users, $timestamp, 
$type ) {
+               wfLoadExtensionMessages( 'LiquidThreads' );
+               $messages = array(
+                       Threads::CHANGE_REPLY_CREATED => 'lqt-enotif-reply',
+                       Threads::CHANGE_NEW_THREAD => 'lqt-enotif-newthread',
+               );
+               $subjects = array(
+                       Threads::CHANGE_REPLY_CREATED => 
'lqt-enotif-subject-reply',
+                       Threads::CHANGE_NEW_THREAD => 
'lqt-enotif-subject-newthread',
+               );
+                       
+               if ( !isset($messages[$type]) || !isset($subjects[$type]) ) {
+                       wfDebugLog( 'LiquidThreads', "Email notification 
failed: type $type unrecognised" );
+                       return;
+               } else {
+                       $msgName = $messages[$type];
+                       $subjectMsg = $subjects[$type];
+               }
+               
+               // Send email notification, fetching all the data in one go
+               $dbr = wfGetDB( DB_SLAVE );
+               $res = $dbr->select( array( 'user', 'user_properties' ), '*',
+                                                       array( 'user_id' => 
$watching_users ), __METHOD__, array(),
+                                                       array( 
'user_properties' =>
+                                                               array( 'left 
join', 
+                                                                       array(
+                                                                               
'up_user=user_id',
+                                                                               
'up_property' => 'timecorrection'
+                                                                       )
+                                                               )
+                                                       )
+                                               );
+               
+               while( $row = $dbr->fetchObject( $res ) ) {
+                       $u = User::newFromRow( $row );
+                       
+                       global $wgLang;
+                       
+                       $permalink = LqtView::permalinkUrl( $t );
+                       
+                       // Adjust with time correction
+                       $adjustedTimestamp = $wgLang->userAdjust( $timestamp, 
$row->up_value );
+                       
+                       $date = $wgLang->date( $adjustedTimestamp );
+                       $time = $wgLang->time( $adjustedTimestamp );
+                       
+                       $talkPage = 
$t->article()->getTitle()->getPrefixedText();
+                       $msg = wfMsg( $msgName, $u->getName(), 
$t->subjectWithoutIncrement(),
+                                                       $date, $time, 
$talkPage, $permalink );
+                                                       
+                       global $wgPasswordSender;
+                                                       
+                       $from = new MailAddress( $wgPasswordSender, 'WikiAdmin' 
);
+                       $to   = new MailAddress( $u );
+                       $subject = wfMsg( $subjectMsg, 
$t->subjectWithoutIncrement() );
+                       
+                       UserMailer::send( $to, $from, $subject, $msg );
+               }
+       }
 
        static function newUserMessages( $user ) {
                global $wgDBprefix;

Modified: trunk/extensions/LiquidThreads/classes/LqtThread.php
===================================================================
--- trunk/extensions/LiquidThreads/classes/LqtThread.php        2009-06-09 
11:05:46 UTC (rev 51637)
+++ trunk/extensions/LiquidThreads/classes/LqtThread.php        2009-06-09 
12:27:15 UTC (rev 51638)
@@ -160,7 +160,7 @@
                     __METHOD__ );
 
                if ( $change_type == Threads::CHANGE_EDITED_ROOT ) {
-                       NewMessages::writeMessageStateForUpdatedThread( $this );
+                       NewMessages::writeMessageStateForUpdatedThread( $this, 
$change_type, $wgUser );
                }
        }
 

Modified: trunk/extensions/LiquidThreads/classes/LqtThreads.php
===================================================================
--- trunk/extensions/LiquidThreads/classes/LqtThreads.php       2009-06-09 
11:05:46 UTC (rev 51637)
+++ trunk/extensions/LiquidThreads/classes/LqtThreads.php       2009-06-09 
12:27:15 UTC (rev 51638)
@@ -105,7 +105,7 @@
 
                self::createTalkpageIfNeeded( $article );
 
-               NewMessages::writeMessageStateForUpdatedThread( $newthread );
+               NewMessages::writeMessageStateForUpdatedThread( $newthread, 
$change_type, $wgUser );
 
                return $newthread;
        }

Modified: trunk/extensions/LiquidThreads/classes/LqtView.php
===================================================================
--- trunk/extensions/LiquidThreads/classes/LqtView.php  2009-06-09 11:05:46 UTC 
(rev 51637)
+++ trunk/extensions/LiquidThreads/classes/LqtView.php  2009-06-09 12:27:15 UTC 
(rev 51638)
@@ -176,6 +176,18 @@
                if ( is_array( $query ) ) $query = self::queryStringFromArray( 
$query );
                return $thread->root()->getTitle()->getFullUrl( $query );
        }
+       
+       static function permalink( $thread, $text = null, $method = null, 
$operand = null,
+                                                               $sk = null, 
$attribs = array() ) {
+               if ( is_null($sk) ) {
+                       global $wgUser;
+                       $sk = $wgUser->getSkin();
+               }
+               
+               list( $title, $query ) = self::permalinkData( $thread, $method, 
$operand );
+               
+               return $sk->link( $title, $text, $attribs, $query );
+       }
 
        static function permalinkUrlWithDiff( $thread ) {
                $changed_thread = $thread->changeObject();



_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to