Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
PersonalizedPraiseLogger
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 7
182
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isEventLoggingAvailable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doLog
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
12
 logSuggested
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 logNotified
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 logPraised
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 logSkipped
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace GrowthExperiments\EventLogging;
4
5use GrowthExperiments\MentorDashboard\PersonalizedPraise\PersonalizedPraiseSettings;
6use MediaWiki\Extension\EventLogging\EventLogging;
7use MediaWiki\Registration\ExtensionRegistry;
8use MediaWiki\User\UserIdentity;
9use MediaWiki\WikiMap\WikiMap;
10
11class PersonalizedPraiseLogger {
12    /** @var string Versioned schema URL for $schema field */
13    private const SCHEMA_VERSIONED = '/analytics/mediawiki/mentor_dashboard/personalized_praise/1.0.2';
14    /** @var string Stream name for EventLogging::submit */
15    private const STREAM = 'mediawiki.mentor_dashboard.personalized_praise';
16
17    public const ACTION_SUGGESTED = 'suggested';
18    public const ACTION_NOTIFIED = 'notified';
19    public const ACTION_PRAISED = 'praised';
20    public const ACTION_SKIPPED = 'skipped';
21
22    private PersonalizedPraiseSettings $personalizedPraiseSettings;
23
24    /**
25     * @param PersonalizedPraiseSettings $personalizedPraiseSettings
26     */
27    public function __construct( PersonalizedPraiseSettings $personalizedPraiseSettings ) {
28        $this->personalizedPraiseSettings = $personalizedPraiseSettings;
29    }
30
31    private function isEventLoggingAvailable(): bool {
32        return ExtensionRegistry::getInstance()->isLoaded( 'EventLogging' );
33    }
34
35    /**
36     * Log an event to Personalized praise's stream
37     *
38     * @param string $action
39     * @param UserIdentity $mentor
40     * @param UserIdentity|null $mentee
41     * @param array $additionalData
42     */
43    private function doLog(
44        string $action,
45        UserIdentity $mentor,
46        ?UserIdentity $mentee,
47        array $additionalData = []
48    ): void {
49        $additionalDataSerialized = [];
50        foreach ( $additionalData as $key => $value ) {
51            $additionalDataSerialized[] = sprintf( '%s=%s', $key, $value );
52        }
53
54        $eventData = [
55            '$schema' => self::SCHEMA_VERSIONED,
56            'database' => WikiMap::getCurrentWikiId(),
57            'action' => $action,
58            'action_data' => implode( ';', $additionalDataSerialized ),
59            'mentor_id' => $mentor->getId(),
60        ];
61        if ( $mentee ) {
62            $eventData['mentee_id'] = $mentee->getId();
63        }
64
65        EventLogging::submit( self::STREAM, $eventData );
66    }
67
68    /**
69     * @param UserIdentity $mentor
70     * @param UserIdentity $mentee
71     * @param bool $wasNotified
72     */
73    public function logSuggested(
74        UserIdentity $mentor, UserIdentity $mentee, bool $wasNotified
75    ): void {
76        if ( $this->isEventLoggingAvailable() ) {
77            $this->doLog(
78                self::ACTION_SUGGESTED,
79                $mentor,
80                $mentee,
81                [
82                    'notification_policy' => $this->personalizedPraiseSettings->getNotificationsFrequency(
83                        $mentor
84                    ),
85                    'was_notified' => $wasNotified,
86                ]
87            );
88        }
89    }
90
91    /**
92     * @param UserIdentity $mentor
93     */
94    public function logNotified( UserIdentity $mentor ): void {
95        if ( $this->isEventLoggingAvailable() ) {
96            $this->doLog(
97                self::ACTION_NOTIFIED,
98                $mentor,
99                null,
100                [
101                    'notification_policy' => $this->personalizedPraiseSettings->getNotificationsFrequency(
102                        $mentor
103                    )
104                ]
105            );
106        }
107    }
108
109    /**
110     * @param UserIdentity $mentor
111     * @param UserIdentity $mentee
112     */
113    public function logPraised( UserIdentity $mentor, UserIdentity $mentee ): void {
114        if ( $this->isEventLoggingAvailable() ) {
115            $this->doLog(
116                self::ACTION_PRAISED,
117                $mentor,
118                $mentee
119            );
120        }
121    }
122
123    /**
124     * @param UserIdentity $mentor
125     * @param UserIdentity $mentee
126     * @param string $skipReason
127     */
128    public function logSkipped(
129        UserIdentity $mentor,
130        UserIdentity $mentee,
131        string $skipReason
132    ): void {
133        if ( $this->isEventLoggingAvailable() ) {
134            $this->doLog(
135                self::ACTION_SKIPPED,
136                $mentor,
137                $mentee,
138                [
139                    'skip_reason' => $skipReason
140                ]
141            );
142        }
143    }
144}