Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
20.00% covered (danger)
20.00%
9 / 45
22.22% covered (danger)
22.22%
2 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
DisplayTitleHooks
20.00% covered (danger)
20.00%
9 / 45
22.22% covered (danger)
22.22%
2 / 9
224.80
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 onParserFirstCallInit
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getdisplaytitleParserFunction
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 onSkinTemplateNavigation__Universal
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 onHtmlPageLinkRendererBegin
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 onSelfLinkBegin
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onBeforePageDisplay
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onOutputPageParserOutput
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 onScribuntoExternalLibraries
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace MediaWiki\Extension\DisplayTitle;
4
5use HtmlArmor;
6use MediaWiki\Hook\BeforePageDisplayHook;
7use MediaWiki\Hook\OutputPageParserOutputHook;
8use MediaWiki\Hook\ParserFirstCallInitHook;
9use MediaWiki\Hook\SelfLinkBeginHook;
10use MediaWiki\Hook\SkinTemplateNavigation__UniversalHook;
11use MediaWiki\Linker\Hook\HtmlPageLinkRendererBeginHook;
12use MediaWiki\Linker\LinkRenderer;
13use MediaWiki\Linker\LinkTarget;
14use NamespaceInfo;
15use OutputPage;
16use Parser;
17use ParserOutput;
18use RequestContext;
19use Skin;
20use SkinTemplate;
21use Title;
22
23class DisplayTitleHooks implements
24    ParserFirstCallInitHook,
25    BeforePageDisplayHook,
26    HtmlPageLinkRendererBeginHook,
27    OutputPageParserOutputHook,
28    SelfLinkBeginHook,
29    SkinTemplateNavigation__UniversalHook
30{
31    /**
32     * @var DisplayTitleService
33     */
34    private $displayTitleService;
35
36    /**
37     * @var NamespaceInfo
38     */
39    private $namespaceInfo;
40
41    /**
42     * @param DisplayTitleService $displayTitleService
43     * @param NamespaceInfo $namespaceInfo
44     */
45    public function __construct(
46        DisplayTitleService $displayTitleService,
47        NamespaceInfo $namespaceInfo
48    ) {
49        $this->displayTitleService = $displayTitleService;
50        $this->namespaceInfo = $namespaceInfo;
51    }
52
53    /**
54     * Implements ParserFirstCallInit hook.
55     * See https://www.mediawiki.org/wiki/Manual:Hooks/ParserFirstCallInit
56     * @since 1.0
57     * @param Parser $parser the Parser object
58     */
59    public function onParserFirstCallInit( $parser ) {
60        $parser->setFunctionHook(
61            'getdisplaytitle',
62            [ $this, 'getdisplaytitleParserFunction' ]
63        );
64    }
65
66    /**
67     * Handle #getdisplaytitle parser function.
68     *
69     * @since 1.0
70     * @param Parser $parser the Parser object
71     * @param string $pagename the name of the page
72     * @return string the displaytitle of the page; defaults to pagename if
73     * displaytitle is not set
74     */
75    public function getdisplaytitleParserFunction( Parser $parser, string $pagename ): string {
76        $title = Title::newFromText( $pagename );
77        if ( $title !== null ) {
78            $this->displayTitleService->getDisplayTitle( $title, $pagename );
79        }
80        return $pagename;
81    }
82
83    // phpcs:disable MediaWiki.NamingConventions.LowerCamelFunctionsName.FunctionName
84
85    /**
86     * Implements SkinTemplateNavigation::Universal hook.
87     * See https://www.mediawiki.org/wiki/Manual:Hooks/SkinTemplateNavigation::Universal
88     *
89     * Migrated from PersonalUrls hook, see https://phabricator.wikimedia.org/T319087
90     *
91     * @since 1.5
92     * @param SkinTemplate $sktemplate SkinTemplate object providing context
93     * @param array &$links The array of arrays of URLs set up so far
94     */
95    public function onSkinTemplateNavigation__Universal( $sktemplate, &$links ): void {
96        if ( $sktemplate->getUser()->isRegistered() ) {
97            $menu_urls = $links['user-menu'] ?? [];
98            if ( isset( $menu_urls['userpage'] ) ) {
99                $pagename = $menu_urls['userpage']['text'];
100                $title = $sktemplate->getUser()->getUserPage();
101                $this->displayTitleService->getDisplayTitle( $title, $pagename );
102                $links['user-menu']['userpage']['text'] = $pagename;
103            }
104            $page_urls = $links['user-page'] ?? [];
105            if ( isset( $page_urls['userpage'] ) ) {
106                // If we determined $pagename already, don't do so again.
107                if ( !isset( $menu_urls['userpage'] ) ) {
108                    $pagename = $page_urls['userpage']['text'];
109                    $title = $sktemplate->getUser()->getUserPage();
110                    $this->displayTitleService->getDisplayTitle( $title, $pagename );
111                }
112                $links['user-page']['userpage']['text'] = $pagename;
113            }
114        }
115    }
116
117    /**
118     * Implements HtmlPageLinkRendererBegin hook.
119     * See https://www.mediawiki.org/wiki/Manual:Hooks/HtmlPageLinkRendererBegin
120     * Handle links to other pages.
121     *
122     * @since 1.4
123     * @param LinkRenderer $linkRenderer the LinkRenderer object
124     * @param LinkTarget $target the LinkTarget that the link is pointing to
125     * @param string|HtmlArmor &$text the contents that the <a> tag should have
126     * @param array &$customAttribs the HTML attributes that the <a> tag should have
127     * @param string &$query the query string to add to the generated URL
128     * @param string &$ret the value to return if the hook returns false
129     */
130    public function onHtmlPageLinkRendererBegin( $linkRenderer, $target, &$text, &$customAttribs, &$query, &$ret ) {
131        $title = RequestContext::getMain()->getTitle();
132        if ( $title ) {
133            $this->displayTitleService->handleLink(
134                $title->getPrefixedText(),
135                Title::newFromLinkTarget( $target ),
136                $text,
137                true
138            );
139        }
140    }
141
142    /**
143     * Implements SelfLinkBegin hook.
144     * See https://www.mediawiki.org/wiki/Manual:Hooks/SelfLinkBegin
145     * Handle self links.
146     *
147     * @since 1.3
148     * @param Title $nt the Title object of the page
149     * @param string &$html the HTML of the link text
150     * @param string &$trail Text after link
151     * @param string &$prefix Text before link
152     * @param string &$ret the value to return if the hook returns false
153     */
154    public function onSelfLinkBegin( $nt, &$html, &$trail, &$prefix, &$ret ) {
155        $this->displayTitleService->handleLink( $nt->getPrefixedText(), $nt, $html, false );
156    }
157
158    /**
159     * Implements BeforePageDisplay hook.
160     * See https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
161     * Display subtitle if requested
162     *
163     * @since 1.0
164     * @param OutputPage $out the OutputPage object
165     * @param Skin $skin the Skin object
166     */
167    public function onBeforePageDisplay( $out, $skin ): void {
168        $this->displayTitleService->setSubtitle( $out );
169    }
170
171    /**
172     * Implements OutputPageParserOutput hook.
173     * See https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageParserOutput
174     * Handle talk page title.
175     *
176     * @since 1.0
177     * @param OutputPage $outputPage
178     * @param ParserOutput $parserOutput
179     */
180    public function onOutputPageParserOutput( $outputPage, $parserOutput ): void {
181        $title = $outputPage->getTitle();
182        if ( $title !== null && $title->isTalkPage() ) {
183            $subjectPage = Title::castFromLinkTarget( $this->namespaceInfo->getSubjectPage( $title ) );
184            if ( $subjectPage->exists() ) {
185                $found = $this->displayTitleService->getDisplayTitle( $subjectPage, $displaytitle );
186                if ( $found ) {
187                    $displaytitle = wfMessage( 'displaytitle-talkpagetitle',
188                        $displaytitle )->plain();
189                    $parserOutput->setTitleText( $displaytitle );
190                }
191            }
192        }
193    }
194
195    /**
196     * Implements ScribuntoExternalLibraries hook.
197     * See https://www.mediawiki.org/wiki/Extension:Scribunto#Other_pages
198     * Handle Scribunto integration
199     *
200     * @since 1.2
201     * @param string $engine engine in use
202     * @param array &$extraLibraries list of registered libraries
203     */
204    public static function onScribuntoExternalLibraries( string $engine, array &$extraLibraries ) {
205        if ( $engine === 'lua' ) {
206            $extraLibraries['mw.ext.displaytitle'] = DisplayTitleLuaLibrary::class;
207        }
208    }
209}