Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 28 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
AxArticleFooterEntrypointRegistrationHandler | |
0.00% |
0 / 28 |
|
0.00% |
0 / 7 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
isEntrypointAllowedOnSkin | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
isDiffPage | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
isDisambiguationPage | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
6 | |||
shouldDisplayFooterEntrypoint | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
72 | |||
onSkinAfterContent | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
onBeforePageDisplay | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace ContentTranslation\HookHandler; |
5 | |
6 | use MediaWiki\Config\Config; |
7 | use MediaWiki\Config\ConfigFactory; |
8 | use MediaWiki\Context\IContextSource; |
9 | use MediaWiki\Extension\Disambiguator\Lookup; |
10 | use MediaWiki\Hook\SkinAfterContentHook; |
11 | use MediaWiki\Html\Html; |
12 | use MediaWiki\Language\Language; |
13 | use MediaWiki\Output\Hook\BeforePageDisplayHook; |
14 | use MediaWiki\Title\Title; |
15 | use Skin; |
16 | |
17 | /** |
18 | * Hook handler that registers the "ext.ax.articlefooter.entrypoint" RL module, when the |
19 | * appropriate conditions are met. |
20 | * |
21 | * @author Nik Gkountas |
22 | * @license GPL-2.0-or-later |
23 | * @since 2024.07 |
24 | */ |
25 | class AxArticleFooterEntrypointRegistrationHandler implements BeforePageDisplayHook, SkinAfterContentHook { |
26 | |
27 | private const ALLOWED_SKINS = [ 'minerva' ]; |
28 | private Config $contentTranslationConfig; |
29 | private Language $contentLanguage; |
30 | |
31 | /** |
32 | * Either a Lookup from the Disambiguator extension, or null if that is not installed |
33 | */ |
34 | private ?Lookup $disambiguatorLookup; |
35 | |
36 | public function __construct( |
37 | ConfigFactory $configFactory, |
38 | Language $contentLanguage, |
39 | ?Lookup $disambiguatorLookup |
40 | ) { |
41 | $this->contentTranslationConfig = $configFactory->makeConfig( 'ArticleFooterEntrypoint' ); |
42 | $this->disambiguatorLookup = $disambiguatorLookup; |
43 | $this->contentLanguage = $contentLanguage; |
44 | } |
45 | |
46 | private function isEntrypointAllowedOnSkin( Skin $skin ): bool { |
47 | $skinName = $skin->getSkinName(); |
48 | |
49 | return in_array( $skinName, self::ALLOWED_SKINS ); |
50 | } |
51 | |
52 | /** |
53 | * Check whether the output page is a diff page |
54 | * |
55 | * @param IContextSource $context |
56 | * @return bool |
57 | */ |
58 | private static function isDiffPage( IContextSource $context ): bool { |
59 | $request = $context->getRequest(); |
60 | $type = $request->getRawVal( 'type' ); |
61 | $diff = $request->getCheck( 'diff' ); |
62 | $oldId = $request->getCheck( 'oldid' ); |
63 | |
64 | return $type === 'revision' || $diff || $oldId; |
65 | } |
66 | |
67 | /** |
68 | * Uses the Disambiguator extension to test whether the page is a disambiguation page. |
69 | * |
70 | * If the Disambiguator extension isn't installed, then the test always fails, i.e. the page is |
71 | * never a disambiguation page. |
72 | * |
73 | * @param Title $title |
74 | * @return bool |
75 | */ |
76 | private function isDisambiguationPage( Title $title ): bool { |
77 | return $this->disambiguatorLookup && $this->disambiguatorLookup->isDisambiguationPage( $title ); |
78 | } |
79 | |
80 | private function shouldDisplayFooterEntrypoint( Skin $skin ): bool { |
81 | $title = $skin->getTitle(); |
82 | $action = $skin->getRequest()->getRawVal( 'action' ) ?? 'view'; |
83 | |
84 | $enabledLanguages = $this->contentTranslationConfig->get( |
85 | 'AutomaticTranslationLanguageSearcherEntrypointEnabledLanguages' |
86 | ) ?? []; |
87 | |
88 | return in_array( $this->contentLanguage->getCode(), $enabledLanguages ) && |
89 | $title->inNamespace( NS_MAIN ) && |
90 | $action === 'view' && |
91 | !$title->isMainPage() && |
92 | $title->exists() && |
93 | !self::isDiffPage( $skin ) && |
94 | !$this->isDisambiguationPage( $title ) && |
95 | $this->isEntrypointAllowedOnSkin( $skin ); |
96 | } |
97 | |
98 | public function onSkinAfterContent( &$data, $skin ) { |
99 | if ( $this->shouldDisplayFooterEntrypoint( $skin ) ) { |
100 | $data .= Html::element( 'div', [ 'class' => 'automatic-translation-entrypoint-container' ] ); |
101 | } |
102 | } |
103 | |
104 | public function onBeforePageDisplay( $out, $skin ): void { |
105 | if ( $this->shouldDisplayFooterEntrypoint( $skin ) ) { |
106 | $out->addModules( [ 'ext.ax.articlefooter.entrypoint' ] ); |
107 | } |
108 | } |
109 | } |