Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
50.00% covered (danger)
50.00%
18 / 36
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
GuidedTourLauncher
50.00% covered (danger)
50.00%
18 / 36
20.00% covered (danger)
20.00%
1 / 5
19.12
0.00% covered (danger)
0.00%
0 / 1
 getNewState
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
2
 getNewCookie
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 launchTour
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 onMakeGlobalVariablesScript
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 launchTourByCookie
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\GuidedTour;
4
5use FormatJson;
6use MediaWiki\Output\OutputPage;
7use RequestContext;
8
9/**
10 * Allows server-side launching of tours (without the URL parameter).
11 */
12class GuidedTourLauncher {
13    /**
14     * State used to tell the client to directly launch tours using a client-side $wg
15     *
16     * @var array|null
17     */
18    protected static $directLaunchState = null;
19
20    // This matches the format used on the client-side (e.g.
21    // mw.guidedTour.internal.getInitialUserStateObject,
22    // mw.guidedTour.launchTourFromUserState, etc.
23
24    /**
25     * Get new state from old state.  The state describes the user's progress
26     * in the tour, and which step they are expected to see next.
27     *
28     * @param array|null $oldState Previous state
29     * @param string $tourName Tour name
30     * @param string $step Step to start at
31     * @return array New state
32     */
33    protected static function getNewState( $oldState, $tourName, $step ) {
34        $newState = $oldState;
35
36        if ( $newState === null ) {
37            $newState = [];
38        }
39
40        $newState = array_replace_recursive( $newState, [
41            'version' => 1,
42            'tours' => [
43                $tourName => [
44                    'step' => $step,
45                ],
46            ]
47        ] );
48
49        return $newState;
50    }
51
52    /**
53     * Adds a tour to the cookie
54     *
55     * @param string|null $oldCookieValue Previous value of cookie
56     * @param string $tourName Tour name
57     * @param string $step Step to start at
58     * @return string Value of new cookie
59     */
60    public static function getNewCookie( $oldCookieValue, $tourName, $step ) {
61        if ( $oldCookieValue == null ) {
62            $oldCookieValue = '{}';
63        }
64
65        $oldState = FormatJson::decode( $oldCookieValue, true );
66        if ( $oldState === null ) {
67            $oldState = [];
68        }
69
70        $newState = self::getNewState( $oldState, $tourName, $step );
71
72        return FormatJson::encode( $newState );
73    }
74
75    /**
76     * Sets a tour to auto-launch on this view
77     *
78     * @param string $tourName Name of tour to launch
79     * @param string $step Step to navigate to
80     */
81    public static function launchTour( $tourName, $step ) {
82        $context = RequestContext::getMain();
83
84        self::$directLaunchState = self::getNewState(
85            self::$directLaunchState,
86            $tourName,
87            $step
88        );
89
90        Hooks::addTour( $context->getOutput(), $tourName );
91    }
92
93    /**
94     * Export data to client-side via mw.config (for use by ext.guidedTour.lib).
95     *
96     * @param array &$vars Array of request-specific JavaScript config variables
97     * @param OutputPage $out
98     */
99    public static function onMakeGlobalVariablesScript( array &$vars, OutputPage $out ) {
100        if ( self::$directLaunchState !== null ) {
101            $vars['wgGuidedTourLaunchState'] = self::$directLaunchState;
102        }
103    }
104
105    /**
106     * Sets a tour to auto-launch on this view using a cookie.
107     *
108     * @param string $tourName Name of tour to launch
109     * @param string $step Step to navigate to
110     */
111    public static function launchTourByCookie( $tourName, $step ) {
112        $context = RequestContext::getMain();
113
114        $request = $context->getRequest();
115        $oldCookie = $request->getCookie( Hooks::COOKIE_NAME );
116        $newCookie = self::getNewCookie( $oldCookie, $tourName, $step );
117        $request->response()->setCookie( Hooks::COOKIE_NAME, $newCookie, 0, [
118            'httpOnly' => false,
119        ] );
120
121        Hooks::addTour( $context->getOutput(), $tourName );
122    }
123}