| Current File : /home/jvzmxxx/wiki1/extensions/Flow/includes/Import/Postprocessor/LqtNotifications.php |
<?php
namespace Flow\Import\Postprocessor;
use DatabaseBase;
use BatchRowIterator;
use EchoCallbackIterator;
use EchoEvent;
use Flow\Import\IImportHeader;
use Flow\Import\IImportPost;
use Flow\Import\IImportTopic;
use Flow\Import\ImportException;
use Flow\Import\LiquidThreadsApi\ImportTopic as LqtImportTopic;
use Flow\Import\PageImportState;
use Flow\Import\TopicImportState;
use Flow\Model\PostRevision;
use Flow\NotificationController;
use RecursiveIteratorIterator;
use User;
/**
* Converts LQT unread notifications into Echo notifications after a topic is imported
*/
class LqtNotifications implements Postprocessor {
/**
* @var NotificationController
*/
protected $controller;
/**
* @var DatabaseBase
*/
protected $dbw;
/**
* @var PostRevision[] Array of imported replies
*/
protected $postsImported = array();
public function __construct( NotificationController $controller, DatabaseBase $dbw ) {
$this->controller = $controller;
$this->dbw = $dbw;
$this->overrideUsersToNotify();
}
/**
* evil, but what should we do instead? This basically removes the default methods
* of determining users to notify so they can be replaced with this class during imports.
*/
protected function overrideUsersToNotify() {
global $wgEchoNotifications;
// Remove the user-locators that choose on a per-notification basis who
// should be notified.
$notifications = require __DIR__ . '/../../Notifications/Notifications.php';
foreach ( array_keys( $notifications ) as $type ) {
unset( $wgEchoNotifications[$type]['user-locators'] );
// The job queue causes our overrides to be lost since it
// has a separate execution context.
$wgEchoNotifications[$type]['immediate'] = true;
}
// Insert our own user locator to decide who should be notified.
// Note this has to be a closure rather than direct callback due to how
// echo considers an array to be extra parameters.
// Overrides existing user-locators, because we don't want unintended
// notifications to go out here.
$self = $this;
$wgEchoNotifications['flow-post-reply']['user-locators'] = array(
function( EchoEvent $event ) use ( $self ) {
return $self->locateUsersWithPendingLqtNotifications( $event );
}
);
}
/**
* @param EchoEvent $event
* @param int $batchSize
* @throws ImportException
* @return \Iterator[User]
*/
public function locateUsersWithPendingLqtNotifications( EchoEvent $event, $batchSize = 500 ) {
$activeThreadId = $event->getExtraParam( 'lqtThreadId' );
if ( $activeThreadId === null ) {
throw new ImportException( 'No active thread!' );
}
$it = new BatchRowIterator(
$this->dbw,
/* table = */ 'user_message_state',
/* primary keys */ array( 'ums_user' ),
$batchSize
);
$it->addConditions( array(
'ums_conversation' => $activeThreadId,
'ums_read_timestamp' => null,
) );
// flatten result into a stream of rows
$it = new RecursiveIteratorIterator( $it );
// add callback to convert user id to user objects
$it = new EchoCallbackIterator( $it, function( $row ) {
return User::newFromId( $row->ums_user );
} );
return $it;
}
public function afterTopicImported( TopicImportState $state, IImportTopic $topic ) {
if ( !$topic instanceof LqtImportTopic ) {
return;
}
if ( empty( $this->postsImported ) ) {
// nothing was imported in this topic
return;
}
$this->controller->notifyPostChange( 'flow-post-reply', array(
'revision' => $this->postsImported[0],
'topic-title' => $state->topicTitle,
'topic-workflow' => $state->topicWorkflow,
'title' => $state->topicWorkflow->getOwnerTitle(),
'reply-to' => $state->topicTitle,
'extra-data' => array(
'lqtThreadId' => $topic->getLqtThreadId(),
'notifyAgent' => true,
),
'timestamp' => $topic->getTimestamp(),
) );
$this->postsImported = array();
}
public function importAborted() {
$this->postsImported = array();
}
public function afterHeaderImported( PageImportState $state, IImportHeader $header ) {
// not a thing to do, yet
}
public function afterPostImported( TopicImportState $state, IImportPost $post, PostRevision $newPost ) {
$this->postsImported[] = $newPost;
}
}