Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 33 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
Hooks | |
0.00% |
0 / 33 |
|
0.00% |
0 / 7 |
240 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onListDefinedTags | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onChangeTagsListActive | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
addChangeTags | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
onRecentChange_save | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
72 | |||
onAbuseFilter_generateUserVars | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
6 | |||
onAbuseFilterBuilder | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\MobileApp; |
4 | |
5 | use ChangeTags; |
6 | use MediaWiki\ChangeTags\Hook\ChangeTagsListActiveHook; |
7 | use MediaWiki\ChangeTags\Hook\ListDefinedTagsHook; |
8 | use MediaWiki\Extension\AbuseFilter\Variables\VariableHolder; |
9 | use MediaWiki\Hook\RecentChange_saveHook; |
10 | use MediaWiki\User\User; |
11 | use RecentChange; |
12 | use Wikimedia\Rdbms\IConnectionProvider; |
13 | |
14 | class Hooks implements |
15 | ListDefinedTagsHook, |
16 | ChangeTagsListActiveHook, |
17 | RecentChange_saveHook |
18 | { |
19 | private IConnectionProvider $dbProvider; |
20 | |
21 | public function __construct( |
22 | IConnectionProvider $dbProvider |
23 | ) { |
24 | $this->dbProvider = $dbProvider; |
25 | } |
26 | |
27 | /** |
28 | * ListDefinedTags hook handler |
29 | * @see https://www.mediawiki.org/wiki/Manual:Hooks/ListDefinedTags |
30 | * |
31 | * @param array &$tags |
32 | */ |
33 | public function onListDefinedTags( &$tags ) { |
34 | $this->addChangeTags( $tags ); |
35 | } |
36 | |
37 | /** |
38 | * ChangeTagsListActive hook handler |
39 | * @see https://www.mediawiki.org/wiki/Manual:Hooks/ChangeTagsListActive |
40 | * |
41 | * @param array &$tags |
42 | */ |
43 | public function onChangeTagsListActive( &$tags ) { |
44 | $this->addChangeTags( $tags ); |
45 | } |
46 | |
47 | /** |
48 | * @param array &$tags |
49 | */ |
50 | private function addChangeTags( &$tags ) { |
51 | $tags[] = 'mobile edit'; |
52 | $tags[] = 'mobile app edit'; |
53 | $tags[] = 'android app edit'; |
54 | $tags[] = 'ios app edit'; |
55 | } |
56 | |
57 | /** |
58 | * RecentChange_save hook handler that tags mobile changes |
59 | * @see https://www.mediawiki.org/wiki/Manual:Hooks/RecentChange_save |
60 | * @param RecentChange $rc |
61 | */ |
62 | public function onRecentChange_save( $rc ) { |
63 | global $wgRequest; |
64 | $userAgent = $wgRequest->getHeader( "User-agent" ); |
65 | $isWikipediaApp = strpos( $userAgent, "WikipediaApp/" ) === 0; |
66 | $isCommonsApp = strpos( $userAgent, "Commons/" ) === 0; |
67 | $logType = $rc->getAttribute( 'rc_log_type' ); |
68 | |
69 | // Apply tag for edits done with the Wikipedia app, and |
70 | // edits and uploads done with the Commons app |
71 | if ( |
72 | ( $isWikipediaApp && $logType === null ) |
73 | || ( $isCommonsApp && ( $logType === null || $logType === 'upload' ) ) |
74 | ) { |
75 | // Although MobileFrontend applies the "mobile edit" tag to any edit |
76 | // that is made through the mobile domain, the Android app actually |
77 | // makes its API requests through the desktop domain, meaning that we |
78 | // must apply the "mobile edit" tag explicitly ourselves, in addition |
79 | // to the "mobile app edit" tag. |
80 | $tags = [ 'mobile edit', 'mobile app edit' ]; |
81 | |
82 | $isAndroid = strpos( $userAgent, "Android" ) > 0; |
83 | $isIOS = strpos( $userAgent, "iOS" ) > 0; |
84 | |
85 | if ( $isAndroid ) { |
86 | $tags[] = 'android app edit'; |
87 | } elseif ( $isIOS ) { |
88 | $tags[] = 'ios app edit'; |
89 | } |
90 | |
91 | $rc->addTags( $tags ); |
92 | } |
93 | } |
94 | |
95 | /** |
96 | * AbuseFilter-generateUserVars hook handler that adds the user_app variable. |
97 | * |
98 | * @see hooks.txt in AbuseFilter extension |
99 | * @param VariableHolder $vars object to add vars to |
100 | * @param User $user |
101 | * @param RecentChange|null $rc If the variables should be generated for an RC entry, this |
102 | * is the entry. Null if it's for the current action being filtered. |
103 | * @return bool |
104 | */ |
105 | public function onAbuseFilter_generateUserVars( $vars, $user, RecentChange $rc = null ) { |
106 | global $wgRequest; |
107 | if ( !$rc ) { |
108 | $userAgent = $wgRequest->getHeader( "User-agent" ); |
109 | $isWikipediaApp = strpos( $userAgent, "WikipediaApp/" ) === 0; |
110 | $vars->setVar( 'user_app', $isWikipediaApp ); |
111 | } else { |
112 | $dbr = $this->dbProvider->getReplicaDatabase(); |
113 | $tags = ChangeTags::getTags( $dbr, $rc->getAttribute( 'rc_id' ) ); |
114 | $vars->setVar( 'user_app', in_array( 'mobile app edit', $tags, true ) ); |
115 | } |
116 | return true; |
117 | } |
118 | |
119 | /** |
120 | * AbuseFilter-builder hook handler that adds user_app variable to list |
121 | * of valid vars |
122 | * |
123 | * @param array &$builder Array in AbuseFilter::getBuilderValues to add to. |
124 | * @return bool |
125 | */ |
126 | public static function onAbuseFilterBuilder( &$builder ) { |
127 | $builder['vars']['user_app'] = 'user-app'; |
128 | return true; |
129 | } |
130 | } |