Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 97 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
PreferenceHooks | |
0.00% |
0 / 97 |
|
0.00% |
0 / 3 |
552 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
arrayRenameKey | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
onGetPreferences | |
0.00% |
0 / 89 |
|
0.00% |
0 / 1 |
380 |
1 | <?php |
2 | /** |
3 | * DiscussionTools preference hooks |
4 | * |
5 | * @file |
6 | * @ingroup Extensions |
7 | * @license MIT |
8 | */ |
9 | |
10 | namespace MediaWiki\Extension\DiscussionTools\Hooks; |
11 | |
12 | use MediaWiki\Config\Config; |
13 | use MediaWiki\Config\ConfigFactory; |
14 | use MediaWiki\Html\Html; |
15 | use MediaWiki\Linker\LinkRenderer; |
16 | use MediaWiki\Preferences\Hook\GetPreferencesHook; |
17 | use MediaWiki\SpecialPage\SpecialPage; |
18 | use MediaWiki\User\User; |
19 | |
20 | class PreferenceHooks implements |
21 | GetPreferencesHook |
22 | { |
23 | |
24 | private Config $config; |
25 | private LinkRenderer $linkRenderer; |
26 | |
27 | public function __construct( |
28 | ConfigFactory $configFactory, |
29 | LinkRenderer $linkRenderer |
30 | ) { |
31 | $this->config = $configFactory->makeConfig( 'discussiontools' ); |
32 | $this->linkRenderer = $linkRenderer; |
33 | } |
34 | |
35 | /** |
36 | * Rename a key in an array while preserving the order of associative array keys. |
37 | * |
38 | * @param array $array |
39 | * @param string $from |
40 | * @param string $to |
41 | * @return array Modified array |
42 | */ |
43 | private static function arrayRenameKey( array $array, string $from, string $to ): array { |
44 | $out = []; |
45 | foreach ( $array as $key => $value ) { |
46 | if ( $key === $from ) { |
47 | $key = $to; |
48 | } |
49 | $out[$key] = $value; |
50 | } |
51 | return $out; |
52 | } |
53 | |
54 | /** |
55 | * Handler for the GetPreferences hook, to add and hide user preferences as configured |
56 | * |
57 | * @param User $user |
58 | * @param array &$preferences |
59 | */ |
60 | public function onGetPreferences( $user, &$preferences ) { |
61 | if ( HookUtils::isFeatureAvailableToUser( $user ) ) { |
62 | $preferences['discussiontools-summary'] = [ |
63 | 'type' => 'info', |
64 | 'default' => wfMessage( 'discussiontools-preference-summary' )->parse(), |
65 | 'raw' => true, |
66 | 'section' => 'editing/discussion', |
67 | ]; |
68 | } |
69 | foreach ( HookUtils::FEATURES as $feature ) { |
70 | if ( |
71 | $feature === HookUtils::VISUALENHANCEMENTS_REPLY || |
72 | $feature === HookUtils::VISUALENHANCEMENTS_PAGEFRAME |
73 | ) { |
74 | // Feature is never user-configurable |
75 | continue; |
76 | } |
77 | if ( HookUtils::isFeatureAvailableToUser( $user, $feature ) ) { |
78 | $preferences["discussiontools-$feature"] = [ |
79 | 'type' => 'toggle', |
80 | // The following messages are used here: |
81 | // * discussiontools-preference-autotopicsub |
82 | // * discussiontools-preference-newtopictool |
83 | // * discussiontools-preference-replytool |
84 | // * discussiontools-preference-sourcemodetoolbar |
85 | // * discussiontools-preference-topicsubscription |
86 | // * discussiontools-preference-visualenhancements |
87 | 'label-message' => "discussiontools-preference-$feature", |
88 | // The following messages are used here: |
89 | // * discussiontools-preference-autotopicsub-help |
90 | // * discussiontools-preference-newtopictool-help |
91 | // * discussiontools-preference-replytool-help |
92 | // * discussiontools-preference-sourcemodetoolbar-help |
93 | // * discussiontools-preference-topicsubscription-help |
94 | // * discussiontools-preference-visualenhancements-help |
95 | 'help-message' => "discussiontools-preference-$feature-help", |
96 | 'section' => 'editing/discussion', |
97 | ]; |
98 | |
99 | // Option to enable/disable new topic tool on pages that haven't been created |
100 | // (it's inside this loop to place the options in a nice order) |
101 | if ( $feature === HookUtils::NEWTOPICTOOL ) { |
102 | $preferences["discussiontools-newtopictool-createpage"] = [ |
103 | 'type' => 'radio', |
104 | 'cssclass' => 'mw-htmlform-checkradio-indent', |
105 | 'label-message' => 'discussiontools-preference-newtopictool-createpage', |
106 | 'options-messages' => [ |
107 | 'discussiontools-preference-newtopictool-createpage-newtopictool' => 1, |
108 | 'discussiontools-preference-newtopictool-createpage-editor' => 0, |
109 | ], |
110 | 'disable-if' => [ '===', 'discussiontools-' . HookUtils::NEWTOPICTOOL, '' ], |
111 | 'section' => 'editing/discussion', |
112 | ]; |
113 | } |
114 | |
115 | // Make this option unavailable when a conflicting Convenient Discussions gadget exists |
116 | // (we can't use 'disable-if' or 'hide-if', because they don't let us change the labels). |
117 | if ( HookUtils::featureConflictsWithGadget( $user, $feature ) ) { |
118 | $preferences["discussiontools-$feature"]['disabled'] = true; |
119 | $preferences["discussiontools-$feature"]['help-message'] = |
120 | [ 'discussiontools-preference-gadget-conflict', 'Special:Preferences#mw-prefsection-gadgets' ]; |
121 | } |
122 | } |
123 | } |
124 | |
125 | if ( isset( $preferences['discussiontools-' . HookUtils::SOURCEMODETOOLBAR] ) && ( |
126 | isset( $preferences['discussiontools-' . HookUtils::REPLYTOOL] ) || |
127 | isset( $preferences['discussiontools-' . HookUtils::NEWTOPICTOOL] ) |
128 | ) ) { |
129 | // Disable this option when it would have no effect |
130 | // (both reply tool and new topic tool are disabled) |
131 | $preferences['discussiontools-' . HookUtils::SOURCEMODETOOLBAR]['disable-if'] = [ 'AND' ]; |
132 | |
133 | if ( isset( $preferences['discussiontools-' . HookUtils::REPLYTOOL] ) && |
134 | // GlobalPreferences extension would delete disabled fields, avoid referring to it. |
135 | !( $preferences['discussiontools-' . HookUtils::REPLYTOOL]['disabled'] ?? false ) |
136 | ) { |
137 | $preferences['discussiontools-' . HookUtils::SOURCEMODETOOLBAR]['disable-if'][] = [ |
138 | '===', 'discussiontools-' . HookUtils::REPLYTOOL, '' |
139 | ]; |
140 | } |
141 | if ( isset( $preferences['discussiontools-' . HookUtils::NEWTOPICTOOL] ) ) { |
142 | $preferences['discussiontools-' . HookUtils::SOURCEMODETOOLBAR]['disable-if'][] = [ |
143 | '===', 'discussiontools-' . HookUtils::NEWTOPICTOOL, '' |
144 | ]; |
145 | } |
146 | } |
147 | |
148 | if ( isset( $preferences['discussiontools-' . HookUtils::AUTOTOPICSUB] ) && |
149 | isset( $preferences['discussiontools-' . HookUtils::TOPICSUBSCRIPTION] ) |
150 | ) { |
151 | // Disable automatic subscriptions when subscriptions are disabled |
152 | $preferences['discussiontools-' . HookUtils::AUTOTOPICSUB]['disable-if'] = [ |
153 | '===', 'discussiontools-' . HookUtils::TOPICSUBSCRIPTION, '' |
154 | ]; |
155 | } |
156 | |
157 | $preferences['discussiontools-showadvanced'] = [ |
158 | 'type' => 'api', |
159 | ]; |
160 | $preferences['discussiontools-seenautotopicsubpopup'] = [ |
161 | 'type' => 'api', |
162 | ]; |
163 | |
164 | if ( !$this->config->get( 'DiscussionToolsBeta' ) ) { |
165 | // When out of beta, preserve the user preference in case we |
166 | // bring back the beta feature for a new sub-feature. (T272071) |
167 | $preferences['discussiontools-betaenable'] = [ |
168 | 'type' => 'api' |
169 | ]; |
170 | } |
171 | |
172 | $preferences['discussiontools-editmode'] = [ |
173 | 'type' => 'api', |
174 | 'validation-callback' => static function ( $value ) { |
175 | return in_array( $value, [ '', 'source', 'visual' ], true ); |
176 | }, |
177 | ]; |
178 | |
179 | // Add a link to Special:TopicSubscriptions to the Echo preferences matrix |
180 | $categoryMessage = wfMessage( 'echo-category-title-dt-subscription' )->numParams( 1 )->escaped(); |
181 | $categoryMessageExtra = $categoryMessage . |
182 | Html::element( 'br' ) . |
183 | wfMessage( 'parentheses' )->rawParams( |
184 | $this->linkRenderer->makeLink( |
185 | SpecialPage::getTitleFor( 'TopicSubscriptions' ), |
186 | wfMessage( 'discussiontools-topicsubscription-preferences-editsubscriptions' )->text() |
187 | ) |
188 | )->escaped(); |
189 | if ( isset( $preferences['echo-subscriptions']['rows'] ) ) { |
190 | $preferences['echo-subscriptions']['rows'] = static::arrayRenameKey( |
191 | $preferences['echo-subscriptions']['rows'], |
192 | $categoryMessage, |
193 | $categoryMessageExtra |
194 | ); |
195 | } |
196 | if ( isset( $preferences['echo-subscriptions']['tooltips'] ) ) { |
197 | $preferences['echo-subscriptions']['tooltips'] = static::arrayRenameKey( |
198 | // Phan insists that this key doesn't exist, even though we just checked with isset() |
199 | // @phan-suppress-next-line PhanTypeInvalidDimOffset, PhanTypeMismatchArgument |
200 | $preferences['echo-subscriptions']['tooltips'], |
201 | $categoryMessage, |
202 | $categoryMessageExtra |
203 | ); |
204 | } |
205 | } |
206 | |
207 | } |