Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 128 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
TourHooks | |
0.00% |
0 / 128 |
|
0.00% |
0 / 7 |
506 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
onBeforePageDisplay | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
42 | |||
onResourceLoaderRegisterModules | |
0.00% |
0 / 70 |
|
0.00% |
0 / 1 |
6 | |||
growthTourDependenciesLoaded | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
onGetPreferences | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
20 | |||
onUserGetDefaultOptions | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
20 | |||
onLocalUserCreated | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | namespace GrowthExperiments; |
4 | |
5 | use MediaWiki\Auth\Hook\LocalUserCreatedHook; |
6 | use MediaWiki\Config\Config; |
7 | use MediaWiki\Hook\BeforePageDisplayHook; |
8 | use MediaWiki\Preferences\Hook\GetPreferencesHook; |
9 | use MediaWiki\ResourceLoader\Hook\ResourceLoaderRegisterModulesHook; |
10 | use MediaWiki\ResourceLoader\ResourceLoader; |
11 | use MediaWiki\User\Hook\UserGetDefaultOptionsHook; |
12 | use MediaWiki\User\Options\UserOptionsLookup; |
13 | use MediaWiki\User\Options\UserOptionsManager; |
14 | |
15 | class TourHooks implements |
16 | BeforePageDisplayHook, |
17 | ResourceLoaderRegisterModulesHook, |
18 | GetPreferencesHook, |
19 | UserGetDefaultOptionsHook, |
20 | LocalUserCreatedHook |
21 | { |
22 | |
23 | public const TOUR_COMPLETED_HELP_PANEL = 'growthexperiments-tour-help-panel'; |
24 | public const TOUR_COMPLETED_HOMEPAGE_MENTORSHIP = 'growthexperiments-tour-homepage-mentorship'; |
25 | public const TOUR_COMPLETED_HOMEPAGE_WELCOME = 'growthexperiments-tour-homepage-welcome'; |
26 | public const TOUR_COMPLETED_HOMEPAGE_DISCOVERY = 'growthexperiments-tour-homepage-discovery'; |
27 | public const TOUR_COMPLETED_NEWIMPACT_DISCOVERY = 'growthexperiments-tour-newimpact-discovery'; |
28 | |
29 | private UserOptionsLookup $userOptionsLookup; |
30 | private ExperimentUserManager $experimentUserManager; |
31 | private Config $config; |
32 | private UserOptionsManager $userOptionsManager; |
33 | |
34 | /** |
35 | * @param UserOptionsLookup $userOptionsLookup |
36 | * @param ExperimentUserManager $experimentUserManager |
37 | * @param Config $config |
38 | * @param UserOptionsManager $userOptionsManager |
39 | */ |
40 | public function __construct( |
41 | UserOptionsLookup $userOptionsLookup, |
42 | ExperimentUserManager $experimentUserManager, |
43 | Config $config, |
44 | UserOptionsManager $userOptionsManager |
45 | ) { |
46 | $this->userOptionsLookup = $userOptionsLookup; |
47 | $this->experimentUserManager = $experimentUserManager; |
48 | $this->config = $config; |
49 | $this->userOptionsManager = $userOptionsManager; |
50 | } |
51 | |
52 | /** @inheritDoc */ |
53 | public function onBeforePageDisplay( $out, $skin ): void { |
54 | // Show the discovery tour if the user isn't on WelcomeSurvey or Homepage. |
55 | // If they have already seen the welcome tour, don't show the discovery one. |
56 | if ( !$out->getTitle()->isSpecial( 'WelcomeSurvey' ) && |
57 | !$out->getTitle()->isSpecial( 'Homepage' ) && |
58 | HomepageHooks::isHomepageEnabled( $out->getUser() ) && |
59 | !Util::isMobile( $skin ) && |
60 | !$this->userOptionsLookup->getBoolOption( $out->getUser(), self::TOUR_COMPLETED_HOMEPAGE_WELCOME ) |
61 | ) { |
62 | Util::maybeAddGuidedTour( |
63 | $out, |
64 | self::TOUR_COMPLETED_HOMEPAGE_DISCOVERY, |
65 | 'ext.guidedTour.tour.homepage_discovery', |
66 | $this->userOptionsLookup |
67 | ); |
68 | } |
69 | } |
70 | |
71 | /** |
72 | * Register ResourceLoader modules which depend on other extensions. |
73 | * @inheritDoc |
74 | */ |
75 | public function onResourceLoaderRegisterModules( ResourceLoader $resourceLoader ): void { |
76 | if ( !self::growthTourDependenciesLoaded() ) { |
77 | return; |
78 | } |
79 | $moduleTemplate = [ |
80 | 'localBasePath' => dirname( __DIR__ ) . '/modules', |
81 | 'remoteExtPath' => 'GrowthExperiments/modules', |
82 | 'dependencies' => 'ext.guidedTour' |
83 | ]; |
84 | $modules = [ |
85 | 'ext.guidedTour.tour.helppanel' => $moduleTemplate + [ |
86 | 'packageFiles' => [ |
87 | 'tours/helpPanelTour.js', |
88 | 'tours/tourUtils.js', |
89 | ], |
90 | 'messages' => [ |
91 | 'growthexperiments-tour-helpdesk-response-tip-title', |
92 | 'growthexperiments-tour-response-tip-text', |
93 | 'growthexperiments-tour-response-button-okay' |
94 | ], |
95 | ], |
96 | 'ext.guidedTour.tour.homepage_mentor' => $moduleTemplate + [ |
97 | 'packageFiles' => [ |
98 | 'tours/homepageMentor.js', |
99 | 'tours/tourUtils.js', |
100 | ], |
101 | 'messages' => [ |
102 | 'growthexperiments-tour-mentor-response-tip-personal-title', |
103 | 'growthexperiments-tour-mentor-response-tip-personal-text', |
104 | 'growthexperiments-tour-response-button-okay' |
105 | ], |
106 | ], |
107 | 'ext.guidedTour.tour.homepage_welcome' => $moduleTemplate + [ |
108 | 'packageFiles' => [ |
109 | 'tours/homepageWelcome.js', |
110 | 'tours/tourUtils.js', |
111 | "ext.growthExperiments.Homepage.Logger/index.js", |
112 | "utils/Utils.js" |
113 | ], |
114 | 'messages' => [ |
115 | 'growthexperiments-tour-welcome-title', |
116 | 'growthexperiments-tour-welcome-description', |
117 | 'growthexperiments-tour-welcome-description-c', |
118 | 'growthexperiments-tour-welcome-description-d', |
119 | 'growthexperiments-tour-response-button-okay', |
120 | ], |
121 | ], |
122 | 'ext.guidedTour.tour.homepage_discovery' => $moduleTemplate + [ |
123 | 'packageFiles' => [ |
124 | 'tours/homepageDiscovery.js', |
125 | 'tours/tourUtils.js', |
126 | ], |
127 | 'messages' => [ |
128 | 'growthexperiments-tour-discovery-title', |
129 | 'growthexperiments-tour-discovery-description', |
130 | 'growthexperiments-tour-response-button-okay' |
131 | ] |
132 | ], |
133 | 'ext.guidedTour.tour.newimpact_discovery' => $moduleTemplate + [ |
134 | 'packageFiles' => [ |
135 | 'tours/newImpactDiscovery.js', |
136 | "ext.growthExperiments.Homepage.Logger/index.js", |
137 | "utils/Utils.js" |
138 | ], |
139 | 'messages' => [ |
140 | 'growthexperiments-tour-newimpact-discovery-title', |
141 | 'growthexperiments-tour-newimpact-discovery-description', |
142 | 'growthexperiments-tour-newimpact-discovery-response-button-okay' |
143 | ] |
144 | ] |
145 | ]; |
146 | $resourceLoader->register( $modules ); |
147 | } |
148 | |
149 | /** |
150 | * @return bool |
151 | */ |
152 | public static function growthTourDependenciesLoaded() { |
153 | $extensionRegistry = \ExtensionRegistry::getInstance(); |
154 | return $extensionRegistry->isLoaded( 'GuidedTour' ) && |
155 | $extensionRegistry->isLoaded( 'Echo' ) && |
156 | $extensionRegistry->isLoaded( 'EventLogging' ); |
157 | } |
158 | |
159 | /** |
160 | * Register tour state as hidden preferences |
161 | * @inheritDoc |
162 | */ |
163 | public function onGetPreferences( $user, &$preferences ) { |
164 | if ( !self::growthTourDependenciesLoaded() ) { |
165 | return; |
166 | } |
167 | if ( HelpPanel::isHelpPanelEnabled() ) { |
168 | $preferences[self::TOUR_COMPLETED_HELP_PANEL] = [ |
169 | 'type' => 'api', |
170 | ]; |
171 | } |
172 | if ( HomepageHooks::isHomepageEnabled() ) { |
173 | $preferences[self::TOUR_COMPLETED_HOMEPAGE_MENTORSHIP] = [ |
174 | 'type' => 'api', |
175 | ]; |
176 | $preferences[self::TOUR_COMPLETED_HOMEPAGE_WELCOME] = [ |
177 | 'type' => 'api', |
178 | ]; |
179 | $preferences[self::TOUR_COMPLETED_HOMEPAGE_DISCOVERY] = [ |
180 | 'type' => 'api', |
181 | ]; |
182 | $preferences[self::TOUR_COMPLETED_NEWIMPACT_DISCOVERY] = [ |
183 | 'type' => 'api', |
184 | ]; |
185 | } |
186 | } |
187 | |
188 | /** |
189 | * Register default preferences for tours. |
190 | * |
191 | * Default is to set their visibility to true (seen), and in the LocalUserCreated |
192 | * hook we'll set these preferences back to false (unseen). |
193 | * |
194 | * @inheritDoc |
195 | */ |
196 | public function onUserGetDefaultOptions( &$defaultOptions ) { |
197 | if ( !self::growthTourDependenciesLoaded() ) { |
198 | return; |
199 | } |
200 | if ( HelpPanel::isHelpPanelEnabled() ) { |
201 | $defaultOptions += [ |
202 | self::TOUR_COMPLETED_HELP_PANEL => true |
203 | ]; |
204 | } |
205 | if ( HomepageHooks::isHomepageEnabled() ) { |
206 | $defaultOptions += [ |
207 | self::TOUR_COMPLETED_HOMEPAGE_MENTORSHIP => true, |
208 | self::TOUR_COMPLETED_HOMEPAGE_WELCOME => true, |
209 | self::TOUR_COMPLETED_HOMEPAGE_DISCOVERY => true, |
210 | // New impact is different from the tours above; no one has |
211 | // seen it yet, and we want all existing users with activated impact modules |
212 | // to see it, so its default value should be false. |
213 | self::TOUR_COMPLETED_NEWIMPACT_DISCOVERY => false, |
214 | ]; |
215 | } |
216 | } |
217 | |
218 | /** @inheritDoc */ |
219 | public function onLocalUserCreated( $user, $autocreated ) { |
220 | if ( $user->isTemp() ) { |
221 | return; |
222 | } |
223 | // Always set the new impact module discovery tour to seen, whether the user |
224 | // is autocreated or local to the wiki, and whether homepage is enabled or not. |
225 | // The only users who should see this tour are existing user accounts in the local |
226 | // wiki who had the old impact module, and now can see the new impact module. |
227 | $this->userOptionsManager->setOption( |
228 | $user, |
229 | self::TOUR_COMPLETED_NEWIMPACT_DISCOVERY, |
230 | // If the new impact module isn't enabled yet, mark the tour |
231 | // as not seen. That way, when the module is eventually enabled, |
232 | // users will see it. |
233 | // If the new impact module is enabled, the user doesn't need to |
234 | // see this tour. |
235 | // When GEUseNewImpactModule is removed, this value can simply be 1, to |
236 | // indicate that it was seen. |
237 | (int)$this->config->get( 'GEUseNewImpactModule' ) |
238 | ); |
239 | } |
240 | } |