Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
5.41% |
2 / 37 |
|
25.00% |
2 / 8 |
CRAP | |
0.00% |
0 / 1 |
AccountCreationLogger | |
5.41% |
2 / 37 |
|
25.00% |
2 / 8 |
113.42 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
logAuthEvent | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
doLogEvent | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
submitEvent | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
logLoginEvent | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
logAccountCreationEvent | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
logPageImpression | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
determineStreamForPage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace WikimediaEvents; |
4 | |
5 | use MediaWiki\Auth\AuthenticationResponse; |
6 | use MediaWiki\Context\RequestContext; |
7 | use MediaWiki\Extension\EventLogging\EventLogging; |
8 | use MediaWiki\Page\PageReference; |
9 | use MediaWiki\SpecialPage\SpecialPageFactory; |
10 | use MediaWiki\User\UserIdentity; |
11 | use MediaWiki\User\UserIdentityUtils; |
12 | use MediaWiki\WikiMap\WikiMap; |
13 | |
14 | class AccountCreationLogger { |
15 | |
16 | private const SCHEMA_VERSIONED = '/analytics/mediawiki/accountcreation/account_conversion/1.0.0'; |
17 | private const STREAM_REGISTER = 'mediawiki.accountcreation.account_conversion'; |
18 | private const STREAM_LOGIN = 'mediawiki.accountcreation.login'; |
19 | private SpecialPageFactory $specialPageFactory; |
20 | /** |
21 | * @var UserIdentityUtils |
22 | */ |
23 | private UserIdentityUtils $userIdentityUtils; |
24 | |
25 | /** |
26 | * @var array Mapping of special page titles to their corresponding event streams. |
27 | */ |
28 | private $pageStreamMap = [ |
29 | 'CreateAccount' => self::STREAM_REGISTER, |
30 | 'Userlogin' => self::STREAM_LOGIN, |
31 | ]; |
32 | |
33 | public function __construct( UserIdentityUtils $userIdentityUtils, SpecialPageFactory $specialPageFactory ) { |
34 | $this->userIdentityUtils = $userIdentityUtils; |
35 | $this->specialPageFactory = $specialPageFactory; |
36 | } |
37 | |
38 | /** |
39 | * Handles logging of authentication and account creation events. |
40 | * |
41 | * @param string $stream The stream event. |
42 | * @param string $eventType The event type ('success' or 'failure'). |
43 | * @param UserIdentity $performer The user involved in the event. |
44 | * @param AuthenticationResponse $response The authentication response. |
45 | */ |
46 | public function logAuthEvent( |
47 | string $stream, string $eventType, UserIdentity $performer, AuthenticationResponse $response ): void { |
48 | $additionalData = []; |
49 | $title = RequestContext::getMain()->getTitle(); |
50 | if ( $title !== null ) { |
51 | $additionalData += [ |
52 | 'page_title' => $title->getDBkey(), |
53 | 'page_namespace' => $title->getNamespace(), |
54 | ]; |
55 | } |
56 | if ( $response->status === AuthenticationResponse::FAIL ) { |
57 | $additionalData['error_message_key'] = $response->message->getKey(); |
58 | } |
59 | $this->doLogEvent( $stream, $eventType, $performer, $additionalData ); |
60 | } |
61 | |
62 | /** |
63 | * Logs different types of events (e.g., impressions, successes, failures) |
64 | * related to account creation and user login. |
65 | * |
66 | * @param string $stream The stream event. |
67 | * @param string $eventType The type of event (e.g., 'impression', 'success', 'failure'). |
68 | * @param UserIdentity $user The user associated with the event. |
69 | */ |
70 | private function doLogEvent( |
71 | string $stream, string $eventType, UserIdentity $user, array $additionalData ): void { |
72 | $eventData = [ |
73 | '$schema' => self::SCHEMA_VERSIONED, |
74 | 'event_type' => $eventType, |
75 | 'performer' => [ |
76 | 'user_id' => $user->getId(), |
77 | 'user_text' => $user->getName(), |
78 | 'is_temp' => $this->userIdentityUtils->isTemp( $user ) |
79 | ], |
80 | 'source_wiki' => WikiMap::getCurrentWikiId() |
81 | ]; |
82 | $eventData = array_merge( $eventData, $additionalData ); |
83 | $this->submitEvent( $stream, $eventData ); |
84 | } |
85 | |
86 | /** |
87 | * Submits the event data to the EventLogging service. |
88 | * |
89 | * @param string $stream The event stream. |
90 | * @param array $eventData The prepared event data. |
91 | */ |
92 | private function submitEvent( string $stream, array $eventData ): void { |
93 | EventLogging::submit( $stream, $eventData ); |
94 | } |
95 | |
96 | /** |
97 | * Logs login event with a specified event type. |
98 | * @param string $eventType The type of the login event (e.g., 'success', 'failure'). |
99 | * @param UserIdentity $performer The user who is performing the login action. |
100 | * @param AuthenticationResponse $response The response received from the authentication process |
101 | */ |
102 | public function logLoginEvent( |
103 | string $eventType, UserIdentity $performer, AuthenticationResponse $response ): void { |
104 | $this->logAuthEvent( self::STREAM_LOGIN, $eventType, $performer, $response ); |
105 | } |
106 | |
107 | /** |
108 | * Logs account creation event with a specified event type. |
109 | * @param string $eventType The type of the account creation event (e.g., 'success', 'failure'). |
110 | * @param UserIdentity $performer The user who is attempting to |
111 | * create a new account or the user performing the action. |
112 | * @param AuthenticationResponse $response The response from the account creation process. |
113 | */ |
114 | public function logAccountCreationEvent( |
115 | string $eventType, UserIdentity $performer, AuthenticationResponse $response ): void { |
116 | $this->logAuthEvent( self::STREAM_REGISTER, $eventType, $performer, $response ); |
117 | } |
118 | |
119 | /** |
120 | * Logs page impression events for specified pages |
121 | * like account creation or login page. |
122 | * |
123 | * @param PageReference $pageReference |
124 | * @param UserIdentity $performer The user viewing the page. |
125 | */ |
126 | public function logPageImpression( PageReference $pageReference, UserIdentity $performer ): void { |
127 | $stream = $this->determineStreamForPage( $pageReference ); |
128 | |
129 | if ( !$stream ) { |
130 | return; // Not an instrumented page, do nothing. |
131 | } |
132 | |
133 | $additionalData = [ |
134 | 'page_title' => $pageReference->getDBkey(), |
135 | 'page_namespace' => $pageReference->getNamespace(), |
136 | ]; |
137 | $this->doLogEvent( $stream, 'impression', $performer, $additionalData ); |
138 | } |
139 | |
140 | /** |
141 | * Determines the appropriate event stream based on the page title. |
142 | * |
143 | * @param PageReference $pageReference Reference to the special page. |
144 | * @return string|null The stream constant or null if the page is not instrumented. |
145 | */ |
146 | private function determineStreamForPage( PageReference $pageReference ): ?string { |
147 | [ $canonicalName, ] = $this->specialPageFactory->resolveAlias( $pageReference->getDBkey() ); |
148 | return $this->pageStreamMap[$canonicalName] ?? null; |
149 | } |
150 | |
151 | } |