Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialHomepageLogger
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 2
132
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
2
 log
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
110
1<?php
2
3namespace GrowthExperiments\EventLogging;
4
5use GrowthExperiments\HomepageModules\Impact;
6use GrowthExperiments\HomepageModules\StartEmail;
7use MediaWiki\Extension\EventLogging\EventLogging;
8use MediaWiki\Logger\LoggerFactory;
9use MediaWiki\Request\WebRequest;
10use MediaWiki\User\User;
11
12class SpecialHomepageLogger {
13
14    /**
15     * @var string
16     */
17    private $pageviewToken;
18    /**
19     * @var array Associative array of modules used on the homepage. Keys are module names,
20     *   values are arbitrary.
21     */
22    private $modules;
23    /**
24     * @var WebRequest
25     */
26    private $request;
27    /**
28     * @var bool
29     */
30    private $isMobile;
31    /**
32     * @var User
33     */
34    private $user;
35
36    /**
37     * @param string $pageviewToken
38     * @param User $user
39     * @param WebRequest $request
40     * @param bool $isMobile
41     * @param array $modules Associative array of modules used on the homepage. Keys are module names,
42     *   values are arbitrary.
43     */
44    public function __construct(
45        $pageviewToken,
46        User $user,
47        WebRequest $request,
48        $isMobile,
49        array $modules
50    ) {
51        $this->pageviewToken = $pageviewToken;
52        $this->user = $user;
53        $this->modules = $modules;
54        $this->request = $request;
55        $this->isMobile = $isMobile;
56    }
57
58    /**
59     * Log an event to HomepageVisit.
60     */
61    public function log() {
62        $event = [];
63        $event['is_mobile'] = $this->isMobile;
64        $referer = $this->request->getHeader( 'REFERER' );
65        $event['referer_route'] = $this->request->getVal(
66            'source',
67            // If there is no referer header and no source param, then assume the user went to the
68            // page directly from their browser history/bookmark/etc.
69            $referer ? 'other' : 'direct'
70        );
71        $namespace = $this->request->getVal( 'namespace' );
72        if ( $namespace !== null ) {
73            $event['referer_namespace'] = (int)$namespace;
74        }
75        $event['referer_action'] = 'view';
76        if ( $referer ) {
77            $referer = wfParseUrl( $referer );
78            if ( isset( $referer['query'] ) ) {
79                $referer_query = wfCgiToArray( $referer['query'] );
80                if ( isset( $referer_query['action'] ) ) {
81                    $event['referer_action'] = $referer_query['action'];
82                }
83            }
84            if ( !isset( $event['referer_action'] ) ) {
85                $event['referer_action'] = $this->request->getVal( 'action', 'view' );
86            }
87        }
88        if ( !in_array( $event['referer_action' ], [ 'view', 'edit' ] ) ) {
89            // Some other action, like info, was specified. For analysis we don't care about the
90            // specific value, just that it's not one of "view" or "edit".
91            $event['referer_action'] = 'other';
92        }
93        $event['user_id'] = $this->user->getId();
94        $event['user_editcount'] = $this->user->getEditCount();
95
96        /** @var Impact $impactModule */
97        $impactModule = $this->modules['impact'] ?? false;
98        if ( $impactModule ) {
99            $event['impact_module_state'] = $impactModule->getState();
100        } else {
101            // Should not happen; it is a required schema field.
102            LoggerFactory::getInstance( 'GrowthExperiments' )
103                ->error( 'Could not set HomepageVisit.impact_module_state schema field' );
104        }
105
106        /** @var StartEmail $startEmailModule */
107        $startEmailModule = $this->modules['startemail'] ?? false;
108        if ( $startEmailModule ) {
109            $event['start_email_state'] = $startEmailModule->getState();
110        } else {
111            // Should not happen; it is a required schema field.
112            LoggerFactory::getInstance( 'GrowthExperiments' )
113                ->error( 'Could not set HomepageVisit.start_email_state schema field' );
114        }
115
116        $event['homepage_pageview_token'] = $this->pageviewToken;
117
118        // This has been migrated to an Event Platform schema; schema revision is no longer used
119        // in this call.  Versioned schema URI is set in extension.json.
120        EventLogging::logEvent( 'HomepageVisit', -1, $event );
121    }
122
123}