Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
75.86% |
22 / 29 |
|
66.67% |
6 / 9 |
CRAP | |
0.00% |
0 / 1 |
TwoColConflictContext | |
75.86% |
22 / 29 |
|
66.67% |
6 / 9 |
32.10 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
shouldCoreHintBeShown | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
4 | |||
shouldTwoColConflictBeShown | |
77.78% |
7 / 9 |
|
0.00% |
0 / 1 |
7.54 | |||
shouldTalkPageSuggestionBeConsidered | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
isSelfConflict | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
hasUserEnabledFeature | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
isUsedAsBetaFeature | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
isEligibleTalkPage | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
isTalkPageSuggesterEnabled | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace TwoColConflict; |
4 | |
5 | use ExtensionRegistry; |
6 | use MediaWiki\Config\Config; |
7 | use MediaWiki\Extension\BetaFeatures\BetaFeatures; |
8 | use MediaWiki\Title\Title; |
9 | use MediaWiki\User\Options\UserOptionsLookup; |
10 | use MediaWiki\User\UserIdentity; |
11 | use MobileContext; |
12 | use WikiPage; |
13 | |
14 | /** |
15 | * @license GPL-2.0-or-later |
16 | */ |
17 | class TwoColConflictContext { |
18 | |
19 | public const BETA_PREFERENCE_NAME = 'twocolconflict'; |
20 | public const ENABLED_PREFERENCE = 'twocolconflict-enabled'; |
21 | public const HIDE_CORE_HINT_PREFERENCE = 'userjs-twocolconflict-hide-core-hint'; |
22 | |
23 | private Config $config; |
24 | private UserOptionsLookup $userOptionsLookup; |
25 | private ExtensionRegistry $extensionRegistry; |
26 | private ?MobileContext $mobileContext; |
27 | |
28 | public function __construct( |
29 | Config $config, |
30 | UserOptionsLookup $userOptionsLookup, |
31 | ExtensionRegistry $extensionRegistry, |
32 | MobileContext $mobileContext = null |
33 | ) { |
34 | $this->config = $config; |
35 | $this->userOptionsLookup = $userOptionsLookup; |
36 | $this->extensionRegistry = $extensionRegistry; |
37 | $this->mobileContext = $mobileContext; |
38 | } |
39 | |
40 | /** |
41 | * @param UserIdentity $user |
42 | * |
43 | * @return bool True if the feature is not used as a beta feature, the |
44 | * user has disabled the feature but has not dismissed the core hint |
45 | * already. |
46 | */ |
47 | public function shouldCoreHintBeShown( UserIdentity $user ): bool { |
48 | return $user->isRegistered() && |
49 | !$this->isUsedAsBetaFeature() && |
50 | !$this->userOptionsLookup->getBoolOption( $user, self::ENABLED_PREFERENCE ) && |
51 | !$this->userOptionsLookup->getBoolOption( $user, self::HIDE_CORE_HINT_PREFERENCE ); |
52 | } |
53 | |
54 | /** |
55 | * @param UserIdentity $user |
56 | * @param Title $title |
57 | * |
58 | * @return bool True if the new conflict interface should be used for this |
59 | * user and title. The user may have opted out, or the titles namespace |
60 | * may be excluded for this interface. |
61 | */ |
62 | public function shouldTwoColConflictBeShown( UserIdentity $user, Title $title ): bool { |
63 | if ( !$title->hasContentModel( CONTENT_MODEL_WIKITEXT ) && |
64 | !$title->hasContentModel( CONTENT_MODEL_TEXT ) |
65 | ) { |
66 | return false; |
67 | } |
68 | |
69 | // T249817: Temporarily disabled on mobile |
70 | if ( $this->mobileContext && $this->mobileContext->shouldDisplayMobileView() ) { |
71 | return false; |
72 | } |
73 | |
74 | if ( $this->isEligibleTalkPage( $title ) && |
75 | !$this->isTalkPageSuggesterEnabled() |
76 | ) { |
77 | // Temporary feature logic to completely disable on talk pages. |
78 | return false; |
79 | } |
80 | |
81 | return $this->hasUserEnabledFeature( $user ); |
82 | } |
83 | |
84 | /** |
85 | * @param WikiPage $page |
86 | * @param UserIdentity $user |
87 | * @return bool True if this article is appropriate for the talk page |
88 | * workflow, and the interface has been enabled by configuration. |
89 | */ |
90 | public function shouldTalkPageSuggestionBeConsidered( WikiPage $page, UserIdentity $user ): bool { |
91 | return $this->isTalkPageSuggesterEnabled() && |
92 | $this->isEligibleTalkPage( $page->getTitle() ) && |
93 | !$this->isSelfConflict( $page, $user ); |
94 | } |
95 | |
96 | private function isSelfConflict( WikiPage $page, UserIdentity $user ): bool { |
97 | $lastRevision = $page->getRevisionRecord(); |
98 | return $lastRevision && $user->equals( $lastRevision->getUser() ); |
99 | } |
100 | |
101 | private function hasUserEnabledFeature( UserIdentity $user ): bool { |
102 | if ( $this->isUsedAsBetaFeature() ) { |
103 | return BetaFeatures::isFeatureEnabled( $user, self::BETA_PREFERENCE_NAME ); |
104 | } |
105 | |
106 | return $this->userOptionsLookup->getBoolOption( $user, self::ENABLED_PREFERENCE ); |
107 | } |
108 | |
109 | /** |
110 | * @return bool True if TwoColConflict should be provided as a beta feature. |
111 | * False if it will be the default conflict workflow. |
112 | */ |
113 | public function isUsedAsBetaFeature(): bool { |
114 | return $this->config->get( 'TwoColConflictBetaFeature' ) && |
115 | $this->extensionRegistry->isLoaded( 'BetaFeatures' ); |
116 | } |
117 | |
118 | private function isEligibleTalkPage( Title $title ): bool { |
119 | return $title->isTalkPage() || $title->inNamespace( NS_PROJECT ); |
120 | } |
121 | |
122 | private function isTalkPageSuggesterEnabled(): bool { |
123 | return $this->config->get( 'TwoColConflictSuggestResolution' ); |
124 | } |
125 | |
126 | } |