Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 39 |
|
0.00% |
0 / 2 |
CRAP | |
0.00% |
0 / 1 |
RecentTranslationEntrypointRegistrationHandler | |
0.00% |
0 / 39 |
|
0.00% |
0 / 2 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
onBeforePageDisplay | |
0.00% |
0 / 36 |
|
0.00% |
0 / 1 |
110 |
1 | <?php |
2 | |
3 | declare( strict_types=1 ); |
4 | |
5 | namespace ContentTranslation\HookHandler; |
6 | |
7 | use ContentTranslation\SiteMapper; |
8 | use ContentTranslation\Store\TranslationStore; |
9 | use MediaWiki\MediaWikiServices; |
10 | use MediaWiki\Output\Hook\BeforePageDisplayHook; |
11 | use MediaWiki\Output\OutputPage; |
12 | use MediaWiki\Registration\ExtensionRegistry; |
13 | use MediaWiki\Revision\RevisionStore; |
14 | use MobileContext; |
15 | use Skin; |
16 | use Wikimedia\Rdbms\ILoadBalancer; |
17 | |
18 | class RecentTranslationEntrypointRegistrationHandler implements BeforePageDisplayHook { |
19 | /** @var ILoadBalancer */ |
20 | private $loadBalancer; |
21 | |
22 | /** @var RevisionStore */ |
23 | private $revisionStore; |
24 | |
25 | /** @var TranslationStore */ |
26 | private $translationStore; |
27 | |
28 | public function __construct( |
29 | ILoadBalancer $loadBalancer, |
30 | RevisionStore $revisionStore, |
31 | TranslationStore $translationStore |
32 | ) { |
33 | $this->loadBalancer = $loadBalancer; |
34 | $this->revisionStore = $revisionStore; |
35 | $this->translationStore = $translationStore; |
36 | } |
37 | |
38 | /** |
39 | * This hook adds "ext.cx.entrypoints.recenttranslation" module, to support |
40 | * entrypoint inside articles, that encourages users to review recently |
41 | * translated articles, if the appropriate conditions are met. |
42 | * These conditions are: |
43 | * 1. SectionTranslation is enabled for current wiki |
44 | * 2. User is accessing the mobile web version of the article |
45 | * 3. User is logged-in |
46 | * 4. The article was published as a new page by Content or Section Translation |
47 | * 5. The article was published in the last 10 days |
48 | * 6. The article has less than 5 edits since it was published |
49 | * |
50 | * @param OutputPage $out |
51 | * @param Skin $skin |
52 | * @throws \Exception |
53 | */ |
54 | public function onBeforePageDisplay( $out, $skin ): void { |
55 | // This entrypoint should only be enabled for mobile web version |
56 | $isMobileView = false; |
57 | |
58 | if ( ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' ) ) { |
59 | /** @var MobileContext $mobileContext */ |
60 | $mobileContext = MediaWikiServices::getInstance()->getService( 'MobileFrontend.Context' ); |
61 | $isMobileView = $mobileContext->shouldDisplayMobileView(); |
62 | } |
63 | |
64 | if ( !$isMobileView ) { |
65 | return; |
66 | } |
67 | |
68 | // This entrypoint should only be enabled for logged-in users |
69 | $user = $out->getUser(); |
70 | if ( !$user->isNamed() ) { |
71 | return; |
72 | } |
73 | |
74 | $title = $out->getTitle(); |
75 | // This entrypoint should only be enabled for article pages |
76 | $isContentPage = $title->isContentPage(); |
77 | if ( !$isContentPage ) { |
78 | return; |
79 | } |
80 | |
81 | $currentLanguageCode = SiteMapper::getCurrentLanguageCode(); |
82 | $enabledLanguages = $out->getConfig()->get( 'SectionTranslationTargetLanguages' ); |
83 | $isSXEnabled = is_array( $enabledLanguages ) && in_array( $currentLanguageCode, $enabledLanguages ); |
84 | |
85 | if ( !$isSXEnabled ) { |
86 | return; |
87 | } |
88 | |
89 | // This entrypoint should only be enabled: |
90 | // a. for pages that are created using Content or Section Translation |
91 | // b. for pages that were published in the last 10 days |
92 | // "cx_translations" table is expected to be smaller than "revision" |
93 | // table, so we query this table first. |
94 | $translation = $this->translationStore->findByPublishedTitle( $title->getPrefixedText(), $currentLanguageCode ); |
95 | |
96 | // If translation not found inside the table, meaning this article has |
97 | // not been created using Content or Section Translation, return |
98 | if ( $translation === null ) { |
99 | return; |
100 | } |
101 | $translationData = $translation->getData(); |
102 | $creationDate = new \DateTime( $translationData['lastUpdateTimestamp'] ); |
103 | // Check if translation was published within the last 10 days |
104 | $createdWithin10Days = (bool)$creationDate->diff( new \DateTime( '-10 days' ) )->invert; |
105 | if ( !$createdWithin10Days ) { |
106 | return; |
107 | } |
108 | |
109 | // This entrypoint should only be enabled for pages that have less than 5 edits. |
110 | $pageId = $out->getWikiPage()->getId(); |
111 | // Find all revisions for this page |
112 | $dbr = $this->loadBalancer->getConnection( DB_REPLICA ); |
113 | $revisionsCount = $this->revisionStore->countRevisionsByPageId( $dbr, $pageId ); |
114 | |
115 | // If article has at least 5 edits, return |
116 | if ( $revisionsCount >= 5 ) { |
117 | return; |
118 | } |
119 | |
120 | // If all the above conditions are met, add 'ext.cx.entrypoints.recenttranslation' entrypoint |
121 | $out->addModules( 'ext.cx.entrypoints.recenttranslation' ); |
122 | // Add Javascript variables for translation source title and source language, |
123 | // so that they can be used inside UI |
124 | $out->addJsConfigVars( 'wgSectionTranslationSourceTitle', |
125 | $translationData['sourceTitle'] ); |
126 | $out->addJsConfigVars( 'wgSectionTranslationSourceLanguage', |
127 | $translationData['sourceLanguage'] ); |
128 | } |
129 | } |