Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
UserLocator
0.00% covered (danger)
0.00%
0 / 38
0.00% covered (danger)
0.00%
0 / 4
110
0.00% covered (danger)
0.00%
0 / 1
 locateUsersWatchingTopic
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 locatePostAuthors
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 locateMentionedUsers
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getCreatorsFromPostIDs
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace Flow\Notifications;
4
5use Flow\Container;
6use Flow\Data\ManagerGroup;
7use Flow\Model\UUID;
8use Flow\RevisionActionPermissions;
9use MediaWiki\Extension\Notifications\Model\Event;
10use MediaWiki\Title\Title;
11use MediaWiki\User\User;
12
13class UserLocator extends \MediaWiki\Extension\Notifications\UserLocator {
14    /**
15     * Return all users watching the topic the event was for.
16     *
17     * The echo job queue must be enabled to prevent timeouts submitting to
18     * heavily watched pages when this is used.
19     *
20     * @param Event $event
21     * @return User[]
22     */
23    public static function locateUsersWatchingTopic( Event $event ) {
24        $workflowId = $event->getExtraParam( 'topic-workflow' );
25        if ( !$workflowId instanceof UUID ) {
26            // something wrong; don't notify anyone
27            return [];
28        }
29
30        // topic title is just the workflow id, but in NS_TOPIC
31        $title = Title::makeTitleSafe( NS_TOPIC, $workflowId->getAlphadecimal() );
32
33        /*
34         * Override title associated with this event. The existing code to
35         * locate users watching something uses the title associated with the
36         * event, which in this case is the board page.
37         * However, here, we're looking to get users who've watchlisted a
38         * specific NS_TOPIC page.
39         * I'm temporarily substituting the event's title so we can piggyback on
40         * locateUsersWatchingTitle instead of duplicating it.
41         */
42        $originalTitle = $event->getTitle();
43        $event->setTitle( $title );
44
45        $users = parent::locateUsersWatchingTitle( $event );
46
47        // reset original title
48        $event->setTitle( $originalTitle );
49
50        return $users;
51    }
52
53    /**
54     * @param Event $event
55     * @return User[]
56     */
57    public static function locatePostAuthors( Event $event ) {
58        $extra = $event->getExtra();
59        $postId = $extra['reply-to'] ?? $extra['post-id'];
60
61        if ( !$postId instanceof UUID ) {
62            // something wrong; don't notify anyone
63            return [];
64        }
65
66        return self::getCreatorsFromPostIDs( [ $postId ] );
67    }
68
69    /**
70     * @param Event $event
71     * @return array
72     */
73    public static function locateMentionedUsers( Event $event ) {
74        $userIds = $event->getExtraParam( 'mentioned-users', [] );
75        return array_map( [ 'User', 'newFromId' ], $userIds );
76    }
77
78    /**
79     * Retrieves the post creators from a set of posts.
80     *
81     * @param array $posts Array of UUIDs or hex representations
82     * @return User[] Associative array, of user ID => User object.
83     */
84    protected static function getCreatorsFromPostIDs( array $posts ) {
85        $users = [];
86        /** @var ManagerGroup $storage */
87        $storage = Container::get( 'storage' );
88
89        $user = new User;
90        $actionPermissions = new RevisionActionPermissions( Container::get( 'flow_actions' ), $user );
91
92        foreach ( $posts as $postId ) {
93            $post = $storage->find(
94                'PostRevision',
95                [
96                    'rev_type_id' => UUID::create( $postId )
97                ],
98                [
99                    'sort' => 'rev_id',
100                    'order' => 'DESC',
101                    'limit' => 1
102                ]
103            );
104
105            $post = reset( $post );
106
107            if ( $post && $actionPermissions->isAllowed( $post, 'view' ) ) {
108                $userid = $post->getCreatorId();
109                if ( $userid ) {
110                    $users[$userid] = User::newFromId( $userid );
111                }
112            }
113        }
114
115        return $users;
116    }
117}