Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 79
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
CollaborationKitHooks
0.00% covered (danger)
0.00%
0 / 79
0.00% covered (danger)
0.00%
0 / 6
552
0.00% covered (danger)
0.00%
0 / 1
 onSkinTemplateNavigation
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
110
 onParserFirstCallInit
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 onCodeEditorGetPageLanguage
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 onOutputPageBeforeHTML
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
 onOutputPageParserOutput
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
 onGetDoubleUnderscoreIDs
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3use MediaWiki\MediaWikiServices;
4use MediaWiki\Revision\SlotRecord;
5
6/**
7 * Hooks to modify the default behavior of MediaWiki.
8 *
9 * @file
10 */
11
12class CollaborationKitHooks {
13
14    /**
15     * Some extra tabs for editing
16     *
17     * @param SkinTemplate &$sktemplate
18     * @param array &$links
19     * @return bool
20     */
21    public static function onSkinTemplateNavigation( &$sktemplate, &$links ) {
22        $title = $sktemplate->getTitle();
23        $request = $sktemplate->getRequest();
24        if ( isset( $links['views']['edit'] ) && $title->canExist() ) {
25            if ( $title->hasContentModel( 'CollaborationListContent' )
26                || $title->hasContentModel( 'CollaborationHubContent' )
27            ) {
28                // Edit as JSON
29                $active = in_array(
30                    $request->getVal( 'action' ),
31                    [ 'edit', 'submit' ]
32                ) && $request->getVal( 'format' ) === 'application/json';
33                $links['actions']['editasjson'] = [
34                    'class' => $active ? 'selected' : false,
35                    'href' => wfAppendQuery(
36                        $links['views']['edit']['href'],
37                        [ 'format' => 'application/json' ]
38                    ),
39                    'text' => wfMessage( 'collaborationkit-editjsontab' )
40                        ->text()
41                ];
42                if ( $active ) {
43                    // Make it not be selected when editing json.
44                    $links['views']['edit']['class'] = false;
45                }
46            }
47            if ( !in_array( $request->getVal( 'action' ), [ 'edit', 'submit' ] )
48                && $title->hasContentModel( 'CollaborationHubContent' )
49            ) {
50                // Add feature
51                $links['actions']['addnewfeature'] = [
52                    'class' => '',
53                    'href' => SpecialPage::getTitleFor( 'CreateHubFeature' )
54                        ->getFullURL( [ 'collaborationhub' => $title->getFullText() ] ),
55                    'text' => wfMessage( 'collaborationkit-hub-addpage' )->text()
56                ];
57            }
58        }
59        return true;
60    }
61
62    /**
63     * Register the {{#transcludelist:...}} and <collaborationkitloadliststyles>
64     * hooks
65     *
66     * #transcludelist is to allow users to transclude a CollaborationList with
67     * custom options. <collaborationkitloadliststyles> allows enabling our style
68     * modules directly from wikitext, so we can do plain wikitext transclusions of
69     * lists and have them work properly, since ContentHandler does not provide access
70     * to the parser when doing plain wikitext transclusion.
71     *
72     * @param Parser $parser
73     */
74    public static function onParserFirstCallInit( $parser ) {
75        $parser->setFunctionHook(
76            'transcludelist',
77            'CollaborationListContent::transcludeHook'
78        );
79        // Hack for transclusion.
80        $parser->setHook(
81            'collaborationkitloadliststyles',
82            'CollaborationListContent::loadStyles'
83        );
84    }
85
86    /**
87     * Declares JSON as the code editor language for CollaborationKit pages.
88     *
89     * This hook only runs if the CodeEditor extension is enabled.
90     * @param Title $title
91     * @param string &$lang Page language.
92     * @return bool
93     */
94    public static function onCodeEditorGetPageLanguage( $title, &$lang ) {
95        $contentModel = $title->getContentModel();
96        $ckitModels = [ 'CollaborationHubContent', 'CollaborationListContent' ];
97        $req = RequestContext::getMain()->getRequest();
98        // Kind of hacky use of globals.
99        if ( in_array( $contentModel, $ckitModels ) ) {
100            if ( $req->getVal( 'format' ) === 'application/json' ) {
101                $lang = 'json';
102                return true;
103            } else {
104                // JsonConfig incorrectly triggers on anything with the default
105                // format of application/json, which includes us. false is kind
106                // of hacky but only way to stop it.
107                $lang = null;
108                return false;
109            }
110        }
111    }
112
113    /**
114     * For the table of contents on subpages of a CollaborationHub
115     *
116     * @param OutputPage $out
117     * @param string &$text the HTML text to be added
118     * @return bool
119     */
120    public static function onOutputPageBeforeHTML( OutputPage $out, &$text ) {
121        $title = $out->getTitle();
122        $parentHub = CollaborationHubContent::getParentHub( $title );
123
124        if ( !$parentHub
125            || $out->getProperty( 'CollaborationHubSubpage' ) !== 'in-progress'
126        ) {
127            return true;
128        }
129
130        /** @var CollaborationHubContent $revisionContent */
131        $revisionContent = MediaWikiServices::getInstance()
132            ->getRevisionLookup()
133            ->getRevisionByTitle( $parentHub )
134            ->getContent( SlotRecord::MAIN );
135        if ( count( $revisionContent->getContent() ) > 0 ) {
136            $toc = new CollaborationHubTOC();
137            $out->prependHTML( $toc->renderSubpageToC( $parentHub ) );
138
139            $colour = $revisionContent->getThemeColour();
140            $text = Html::rawElement(
141                'div',
142                [ 'class' => "mw-cklist-square-$colour" ],
143                $text
144            );
145
146            $out->addModuleStyles( [
147                'ext.CollaborationKit.hubsubpage.styles',
148                'ext.CollaborationKit.icons',
149                'ext.CollaborationKit.blots'
150            ] );
151
152            // Set this mostly just so we can make sure this entire thing hasn't
153            // already been done, because otherwise the ToC is added twice on
154            // edit for some reason
155            $out->setProperty( 'CollaborationHubSubpage', true );
156        }
157        return true;
158    }
159
160    /**
161     * Propogate if we should create a ToC from ParserOutput -> OutputPage.
162     *
163     * Its assumed we should create a ToC on the following conditions:
164     *  * __NOCOLLABORATIONHUBTOC__ is not on page
165     *  * Somebody added parser metadata to the OutputPage (More likely to be a real page)
166     *  * The limit report was enabled (More likely to be a real page)
167     * These conditions are hacky. Ideally we'd come up with a more
168     * robust way of determining if this is really a wikipage.
169     *
170     * Eventually, the TOC will be output by onOutputPageBeforeHTML hook if this
171     * hook signals it is ok.
172     *
173     * @param OutputPage $out
174     * @param ParserOutput $pout
175     */
176    public static function onOutputPageParserOutput( OutputPage $out,
177        ParserOutput $pout
178    ) {
179        if ( $out->getProperty( 'CollaborationHubSubpage' ) ) {
180            // We've already been here, so we can't abort
181            // outputting the TOC at this stage.
182            wfDebug( __METHOD__ . ' TOC already outputted, possibly incorrectly.' );
183            return;
184        }
185
186        if ( $pout->getPageProperty( 'nocollaborationhubtoc' ) !== null ) {
187            // TOC disabled, mark as done.
188            $out->setProperty( 'CollaborationHubSubpage', true );
189        } elseif ( $pout->getLimitReportData() ) {
190            $out->setProperty( 'CollaborationHubSubpage', 'in-progress' );
191        }
192    }
193
194    /**
195     * Register __NOCOLLABORATIONHUBTOC__ as a magic word.
196     *
197     * @param array &$magicWords All double underscore magic ids
198     */
199    public static function onGetDoubleUnderscoreIDs( array &$magicWords ) {
200        $magicWords[] = 'nocollaborationhubtoc';
201    }
202}