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