Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.38% covered (success)
90.38%
47 / 52
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialCreateAbstract
90.38% covered (success)
90.38%
47 / 52
62.50% covered (warning)
62.50%
5 / 8
21.39
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDescription
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isListed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 userCanExecute
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 displayNotAvailableError
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getTargetTitle
78.57% covered (warning)
78.57%
11 / 14
0.00% covered (danger)
0.00%
0 / 1
7.48
 execute
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2/**
3 * WikiLambda Special:CreateAbstract page
4 *
5 * @file
6 * @ingroup Extensions
7 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
8 * @license MIT
9 */
10
11namespace MediaWiki\Extension\WikiLambda\Special;
12
13use MediaWiki\Exception\ErrorPageError;
14use MediaWiki\Extension\WikiLambda\AbstractContent\AbstractContentEditPageTrait;
15use MediaWiki\SpecialPage\SpecialPage;
16use MediaWiki\Title\Title;
17use MediaWiki\User\User;
18
19class SpecialCreateAbstract extends SpecialPage {
20    use AbstractContentEditPageTrait;
21
22    public function __construct() {
23        parent::__construct( 'CreateAbstract', 'wikilambda-abstract-create' );
24    }
25
26    /**
27     * @inheritDoc
28     */
29    protected function getGroupName() {
30        // Triggers use of message specialpages-group-abstractwiki
31        return 'abstractwiki';
32    }
33
34    /**
35     * @inheritDoc
36     */
37    public function getDescription() {
38        return $this->msg( 'wikilambda-abstract-special-create' );
39    }
40
41    /**
42     * @inheritDoc
43     */
44    public function isListed() {
45        return $this->getConfig()->get( 'WikiLambdaEnableAbstractMode' );
46    }
47
48    /**
49     * @inheritDoc
50     */
51    public function userCanExecute( User $user ) {
52        // Does the user have the relevant right (wikilambda-abstract-create, as set above)?
53        $userCanExecute = parent::userCanExecute( $user );
54
55        // If they're blocked in some way, does it block page creations or is site-wide?
56        $block = $user->getBlock();
57        $userNotBlocked = ( !$block || !$block->appliesToRight( 'createpage' ) || !$block->isSitewide() );
58
59        return $userCanExecute && $userNotBlocked;
60    }
61
62    /**
63     * Output an error message telling the user that the Abstract Mode is not enabled
64     *
65     * @throws ErrorPageError
66     */
67    private function displayNotAvailableError(): never {
68        $titleMessage = $this->msg( 'wikilambda-abstract-special-create-not-enabled-title' );
69        $errorMessage = $this->msg( 'wikilambda-abstract-special-create-not-enabled' );
70        throw new ErrorPageError( $titleMessage, $errorMessage );
71    }
72
73    /**
74     * Get target title from subpage and parameters:
75     * 1. If there is subpage, that will contain namespace:qid, or just qid for main ns
76     *       * Special:CreateAbstract/Abstract_Wikipedia:Q42
77     *       * Special:CreateAbstract/Q42
78     * 2. Else, look into request parameters qid, which might contain title or ns:qid
79     *    * Special:CreateAbstract?qid=Q42
80     *    * Special:CreateAbstract?qid=Abstract_Wikipedia:Q42
81     * We ignore oldid= parameter in Special:CreateAbstract page
82     *
83     * @param string|null $subpage
84     * @return Title
85     */
86    private function getTargetTitle( $subpage ): Title {
87        $request = $this->getRequest();
88
89        // Get qid, if any, either in subpage or as the url parameter 'qid'
90        $rawTitle = $subpage ?: $request->getVal( 'qid' ) ?: '';
91
92        // Get primary namespace: first of WikiLambdaAbstractNamespaces or NS_MAIN
93        $namespaces = $this->getContext()->getConfig()->get( 'WikiLambdaAbstractNamespaces' );
94        $namespaceIds = is_array( $namespaces ) && ( count( $namespaces ) > 0 )
95            ? array_map( 'intval', array_keys( $namespaces ) )
96            : [ NS_MAIN ];
97        $primaryNamespace = $namespaceIds[0];
98
99        // Parse as full title
100        $title = Title::newFromText( $rawTitle );
101
102        // Invalid or empty raw title; return empty title in primary NS
103        if ( !$title ) {
104            return Title::makeTitle( $primaryNamespace, '' );
105        }
106
107        // If namespace is not a configured abstract namespace, overwrite it with primary AW ns
108        $ns = $title->getNamespace();
109        if ( !in_array( $ns, $namespaceIds, true ) ) {
110            return Title::makeTitle( $primaryNamespace, $title->getText() );
111        }
112
113        return $title;
114    }
115
116    /**
117     * @inheritDoc
118     */
119    public function execute( $subpage ) {
120        // Throw ErrorPageError if Abtract Mode is not enabled
121        if ( !$this->getConfig()->get( 'WikiLambdaEnableAbstractMode' ) ) {
122            $this->displayNotAvailableError();
123        }
124
125        // Throw PermissionsError if user doesn't have the necessary rights
126        if ( !$this->userCanExecute( $this->getUser() ) ) {
127            $this->displayRestrictionError();
128        }
129
130        $output = $this->getOutput();
131        $context = $this->getContext();
132
133        $userLangCode = $context->getLanguage()->getCode();
134
135        $title = $this->getTargetTitle( $subpage );
136
137        // If title exists, we redirect to Special:ViewAbstract/<lang>/<title>
138        if ( $title->exists() ) {
139            $redirectSubpage = $userLangCode . '/' . $title->getPrefixedText();
140            $redirectTitle = SpecialPage::getTitleFor( 'ViewAbstract', $redirectSubpage );
141            $redirectParams = [ 'created' => 1 ];
142            $redirectURL = $redirectTitle->getFullURL( $redirectParams );
143            $output->redirect( $redirectURL );
144            return;
145        }
146
147        // If title doesn't exist, start building the page:
148        $this->setHeaders();
149
150        // Generate Abstract Content payload and pass data through JS config vars
151        $this->generateAbstractContentPayload( $context, $output, $title );
152
153        // Override page title if we are creating a new page for a pre-selected qid
154        if ( $title->getText() !== '' ) {
155            $titleMsg = $this->msg( 'wikilambda-abstract-special-create-qid' )->params( $title->getText() );
156            $output->setPageTitleMsg( $titleMsg );
157        }
158
159        $output->addModules( [ 'ext.wikilambda.app', 'mediawiki.special' ] );
160        $output->addModuleStyles( [ 'ext.wikilambda.special.styles' ] );
161
162        $output->addWikiMsg(
163            'wikilambda-abstract-special-create-intro',
164            'Special:MyLanguage/Abstract Wikipedia:List_of_policies_and_guidelines'
165        );
166
167        $this->addHelpLink( 'Help:How_to_create_an_article' );
168    }
169}