Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
3.85% covered (danger)
3.85%
6 / 156
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
HomepageModuleRegistry
3.85% covered (danger)
3.85%
6 / 156
0.00% covered (danger)
0.00%
0 / 4
64.90
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
 get
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
4.25
 getModuleIds
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getWiring
0.00% covered (danger)
0.00%
0 / 146
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace GrowthExperiments\Homepage;
4
5use GrowthExperiments\DashboardModule\IDashboardModule;
6use GrowthExperiments\GrowthExperimentsServices;
7use GrowthExperiments\HomepageModules\Banner;
8use GrowthExperiments\HomepageModules\CommunityUpdates;
9use GrowthExperiments\HomepageModules\Help;
10use GrowthExperiments\HomepageModules\Impact;
11use GrowthExperiments\HomepageModules\Mentorship;
12use GrowthExperiments\HomepageModules\MentorshipOptIn;
13use GrowthExperiments\HomepageModules\StartEditing;
14use GrowthExperiments\HomepageModules\StartEmail;
15use GrowthExperiments\HomepageModules\SuggestedEdits;
16use GrowthExperiments\HomepageModules\WelcomeSurveyReminder;
17use MediaWiki\Context\IContextSource;
18use MediaWiki\Extension\CommunityConfiguration\CommunityConfigurationServices;
19use MediaWiki\Logger\LoggerFactory;
20use MediaWiki\MediaWikiServices;
21use MediaWiki\Registration\ExtensionRegistry;
22use OutOfBoundsException;
23
24/**
25 * Container class for handling dependency injection of homepage modules.
26 */
27class HomepageModuleRegistry {
28
29    /** @var MediaWikiServices */
30    private $services;
31
32    /** @var callable[] id => factory method */
33    private $wiring;
34
35    /** @var IDashboardModule[] id => module */
36    private $modules = [];
37
38    /**
39     * @param MediaWikiServices $services
40     */
41    public function __construct( MediaWikiServices $services ) {
42        $this->services = $services;
43    }
44
45    /**
46     * @param string $id
47     * @param IContextSource $contextSource
48     * @return IDashboardModule
49     */
50    public function get( string $id, IContextSource $contextSource ): IDashboardModule {
51        if ( $this->modules[$id] ?? null ) {
52            return $this->modules[$id];
53        }
54        if ( $this->wiring === null ) {
55            $this->wiring = self::getWiring();
56        }
57        if ( !array_key_exists( $id, $this->wiring ) ) {
58            throw new OutOfBoundsException( 'Module not found: ' . $id );
59        }
60        $this->modules[$id] = $this->wiring[$id]( $this->services, $contextSource );
61        return $this->modules[$id];
62    }
63
64    /**
65     * @internal for testing only
66     * @return string[]
67     */
68    public static function getModuleIds(): array {
69        return array_keys( self::getWiring() );
70    }
71
72    /**
73     * Returns wiring callbacks for each module.
74     * The callback receives the service container and the request context,
75     * and must return a homepage module.
76     * @return callable[] module id => callback
77     */
78    private static function getWiring() {
79        return [
80            'banner' => static function (
81                MediaWikiServices $services,
82                IContextSource $context
83            ) {
84                $growthServices = GrowthExperimentsServices::wrap( $services );
85                return new Banner(
86                    $context,
87                    $growthServices->getGrowthWikiConfig(),
88                    $growthServices->getExperimentUserManager()
89                );
90            },
91
92            'welcomesurveyreminder' => static function (
93                MediaWikiServices $services,
94                IContextSource $context
95            ) {
96                $growthServices = GrowthExperimentsServices::wrap( $services );
97                return new WelcomeSurveyReminder(
98                    $context,
99                    $growthServices->getGrowthWikiConfig(),
100                    $growthServices->getExperimentUserManager(),
101                    $services->getSpecialPageFactory(),
102                    $growthServices->getWelcomeSurveyFactory()
103                );
104            },
105
106            'startemail' => static function (
107                MediaWikiServices $services,
108                IContextSource $context
109            ) {
110                $growthServices = GrowthExperimentsServices::wrap( $services );
111                return new StartEmail(
112                    $context,
113                    $growthServices->getGrowthWikiConfig(),
114                    $growthServices->getExperimentUserManager()
115                );
116            },
117
118            'suggested-edits' => static function (
119                MediaWikiServices $services,
120                IContextSource $context
121            ) {
122                $growthServices = GrowthExperimentsServices::wrap( $services );
123                $pageViewInfoEnabled = ExtensionRegistry::getInstance()->isLoaded( 'PageViewInfo' );
124                return new SuggestedEdits(
125                    $context,
126                    $growthServices->getGrowthWikiConfig(),
127                    $growthServices->getGrowthExperimentsCampaignConfig(),
128                    $growthServices->getExperimentUserManager(),
129                    $pageViewInfoEnabled ? $services->get( 'PageViewService' ) : null,
130                    $growthServices->getNewcomerTasksConfigurationLoader(),
131                    $growthServices->getNewcomerTasksUserOptionsLookup(),
132                    $growthServices->getTaskSuggesterFactory()->create(),
133                    $services->getTitleFactory(),
134                    $growthServices->getProtectionFilter(),
135                    $services->getUserOptionsLookup(),
136                    $growthServices->getLinkRecommendationFilter(),
137                    $growthServices->getImageRecommendationFilter(),
138                    $services->getPerDbNameStatsdDataFactory(),
139                );
140            },
141
142            'impact' => static function (
143                MediaWikiServices $services,
144                IContextSource $context
145            ) {
146                $growthServices = GrowthExperimentsServices::wrap( $services );
147                $userOptionsLookup = $services->getUserOptionsLookup();
148                return new Impact(
149                    $context,
150                    $growthServices->getGrowthWikiConfig(),
151                    $growthServices->getExperimentUserManager(),
152                    $context->getUser(),
153                    $growthServices->getUserImpactStore(),
154                    $growthServices->getUserImpactFormatter(),
155                    $growthServices->getUserDatabaseHelper(),
156                    SuggestedEdits::isEnabled( $context->getConfig() ),
157                    SuggestedEdits::isActivated( $context->getUser(), $userOptionsLookup )
158                );
159            },
160
161            'mentorship' => static function (
162                MediaWikiServices $services,
163                IContextSource $context
164            ) {
165                $growthServices = GrowthExperimentsServices::wrap( $services );
166                return new Mentorship(
167                    $context,
168                    $growthServices->getGrowthWikiConfig(),
169                    $growthServices->getExperimentUserManager(),
170                    $growthServices->getMentorManager(),
171                    $growthServices->getMentorStatusManager(),
172                    $services->getGenderCache(),
173                    $services->getUserEditTracker()
174                );
175            },
176
177            'mentorship-optin' => static function (
178                MediaWikiServices $services,
179                IContextSource $context
180            ) {
181                $growthServices = GrowthExperimentsServices::wrap( $services );
182                return new MentorshipOptIn(
183                    $context,
184                    $growthServices->getGrowthWikiConfig(),
185                    $growthServices->getExperimentUserManager(),
186                    $growthServices->getMentorManager()
187                );
188            },
189
190            'help' => static function (
191                MediaWikiServices $services,
192                IContextSource $context
193            ) {
194                $growthServices = GrowthExperimentsServices::wrap( $services );
195                return new Help(
196                    $context,
197                    $growthServices->getGrowthWikiConfig(),
198                    $growthServices->getExperimentUserManager()
199                );
200            },
201
202            'start-startediting' => static function (
203                MediaWikiServices $services,
204                IContextSource $context
205            ) {
206                $growthServices = GrowthExperimentsServices::wrap( $services );
207                return new StartEditing(
208                    $context,
209                    $growthServices->getGrowthWikiConfig(),
210                    $growthServices->getExperimentUserManager(),
211                    $services->getUserOptionsLookup()
212                );
213            },
214            'community-updates' => static function (
215                MediaWikiServices $services,
216                IContextSource $context
217            ) {
218                $growthServices = GrowthExperimentsServices::wrap( $services );
219                return new CommunityUpdates(
220                    LoggerFactory::getInstance( 'GrowthExperiments' ),
221                    $context,
222                    $growthServices->getGrowthWikiConfig(),
223                    $growthServices->getExperimentUserManager(),
224                    CommunityConfigurationServices::wrap( $services )->getConfigurationProviderFactory(),
225                    $services->getUserEditTracker(),
226                    $services->getLinkRenderer(),
227                    $services->getTitleFactory(),
228                    $services->getMainWANObjectCache(),
229                    $services->getHttpRequestFactory()
230                );
231            },
232        ];
233    }
234
235}