Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
PageDisplayHandlers
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 7
506
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 shouldShowStoriesOnSkin
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
12
 shouldShowStoriesForAction
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 shouldShowStoriesForUser
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
56
 shouldShowStoriesOnPage
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 shouldShowStories
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
20
 onBeforePageDisplay
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace MediaWiki\Extension\Wikistories\Hooks;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Context\IContextSource;
7use MediaWiki\Extension\BetaFeatures\BetaFeatures;
8use MediaWiki\Extension\Wikistories\Hooks;
9use MediaWiki\Output\Hook\BeforePageDisplayHook;
10use MediaWiki\Output\OutputPage;
11use MediaWiki\Registration\ExtensionRegistry;
12use MediaWiki\Skin\Skin;
13use MediaWiki\Title\Title;
14use MediaWiki\User\Options\UserOptionsLookup;
15use MediaWiki\User\User;
16use MobileContext;
17
18class PageDisplayHandlers implements BeforePageDisplayHook {
19
20    public function __construct(
21        private readonly UserOptionsLookup $userOptionsLookup,
22        private readonly ?MobileContext $mobileContext = null,
23    ) {
24    }
25
26    private function shouldShowStoriesOnSkin( Skin $skin ): bool {
27        $isMobileView = $this->mobileContext && $this->mobileContext->shouldDisplayMobileView();
28        return $skin->getSkinName() === 'minerva' && $isMobileView;
29    }
30
31    private static function shouldShowStoriesForAction( IContextSource $context ): bool {
32        return $context->getActionName() === 'view' &&
33            $context->getRequest()->getText( 'diff' ) === '';
34    }
35
36    private function shouldShowStoriesForUser( User $user, Config $config ): bool {
37        if ( Hooks::isBetaDiscoveryMode( $config ) ) {
38            return $user->isNamed()
39                && ExtensionRegistry::getInstance()->isLoaded( 'BetaFeatures' )
40                && BetaFeatures::isFeatureEnabled( $user, BetaFeaturesHandlers::WIKISTORIES_BETA_FEATURE );
41        } elseif ( Hooks::isPublicDiscoveryMode( $config ) ) {
42            return ( $user->isAnon() || $user->isTemp() )
43                || (bool)$this->userOptionsLookup->getOption( $user, Hooks::WIKISTORIES_PREF_SHOW_DISCOVERY, true );
44        } else {
45            // unknown discovery mode
46            return false;
47        }
48    }
49
50    private static function shouldShowStoriesOnPage( Title $title ): bool {
51        return !$title->isMainPage()
52            && $title->inNamespace( NS_MAIN )
53            && $title->exists();
54    }
55
56    private function shouldShowStories( User $user, Title $title, Skin $skin, IContextSource $context ): bool {
57        return $this->shouldShowStoriesForUser( $user, $context->getConfig() )
58            && $this->shouldShowStoriesOnSkin( $skin )
59            && self::shouldShowStoriesOnPage( $title )
60            && self::shouldShowStoriesForAction( $context );
61    }
62
63    /**
64     * @param OutputPage $out
65     * @param Skin $skin
66     */
67    public function onBeforePageDisplay( $out, $skin ): void {
68        $title = $out->getTitle();
69        if ( $this->shouldShowStories( $out->getUser(), $title, $out->getSkin(), $out->getContext() ) ) {
70            $out->addModules( [ 'ext.wikistories.discover' ] );
71            $out->addModuleStyles( 'ext.wikistories.discover.styles' );
72        }
73    }
74}