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