Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
76.19% covered (warning)
76.19%
16 / 21
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
SummaryParser
76.19% covered (warning)
76.19%
16 / 21
50.00% covered (danger)
50.00%
1 / 2
12.63
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 parse
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3namespace MediaWiki\Extension\Notifications;
4
5use MediaWiki\Title\Title;
6use MediaWiki\User\User;
7
8class SummaryParser {
9    /** @var callable */
10    private $userLookup;
11
12    /**
13     * @param callable|null $userLookup Function that receives User object and returns its id
14     *  or 0 if the user doesn't exist. Passing null to this parameter will result in default
15     *  implementation being used.
16     */
17    public function __construct( callable $userLookup = null ) {
18        $this->userLookup = $userLookup;
19        if ( !$this->userLookup ) {
20            $this->userLookup = static function ( User $user ) {
21                return $user->getId();
22            };
23        }
24    }
25
26    /**
27     * Returns a list of registered users linked in an edit summary
28     *
29     * @param string $summary
30     * @return User[] Array of username => User object
31     */
32    public function parse( $summary ) {
33        // Remove section autocomments. Replace with characters that can't be in titles,
34        // to prevent fun stuff like "[[foo /* section */ bar]]".
35        $summary = preg_replace( '#/\*.*?\*/#', ' [] ', $summary );
36
37        $users = [];
38        $regex = '/\[\[([' . Title::legalChars() . ']++)(?:\|.*?)?\]\]/';
39        if ( preg_match_all( $regex, $summary, $matches ) ) {
40            foreach ( $matches[1] as $match ) {
41                if ( $match[0] === ':' ) {
42                    continue;
43                }
44
45                $title = Title::newFromText( $match );
46                if ( $title
47                     && $title->isLocal()
48                     && $title->getNamespace() === NS_USER
49                ) {
50                    $user = User::newFromName( $title->getText() );
51                    $lookup = $this->userLookup;
52                    if ( $user && $lookup( $user ) > 0 ) {
53                        $users[$user->getName()] = $user;
54                    }
55                }
56            }
57        }
58
59        return $users;
60    }
61}